Java 8 从Joda时间库迁移到Java时间(Java 8)

Java 8 从Joda时间库迁移到Java时间(Java 8),java-8,refactoring,jodatime,java-time,Java 8,Refactoring,Jodatime,Java Time,我们的软件架构师决定从项目依赖项中删除Joda时间库,并使用Java8时间的特性。我正在研究我们的项目,并试图找到我们使用Joda时间库的所有地方,并确定我们实际使用的是什么(JodaLocalDate,DateTime,等等)。 我不是Joda time library的专家,也不是Java 8 time的专家,所以我有一些问题: 在代码中,我看到了很多这样的地方: DateTime jodaDateTime = new DateTime(); doSomething(jodaDateTime

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

DateTime jodaDateTime = new DateTime();
doSomething(jodaDateTime.toDate()); 
我有点困惑

Q1)使用joda有意义吗
DateTime
在这种情况下?我相信,我们可以只使用classic
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 time 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%。 我刚刚找到了一个表的链接:“ 有一些我发现的信息,我需要使用
java.time.ZonedDateTime
java.time.OffsetDateTime
类,但不是
java.time.LocalDateTime
,因为
LocalDateTime
-

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


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

您在这两种情况下都做对了。我可能会添加的唯一一条注释是Java8 time取代了java.util.Date,因此您可能想考虑将方法doSomething(java.util.Date)替换为doSomething(java.time.TemporalAccessor)。然而,java.util.Date还没有被声明为去润滑,所以您不必这样做。以我的经验,Java8时间包是非常灵活和全面的包。我发现Joda有一些有趣的bug,尽管Joda在当时是一个不错的软件包

大多数关于转换的问题都应该由我在这个主题上处理

问题1A: 创建一个Joda时间对象,只将其更改回
java.util.Date
,没有任何意义。但是,该方法可能需要
即时
分区时间

Instant instant = Instant.now();
doSomething(instant);  // method changed to take Instant
请注意,
Instant
java.util.Date
最匹配

问题1B: 本例涉及时区,因此应使用
ZonedDateTime

ZonedDateTime java8DateTime = ZonedDateTime.now();  // uses ZoneId.systemDefault()
ZonedDateTime java8DateTimeInPast = java8DateTime.minusSeconds(60);
doSomething(java8DateTimeInPast.toInstant());
同样,这假设
doSomething
更改为采取
即时

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

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

在大多数应用程序代码中不应使用临时Accessor
。一般来说,如果您在最低级别的库之外使用它,那么您就做错了。在这种情况下,它应该是
doSomething(Instant)
doSomething(ZonedDateTime)
或类似于您写的:“Instant与java.util.Date最匹配”,但例如:new Date().toString()返回:Thu Jan 28 18:26:27 EET 2016,但Instant.now().toString()返回:2016-01-28816:26:27.210Z。如您所见,Instant返回16:26:27,它是UTC,Date返回18:26:27-eet
java.util.Date
上的
toString()
返回本地时区中的时间。但对象的状态并不支持这一点。理解这种差异是理解
java.util.Date
的关键。