Java 8 ZonedDateTime或OffsetDateTime替换Joda DateTime

时间:2016-01-05 10:18:57

标签: java datetime java-8 jodatime

在Java8之前,我使用了Joda的DateTime类来包含时区信息,我可以轻松地在DateTime和sql Timestamp之间进行转换。

迁移到Java8后,我应该替换哪个类? OffsetDateTimeZonedDateTime

此外,我尝试使用OffsetDateTime,但似乎无法从sql OffsetDateTime构建回Timestamp

对于Joda DateTimeTimestamp转换器,代码如下:

val joda = DateTime.now()
val sqlJoda = new Timestamp(joda.getMillis)
val jodaBack = new DateTime(sqlJoda)

但是对于Java8,

val java8 = OffsetDateTime.now()
val sqlJava8 = new Timestamp(java8.toInstant.toEpochMilli)
val java8Back = ???

有人对此有所了解吗?似乎Joda DateTime非常好。

3 个答案:

答案 0 :(得分:6)

在java.time中使用Java 8 API,您可以执行以下操作:

long ms_since_epoch = 1_500_000_000_000L;
Instant instant = Instant.ofEpochMilli(ms_since_epoch);

// convert milliseconds in UTC to date
OffsetDateTime dateUTC = OffsetDateTime.ofInstant(instant, ZoneOffset.UTC);

使用您的约定:

val java8 = OffsetDateTime.now()
val sqlJava8 = new Timestamp(java8.toInstant.toEpochMilli)
val java8Back = OffsetDateTime.ofInstant(sqlJava8.toInstant(), ZoneOffset.UTC);

答案 1 :(得分:4)

您可以使用ZonedDateTime。这是我用来来回转换为Timestamp的一些示例代码。

public ZonedDateTime from(Timestamp timestamp) {
    if (timestamp == null) {
        return null;
    }
    final ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(timestamp.toInstant(), ZoneId.of("UTC"));
    return zonedDateTime;
}

public Timestamp to(ZonedDateTime zonedDateTime) {
    if (zonedDateTime == null) {
        return null;
    }
    final Timestamp timestamp = Timestamp.valueOf(zonedDateTime.withZoneSameInstant(ZoneId.of("UTC")).toLocalDateTime());
    return timestamp;
}

请注意,我以UTC格式存储数据库中的日期时间。

答案 2 :(得分:2)

我假设您的数据库类型是timestamp with time zone。如果它是timestamp without timezone,您将需要不同的类型/转换机制。

JDBC 4.2 spec建议将timestamp with time zone映射到OffsetDateTime。您可以通过以下方式在OffsetDateTimejava.sql.Timestamp之间进行转换。

  • OffsetDateTimeTimestamp

    Timestamp ts = ...;
    OffsetDateTime odt = OffsetDateTime.ofInstant(ts.toInstant(), ZoneId.systemDefault());
    
  • TimestampOffsetDateTime

    OffsetDateTime odt = ...;
    Timestamp ts = Timestamp.from(odt.toInstant());