Java 8 ZonedDateTime或OffsetDateTime替换Joda DateTime

ttt*_*ttt 9 java datetime jodatime java-8

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

迁移到Java8后,我应该替换哪个类?OffsetDateTime还是ZonedDateTime

另外,我试图使用OffsetDateTime,但似乎无法OffsetDateTime从sql 构造回来Timestamp.

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

val joda = DateTime.now()
val sqlJoda = new Timestamp(joda.getMillis)
val jodaBack = new DateTime(sqlJoda)
Run Code Online (Sandbox Code Playgroud)

但对于Java8,

val java8 = OffsetDateTime.now()
val sqlJava8 = new Timestamp(java8.toInstant.toEpochMilli)
val java8Back = ???
Run Code Online (Sandbox Code Playgroud)

有人对此有所了解吗?看来Joda DateTime真的很棒.

Mat*_*oka 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);
Run Code Online (Sandbox Code Playgroud)

使用您的约定:

val java8 = OffsetDateTime.now()
val sqlJava8 = new Timestamp(java8.toInstant.toEpochMilli)
val java8Back = OffsetDateTime.ofInstant(sqlJava8.toInstant(), ZoneOffset.UTC);
Run Code Online (Sandbox Code Playgroud)

  • 是.但您可以使用不同的ZoneId将其更改为相应的时区. (2认同)

spa*_*spa 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;
}
Run Code Online (Sandbox Code Playgroud)

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

  • SQL 时间戳的官方映射是 LocalDateTime(不带时区的时间戳)或 OffsetDateTime(带时区的时间戳)。例如,请参阅此处的 JDBC 4 JCP 维护版本 2:https://jcp.org/en/jsr/detail?id=221 (2认同)