我尝试使用LocalDateTime在应用程序中操作日期,但我注意到从中获取纪元秒数返回的值与我预期的值不同
val now1 = Instant.now().epochSecond - 60
val now2 = Instant.now().minusSeconds(60).epochSecond
val now3 = LocalDateTime.now().minusSeconds(60).toEpochSecond(ZoneOffset.UTC)
val now4 = System.currentTimeMillis() / 1000 - 60
产出
Now1 = 1674501451
Now2 = 1674501451
Now3 = 1674512251
Now4 = 1674501451
注意Now3的值是不同的,这是怎么回事?
2条答案
按热度按时间rdlzhqv91#
您需要将
LocalTime#now(ZoneId zone)
与ZoneOffset.UTC
一起使用,以获取UTC的本地时间;否则,系统提取系统所在时区的本地时间。ONLINE DEMO
从**Trail: Date Time**了解有关现代日期-时间API的更多信息。
rqcrx0a62#
TL;医生
LocalDateTime
类的使用不当。∮时刻对不时刻∮
我正在尝试使用LocalDateTime操作日期
别说了
如果你正在表示一个时刻,时间线上的一个特定点,不要使用
LocalDateTime
。这个类保存了一个日期和一天中的时间,但是缺少时区或UTC偏移量的上下文。要表示一个时刻,使用:👉 do not useLocalDateTime
. That class holds a date with a time-of-day but lacks the context of a time zone or offset-from-UTC. To represent a moment use:Instant
-UTC中的时刻(相对于UTC的零时-分-秒偏移量)。OffsetDateTime
-特定偏移下的力矩。ZonedDateTime
-通过特定时区看到的时刻。我无法想象调用
LocalDateTime.now
是正确的事情的任何场景。LocalDateTime#toEpochSecond
在
LocalDateTime
上调用toEpochSecond
方法在概念上是比较棘手的,作为一个概念,LocalDateTime
没有epoch reference点,只是一个带时间的日期,比如"2023年1月23日中午"本身就没有具体的含义,不能被固定在时间线上的某个点上。所以将"2023年1月23日中午"与一个参考点进行比较是没有意义的,比如UTC中看到的1970年的第一时刻,1970年1月1日零时实际上,
LocalDateTime
类的实现就像是在UTC中一样。因此,在内部,该类计算自1970 - 01 - 01T00:00Z以来的整数秒数,加上小数秒的纳秒计数。但是,在为业务逻辑编写代码时,不应该考虑此实现细节。对于业务逻辑,调用LocalDateTime#toEpochSecond
没有意义。从技术上讲
因此,从技术上来说,您的问题的答案是,您的3小时增量(1_674_501_451L-1_674_512_251L)是由于JVM当前的默认时区使用了+03:00的偏移量,比UTC早3小时。因此,您调用
LocalDateTime.now
捕获了比UTC早3小时的日期和时间,但随后您请求toEpochSecond
,它将相同的日期和时间视为UTC**。从逻辑上讲
当然,这个日期和时间并不代表UTC中的某个时刻,所以从逻辑上讲,您的代码是没有意义的,您不应该将
LocalDateTime
(这是一个非时刻)的历元计数与其他类(如Instant
,这是一个时刻)进行比较。换句话说,你是comparing apples and oranges。
序列化日期-时间数据
那么,如果
LocalDateTime#toEpochSecond
不适合于业务逻辑,那么该类为什么要提供这样一个方法呢?该方法对于序列化
LocalDateTime
值以进行存储或数据交换很有用。其他一些系统可能以这种方式显示日期时间值。ISO 8601标准
但是,使用引用计数是一种很差的日期时间值通信方式。这些值是不明确的,因为它们的粒度是隐式的,而且它们特定的纪元参考点也是隐式的。而且,这样的值使人类读者难以验证和调试。
我强烈建议在Java之外存储或交换日期-时间值时使用标准的ISO 8601文本而不是count。
2023年1月23日22时17分31秒
一般建议:* * 避免使用
LocalDateTime
类**,除非您 * 非常 * 清楚它的适当用法。对于商业应用程序,我们通常会跟踪时刻。例如,"这个合同什么时候生效","这个员工什么时候被雇佣","这个房子什么时候结束购买"。所以不需要
LocalDateTime
。LocalDateTime
的两个业务场景是(a)如果时区规则发生变化,我们希望时间浮动的预约,如诊所和沙龙预约,以及(b)这里我们指的是几个时刻,每个时刻都有相同的挂钟时间,但发生在时间线上的不同点,例如"中午在我们公司位于德里、杜塞尔多夫、和底特律。"。搜索栈溢出了解更多关于这一点,因为我和其他人已经张贴多次。On Ideone.com,请参阅我在编写此答案时参考的一些代码。