我看到几乎所有接口都使用 LocalDateTime (至少在服务层)的优势,这样我的应用程序就不必管理时区,并且可以安全地假定时间始终采用 UTC。
我不确定我是否理解您的想法。LocalDateTime
并DateTime
代表两个完全不同的概念。并非 aLocalDateTime
有一些隐含的 UTC 时区:它实际上没有时区(在内部它可能表示为DateTime
带有 UTC 时区的 a,但这只是一个实现细节,对使用它的程序员无关紧要)。
您可以在 API 文档 中看到,虽然 aDateTime
是“ Instant
”(世界时间线上的一个点,一个物理概念),但 aLocalDateTime
不是这样的东西。这LocalDateTime
实际上是一个Partial
, (一个“公民”概念),在不同的类层次结构中。类名可能——不幸的是——让你认为这LocalDateTime
是 : 的一些特殊化DateTime
:好吧,它不是。
ALocalDateTime
应该被视为一对 { Date
( Y/M/D
) ; Time
( hh:mm:ss.msec
)},一组数字,对应于时间相关数据的“民用”标准表示。如果给定 a LocalDateTime
,我们不能直接将其转换为 a DateTime
,我们需要指定一个时区;这种转换将我们带到另一种实体。(类比:Java 中的字符串和字节流:要在它们之间进行转换,您必须指定字符集编码,因为它们在概念上是不同的东西)
何时在应用程序中使用其中一种……有时是有争议的,但一旦了解了 Jodatime 的概念,通常就足够清楚了。而 IMO 与“层”关系不大,可能更多的是与用例或场景相关。
一个不平凡的例子:你在谷歌工作,为日历编程。您必须让用户管理(添加、查看、修改)包含日期时间的事件(让我们忽略重复事件),例如“我在 2019 年 7 月 3 日上午 10:00 与我的医生有约会”。在软件层中使用的时间-日期实体是什么(对于这个用例)?我会说:一个LocalDateTime
. 因为用户实际上并不是在处理一个物理时间点,而是在处理一个民用时间:在他的手腕上或在他的家中显示时钟的日期和时间。他甚至没有考虑时区(让我们忽略一个在世界各地旅行的用户的特殊情况......)然后,在业务和表示层中,a LocalDateTime
似乎是正确的实体。
但是假设您还必须编写一个不同的场景:提醒。当 Google 内部调度器检测到用户存储的事件是从现在开始的 N 分钟后,它必须向他发送提醒。在这里,“从现在开始的 N 分钟”是一个完全“物理”的时间概念,所以这里的“业务层”将处理DateTime
. 有几种选择,例如:事件被存储在数据库中LocalDateTime
(即,只是没有时区的时间和日期——一个经常使用 UTC 时间戳来表示它,但这是一个实现细节)。在这种情况下(仅在这种情况下),我们必须将其加载为DateTime
,我们使用时区转换它,可能来自用户的配置文件。