【问题标题】:Java 8 ZonedDateTime or OffsetDateTime to replace Joda DateTimeJava 8 ZonedDateTime 或 OffsetDateTime 替换 Joda DateTime
【发布时间】:2016-04-09 03:10:55
【问题描述】:

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

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

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

对于 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 = ???

有人对此有所了解吗?看来乔达DateTime真的不错。

【问题讨论】:

    标签: java datetime java-8 jodatime


    【解决方案1】:

    在 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);
    

    【讨论】:

    • 这意味着我们假设数据库是UTC,对吧?谢谢。
    • 是的。但是您可以使用不同的 ZoneId 将其更改为您相应的时区。
    【解决方案2】:

    您可以使用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 存储日期时间。

    【讨论】:

    • SQL时间戳的官方映射要么是LocalDateTime(不带时区的时间戳)要么是OffsetDateTime(带时区的时间戳)。例如,请参阅此处的 JDBC 4 JCP 维护版本 2:jcp.org/en/jsr/detail?id=221
    • 不知道。谢谢。那里有文档吗?
    【解决方案3】:

    我假设您的数据库类型是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());
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-21
      • 2018-12-24
      • 2015-11-07
      • 2017-08-29
      • 2018-01-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多