LocalDate
可能模棱两可
安迪·特纳的答案是正确且有价值的。另外,我想指出LocalDate
.
该类LocalDate
表示仅日期值,没有时间,没有时区。对于任何给定的时刻,日期在全球范围内因时区而异。在某个特定时刻,在日本东京可能是“明天”,而在美国俄亥俄州托莱多可能是“昨天”。两个不同的日期在同一时刻生效。
因此,虽然您可能认为日期包含 24 小时,定义了特定的时刻范围,但事实并非如此。您必须将日期放在时区的上下文中才能确定时刻。(顺便说一句,日子并不总是 24 小时。)
LocalDate localDate = LocalDate.of( 2021 , Month.JANUARY , 24 ) ;
ZoneId zoneTokyo = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime startOfDayTokyo = localDate.atStartOfDay( zoneTokyo ) ; // Determine a specific moment.
startOfDayTokyo.toString(): 2021-01-24T00:00+09:00[亚洲/东京]
要在 UTC 中查看同一时刻,请提取一个Instant
对象。
Instant instant = startOfDayTokyo.toInstant() ;
请注意,日期是 23 日而不是 24 日。
即时.toString(): 2021-01-23T15:00:00Z
通过第三个挂钟时间查看同一时刻,即美国俄亥俄州托莱多时区的时刻America/New_York
。
ZonedDateTime zdtToledo = instant.atZone( ZoneId.of( "America/New_York" ) ) ;
请注意,日期是 23 日而不是 24 日。
zdtToledo.toString(): 2021-01-23T10:00-05:00[美国/纽约]
请参阅在 IdeOne.com 上实时运行的代码。
因此,在存储 a 时LocalDate
,您可能还想存储时区名称。在数据库表中,这意味着两列。
例如,想想生日。如果知道某人当天的年龄至关重要,那么仅日期值是不够的。只有一个约会,一个在日本东京看起来年满 18 岁的人在美国俄亥俄州托莱多仍然是 17 岁。作为另一个例子,考虑合同中的到期日。如果仅表示日期,日本的利益相关者将认为任务过期,而托莱多的另一利益相关者将任务视为准时。
相反,当您指的是时间线上的特定点时,请使用Instant
(或OffsetDateTime
或ZonedDateTime
)。
