2017-08-23 46 views
2

我想根据某些逻辑在Java数据库的数据类型列中插入一个值datetime从ZonedDateTime获取java.sql.Timestamp

逻辑: 如果月份的日期是29日,30日或31日,则在下个月的28日。其他人在下个月的同一天投入。

E.g.如果日期为2017-08-31,则数据库中的日期为2017-09-28。但是,如果日期是2017-08-27,则数据库中的日期将为2017-09-27

我也想要一切在UTC

我想要的代码是这样的:

ZonedDateTime utcDateTime = ZonedDateTime.now(ZoneOffset.UTC); 

utcDateTime = utcDateTime.plusMonths(1); 

if(utcDateTime.getDayOfMonth() >= 29){ 
    utcDateTime = utcDateTime.withDayOfMonth(28); 
    Timestamp time = Timestamp.from(utcDateTime.toInstant()); 
    System.out.println(time); // DB insert here 
}else{ 
     Timestamp time = Timestamp.from(utcDateTime.toInstant()); 
     System.out.println(time); // DB insert here 
    } 

问:这是最正确的做法还是有使用Instant(它总是在UTC)一个简单的Java 8路?我没有办法从Instant对象或方式中直接获取月份中的某个月份到Instant对象。

+1

不考虑所有可能性,立即你的代码看起来很好。 '即时'不适合你需要的日期算术,所以最好使用另一个类。我会考虑'OffsetDateTime'而不是'ZonedDateTime'。 –

+0

你需要一天中的任何时间吗?如果不是这样,使用LocalDate可能会更加正确(即使转换为Instant也不那么简单)。你也可能想解释为什么你要回到9月28日,那时9月有30天;这似乎有点有趣? –

回答

1

您的代码适合您的目的。为了您可能灵感,这里是我的版本:

OffsetDateTime utcDateTime = OffsetDateTime.now(ZoneOffset.UTC); 

    if (utcDateTime.getDayOfMonth() >= 29) { 
     utcDateTime = utcDateTime.withDayOfMonth(28); 
    } 

    utcDateTime = utcDateTime.plusMonths(1); 
    Timestamp time = Timestamp.from(utcDateTime.toInstant()); 
    System.out.println(time); // DB insert here 

我使用OffsetDateTime而不是ZonedDateTime,因为我们不需要任何的一个时间段的额外功能,如夏令时间(DST)和历史悠久的偏移变化。我在之后增加了一个月,调整月份。两者都可以工作,但是这样可以让读者不必考虑在1月31日增加一个月后会发生什么。最后我发现没有else部分的版本更自然:在某些情况下,您需要调整日期,所以if部分负责处理这个问题,而在其他所有情况下,我们都不做这种调整。把你喜欢的部分(如果有的话)丢弃,然后丢弃其余部分。

该代码(包括你的和我的)保留了时间。我想你想要这个。为了完整起见,如果你不这样做,你会希望你的数据库来保存刚才的日期,而不是一个时间戳,所以代码将使用一个java.sql.Date

LocalDate utcDate = LocalDate.now(ZoneOffset.UTC); 
    if (utcDate.getDayOfMonth() > 28) { 
     utcDate = utcDate.withDayOfMonth(28); 
    } 
    utcDate = utcDate.plusMonths(1); 
    Date date = Date.valueOf(utcDate); 
    System.out.println(date); // DB insert here 

如果您不能更改数据库列数据类型,它通常采用日(0:00)开始:

Timestamp time = Timestamp.from(utcDate.atStartOfDay(ZoneOffset.UTC).toInstant()); 
    System.out.println(time); // DB insert here 

最后,我热烈鼓励你看,如果你可以为你的数据库的JDBC驱动程序4.2。这将接受直接插入Instant(或LocalDate),所以你完全摆脱了过时的Timestamp类(或Date)。

相关问题