Java 8 从Joda时间库迁移到Java时间(Java 8)
我们的软件架构师决定从项目依赖项中删除Joda时间库,并使用Java8时间的特性。我正在研究我们的项目,并试图找到我们使用Joda时间库的所有地方,并确定我们实际使用的是什么(JodaJava 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
LocalDate
,DateTime
,等等)。我不是Joda time library的专家,也不是Java 8 time的专家,所以我有一些问题:
在代码中,我看到了很多这样的地方:
DateTime jodaDateTime = new DateTime();
doSomething(jodaDateTime.toDate());
我有点困惑
(Q1)使用joda有意义吗
DateTime
在这种情况下?我相信,我们可以只使用classicjava.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
-
相同的概念-没有时区的日期和时间
请确认我的重构是正确的(对于Q1和Q2)。您在这两种情况下都做对了。我可能会添加的唯一一条注释是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-eetjava.util.Date
上的toString()
返回本地时区中的时间。但对象的状态并不支持这一点。理解这种差异是理解java.util.Date
的关键。