Oli*_*Oli 4 java java-time java.time.instant
我想代表一个“营业日期”,例如“2019 年 6 月 3 日”发生的交易。为此,我们主动忽略时区,因为我们完全知道日本的“2019 年 6 月 3 日”可能是美国的“2019 年 6 月 2 日”——而在“一天”内订购同样无关紧要。所有日期都是今天或之前的日期。
我显而易见的答案是,这是一个LocalDate. 但是,其他人建议将其表示为Instantof更好2019-06-03T00:00:00.000Z。
除了在 UI 中将其转换/格式化为人类可读的日期时我们必须进行的不同调用,这两种方法之间实际上有什么区别吗?
这是一个与Instant 和 LocalDateTime 之间有什么区别的不同问题?因为时间与这个问题无关,它只与过去(或当前)日期有关。
我曾经在开发一种产品时犯了将出生日期表示为瞬间的错误。
这是我们多年后仍在处理的那些“微小”设计错误之一。
问题是当用户更改时区时,您无法在 UI 中可靠地显示它;在后端转换很容易出错,因为开发人员在不同的时区工作与服务器运行的地方。它有点在一个时区工作,但随着产品扩展到其他时区,它变得令人头疼。
瞬间是时间线上的一个点;本地日期是一个时间范围(而不是一个明确定义的时间范围,因为它可以代表不同时区的不同瞬间范围)。它们代表不同的事物。
如果要表示日期,请存储日期。我的意思不是 a java.util.Date,它真的是一瞬间。
使用一个LocalDate.
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.
Run Code Online (Sandbox Code Playgroud)
startOfDayTokyo.toString(): 2021-01-24T00:00+09:00[亚洲/东京]
要在 UTC 中查看同一时刻,请提取一个Instant对象。
Instant instant = startOfDayTokyo.toInstant() ;
Run Code Online (Sandbox Code Playgroud)
请注意,日期是 23 日而不是 24 日。
Instant.toString(): 2021-01-23T15:00:00Z
通过第三个挂钟时间看到同一时刻,美国俄亥俄州托莱多的时区America/New_York。
ZonedDateTime zdtToledo = instant.atZone( ZoneId.of( "America/New_York" ) ) ;
Run Code Online (Sandbox Code Playgroud)
请注意,日期是 23 日而不是 24 日。
zdtToledo.toString(): 2021-01-23T10:00-05:00[美国/纽约]
查看此代码在 IdeOne.com 上实时运行。
因此,在存储 a 时LocalDate,您可能还想存储时区名称。在数据库表中,这意味着两列。
举个例子,想想生日。如果知道某人当天的年龄至关重要,那么仅日期值是不够的。只有一个约会对象,在日本东京看起来年满 18 岁的人在美国俄亥俄州托莱多仍然是 17 岁。再举一个例子,考虑合同中的到期日。如果仅声明为日期,日本的一个利益相关者会将任务视为逾期,而托莱多的另一个利益相关者则认为该任务准时完成。
相反,当您指的是某个时刻、时间线上的特定点时,请使用Instant(或OffsetDateTime或ZonedDateTime)。
| 归档时间: |
|
| 查看次数: |
1557 次 |
| 最近记录: |