英文:
Set empty value for ZonedDateTime
问题
I want to migrate this code from Joda-Time to its replacement, java.time (JSR 310).
Specifically, I want to use ZonedDateTime
.
Old code:
DateTime startTime = new DateTime();
DateTime stopTime = new DateTime();
durationMilli = Math.max(1, (stopTime.getMillis() - startTime.getMillis()));
to
ZonedDateTime startTime = ZonedDateTime.now();
ZonedDateTime stopTime = ZonedDateTime.now();
durationMilli = Math.max(1, (stopTime.toInstant().toEpochMilli() - startTime.toInstant().toEpochMilli()));
I have the following questions.
How can I set ZonedDateTime.now()
to an empty value? As you can see, stopTime
should be empty.
The issue is that the method getMillis
is missing. How can I get milliseconds?
英文:
I want to migrate this code from Joda-Time to its replacement, java.time (JSR 310).
Specifically I want to use ZonedDateTime
.
Old code:
DateTime startTime = new DateTime();
DateTime stopTime = new DateTime();
durationMilli = Math.max(1, (stopTime.getMillis() - startTime.getMillis()));
to
ZonedDateTime startTime = ZonedDateTime.now();
ZonedDateTime stopTime = ZonedDateTime.now();
durationMilli = Math.max(1, (stopTime.getMillis() - startTime.getMillis()));
I have the following questions.
How I can set ZonedDateTime.now()
to empty value? As you can see stopTime
should be empty.
Send issue is that method getMillis
is missing. How I can get milliseconds?
答案1
得分: 3
tl;dr
>如何将ZonedDateTime.now()设置为空值?
像对待其他类的对象引用一样处理。要么:
null
Optional.empty
>如何获取毫秒数?
myZonedDateTime.toInstant().toEpochMilli()
详细信息
是的,ZonedDateTime
替代了DateTime
Joda-Time中的DateTime
类表示一个时刻,即在特定时区中查看的时间线上的特定点。
new org.joda.time.DateTime()
捕捉当前时刻,视为当前默认时区中的时刻。在java.time中的等价物是ZonedDateTime.now()
。
明确指定时区
顺便说一下,我发现明确指定您知道并希望使用JVM的当前默认时区更清晰。像这样:ZonedDateTime.now( ZoneId.systemDefault() )
,而不是隐式依赖默认时区。
空值?
您说:
>正如您所看到的,stopTime应该是空的。
不,我根本看不到。在您的代码中,哪里有任何类型的空值?
诸如ZonedDateTime
之类的日期时间对象总是有值的。它的任务就是有一个值,具体地说是:代表一个经过时区查看的时刻。因此,没有“空”值。如果要表示没有已知的时刻,请使用以下任一选项:
null
Optional
…推荐使用Optional
。请参阅baeldung的Java 8 Optional指南。
Optional< ZonedDateTime > empty = Optional.empty();
作为占位符的纪元参考
或者,如果您想将特定时刻用作标志或占位符,我建议使用java.time中定义的纪元参考:1970年的第一时刻,与UTC的零小时-分钟-秒的偏移量为零,即1970-01-01T00:00Z。
java.time.Instant
类具有该值的预定义常量:Instant.EPOCH
。
在UTC和时区之间进行调整
您可以将UTC中的Instant
调整为特定时区中的ZonedDateTime
。
Instant instant = Instant.EPOCH ;
ZoneId z = Zone.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
然后再次回到UTC时区(零偏移量)。
Instant instant = zdt.toInstant() ;
自纪元参考以来的毫秒数
您可以查询Instant
对象的自纪元参考以来的毫秒数。请注意可能会丢失数据,因为Instant
对象可能具有您将要忽略的微秒或纳秒。
long millisSinceEpoch = instant.toEpochMilli() ;
然后再反向操作:
Instant instant = Instant.ofEpochMilli( millisSinceEpoch ) ;
ISO 8601
我建议不要将时间跟踪为自纪元开始的计数。这样的数字对人类来说毫无意义,因为我们无法从纯整数数字中确定时刻。这意味着错误可能会被忽略。而且调试更加困难。此外,还存在Y2K38问题。
相反,当以文本方式存储或交换日期时间值时,请使用标准的ISO 8601格式。
英文:
tl;dr
>How I can set ZonedDateTime.now() to empty value?
Do as you would do for an object reference of any other class. Either:
null
Optional.empty
>How I can get milliseconds?
myZonedDateTime.toInstant().toEpochMilli()
Details
Yes, ZonedDateTime
replaces DateTime
The DateTime
class in Joda-Time represents a moment, a specific point on the timeline, as viewed through a specific time zone.
new org.joda.time.DateTime()
captures the current moment as seen in the current default time zone. It's equivalent in java.time is ZonedDateTime.now()
.
Make time zone explicit
By the way, I find it more clear to specify that you know and want the JVM’s current default time zone. Like this: ZonedDateTime.now( ZoneId.systemDefault() )
rather than rely implicitly on the default.
Empty?
You said:
>As you can see stopTime should be empty.
No, I do not see that at all. Where in your code is there any kind of empty value?
A date-time object such as ZonedDateTime
always has a value. Having a value is its job, specifically: representing a moment as seen through a time zone. So there is no "empty" value. If you want to represent having no known moment, use either:
null
Optional
… with Optional
being recommended. See Guide To Java 8 Optional by baeldung.
Optional< ZonedDateTime > empty = Optional.empty();
Epoch reference as a placeholder
Alternatively, if you want to use a specific moment as a flag or placeholder, I would suggest using the epoch reference defined in java.time: the first moment of 1970 with an offset of zero hours-minutes-seconds from UTC, 1970-01-01T00:00Z.
The java.time.Instant
class has a predefined constant for that value: Instant.EPOCH
.
Adjusting between UTC and a time zone
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 ) ;
And go back again, moving from time zone to UTC (zero offset).
Instant instant = zdt.toInstant() ;
Count of milliseconds since epoch reference
You may interrogate the Instant
object for a count of milliseconds since the epoch reference of 1970-01-01T00:00Z. Be aware of possible data loss, as an Instant
object may have microseconds or nanoseconds that you’ll be ignoring.
long millisSinceEpoch = instant.toEpochMilli() ;
And back the other direction:
Instant instant = Instant.ofEpochMilli( millisSinceEpoch ) ;
ISO 8601
I recommend against tracking time as a count from epoch. Such numbers are meaningless to humans, as we cannot determine a moment from a mere integer number. That means errors can slip by unnoticed. And debugging is more difficult. Also, there is the Y2K38 Problem.
Instead, when storing or exchanging date-time values textually, use standard ISO 8601 formats.
答案2
得分: 0
不需要将 ZonedDateTime.now()
设置为空值。您可以使用 zonedDateTime.toInstant()
然后 instant.toEpochMilli()
来获取以毫秒为单位的时间戳。
英文:
I dont think there is a need to set ZonedDateTime.now()
to empty value.
You can use zonedDateTime.toInstant()
and then instant.toEpochMilli()
to get it in milliseconds.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论