【问题标题】:migrate from Joda time library to Java time (Java 8)从 Joda 时间库迁移到 Java 时间 (Java 8)
【发布时间】:2016-01-27 17:13:25
【问题描述】:

我们的软件架构师决定从我们的项目依赖项中删除 Joda 时间库并使用 Java 8 时间的功能。我正在研究我们的项目,并试图找到我们使用 Joda 时间库的所有地方,并确定我们实际使用的是什么(joda LocalDateDateTime 等)。
我不是 Joda 时间库的专家,也不是 Java 8 时间的专家,所以我有一些问题:
在代码中我看到很多这样的地方:

DateTime jodaDateTime = new DateTime();
doSomething(jodaDateTime.toDate()); 

我有点困惑。

(Q1) 用joda有意义吗 DateTime 在这种特殊情况下?我相信,我们可以只使用经典的java.util.Date 而我们不需要 Joda:

java.util.Date date = new Date();
doSomething(date);

正确吗?

另外,我看到了这段代码:

org.joda.time.DateTime jodaDateTime = new DateTime();
org.joda.time.DateTime jodaDateTimeInPast = jodaDateTime.minusSeconds(60);
doSomething(jodaDateTimeInPast.toDate());

我认为,java 8 时间 API 为计算过去的任何日期提供了很好的支持,所以我知道如何将上面的代码替换为 Java 8:

LocalDatetime java8DateTime = LocalDateTime.now();
LocaldateTime java8DateTimeInPast = java8DateTime.minusSeconds(60);
Date java8Date = Date.from(java8DateTimeInPast.atZone(ZoneId.systemDefault()).toInstant());
doSomething(java8Date);

(Q2) 我做对了吗?我不确定 100%。 我刚刚找到了一个带有表格的链接:“Converting from Joda-Time to java.time” 有我发现的信息,我需要使用java.time.ZonedDateTimejava.time.OffsetDateTime 类,但不是java.time.LocalDateTime,因为LocalDateTime -

相同的概念 - 没有时区的日期和时间

请确认我的重构是正确的(对于 Q1Q2)。

【问题讨论】:

    标签: java-8 refactoring jodatime java-time


    【解决方案1】:

    关于转换的大多数问题应该由我的blog处理。

    Q1a: 创建一个 Joda-Time 对象只是为了改回java.util.Date 是没有意义的。但是,该方法可能应该采用InstantZonedDateTime

    Instant instant = Instant.now();
    doSomething(instant);  // method changed to take Instant
    

    请注意,Instant 是最接近 java.util.Date 的匹配项。

    Q1b: 本案例涉及时区,应使用ZonedDateTime

    ZonedDateTime java8DateTime = ZonedDateTime.now();  // uses ZoneId.systemDefault()
    ZonedDateTime java8DateTimeInPast = java8DateTime.minusSeconds(60);
    doSomething(java8DateTimeInPast.toInstant());
    

    再次假设 doSomething 被更改为 Instant

    正确使用java.time 的关键是考虑每条数据的正确数据类型。

    • 只是约会?然后使用LocalDate
    • 只是一次?然后使用LocalTime
    • 日期、时间和时区?然后使用ZonedDateTime
    • 只是一个没有其他信息的时间戳?然后使用Instant
    • 带有偏移量(不是区域)的网络日期时间格式?然后使用OffsetDateTime

    【讨论】:

    • 您写道:“Instant 是最接近 java.util.Date 的匹配项”,但例如: new Date().toString() 返回:Thu Jan 28 18:26:27 EET 2016,但 Instant.now().toString() 返回:2016-01-28T16:26:27.210Z。如您所见,Instant 返回 16:26:27,它是 UTC,Date 返回 18:26:27 - EET
    • toString() on java.util.Date 返回本地时区的时间。但是对象的状态并不成立。了解这种差异是了解java.util.Date 的关键。
    【解决方案2】:

    你在这两种情况下都做得对。我可能会添加的唯一评论是 java 8 time 取代了 java.util.Date,因此您可能想考虑用 doSomething(java.time.temporal.TemporalAccessor) 替换您的方法 doSomething(java.util.Date)。但是,java.util.Date 尚未被声明为 deprecated,因此您不必这样做。以我的经验,java 8 时间包是非常灵活和全面的包。尽管 Joda 在当时是一个不错的软件包,但我发现 Joda 有一些有趣的错误。

    【讨论】:

    • TemporalAccessor 不应在大多数应用程序代码中使用。一般来说,如果你在最低级别的库之外使用它,你就做错了。在这种情况下,它应该是doSomething(Instant)doSomething(ZonedDateTime) 或类似
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-26
    • 2016-01-24
    • 1970-01-01
    相关资源
    最近更新 更多