我想将这段代码从 Joda-Time 迁移到它的替代品 java.time (JSR 310)。
ZonedDateTime
.
旧代码:
DateTime startTime = new DateTime();
DateTime stopTime = new DateTime();
durationMilli = Math.max(1, (stopTime.getMillis() - startTime.getMillis()));
到
ZonedDateTime startTime = ZonedDateTime.now();
ZonedDateTime stopTime = ZonedDateTime.now();
durationMilli = Math.max(1, (stopTime.getMillis() - startTime.getMillis()));
我有以下问题
如何将
ZonedDateTime.now()
设置为空值?如您所见,stopTime
应该是空的。
发送问题是缺少方法getMillis
。我怎样才能得到毫秒?
如何将 ZonedDateTime.now() 设置为空值?
就像你对任何其他类的对象引用所做的那样。要么:
null
Optional.empty
如何获得毫秒数?
myZonedDateTime.toInstant().toEpochMilli()
ZonedDateTime
替换DateTime
DateTime
类代表一个时刻,时间轴上的一个特定点,从特定时区来看。
new org.joda.time.DateTime()
捕捉在当前默认时区中看到的当前时刻。它在java.time中等价于ZonedDateTime.now()
.
顺便说一句,我发现指定您知道并想要JVM当前的默认时区会更清楚。像这样:
ZonedDateTime.now( ZoneId.systemDefault() )
而不是隐式依赖默认值。
你说:
如您所见,stopTime 应该是空的。
不,我根本没有看到。您的代码中哪里有任何类型的空值?
像
ZonedDateTime
这样的日期时间对象总是有一个值。拥有一个价值是它的工作,具体来说:代表一个时区所见的时刻。所以没有“空”值。如果您想表示没有已知时刻,请使用:
null
Optional
Optional
。请参阅 baeldung 的 Java 8 可选指南。
Optional< ZonedDateTime > empty = Optional.empty();
或者,如果您想使用特定时刻作为标志或占位符,我建议使用 java.time 中定义的 epoch 参考:1970 年的第一个时刻,偏移量为零小时-分钟-秒UTC,1970-01-01T00:00Z.
java.time.Instant
类具有该值的预定义常量:Instant.EPOCH
.
You can adjust an
Instant
in UTC to a ZonedDateTime
in a particular time zone.
Instant instant = Instant.EPOCH ;
ZoneId z = Zone.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
再次返回,从时区移动到 UTC(零偏移)。
Instant instant = zdt.toInstant() ;
您可以询问
Instant
对象 自纪元参考 1970-01-01T00:00Z 以来的毫秒数。请注意可能的数据丢失,因为 Instant
对象可能有您将忽略的微秒或纳秒。
long millisSinceEpoch = instant.toEpochMilli() ;
然后返回另一个方向:
Instant instant = Instant.ofEpochMilli( millisSinceEpoch ) ;
我建议不要将跟踪时间作为从纪元开始的计数。这样的数字对人类来说毫无意义,因为我们无法从纯粹的整数中确定时刻。这意味着错误可能会被忽视。而且调试比较困难。此外,还有Y2K38问题。
相反,当以文本方式存储或交换日期时间值时,请使用标准 ISO 8601 格式。
我认为没有必要将
ZonedDateTime.now()
设置为空值。
您可以使用 zonedDateTime.toInstant()
然后 instant.toEpochMilli()
以毫秒为单位获取它。