Joda-Time库包含不同的日期时间类
DateTime - 不可变更替 对于JDK日历
DateMidnight - 表示强制时间的日期的不可变类 午夜时间LocalDateTime - 表示本地的不可变类 日期和时间(无时区)
我想知道您如何在分层应用程序中使用这些类。
我看到几乎所有接口都使用LocalDateTime(至少在服务层)的优势,因此我的应用程序不必管理时区,并且可以安全地假设时间始终为UTC。然后我的应用程序可以在执行流程的最开始使用DateTime来管理时区。
我也想知道DateMidnight在哪种情况下很有用。
答案 0 :(得分:76)
我看到几乎所有的优势 使用LocalDateTime的接口(at 至少服务层)这样我的 应用程序无需管理 时区,可以安全地假设时间总是在UTC。
我不确定我在这里理解你的想法。 LocalDateTime
和DateTime
代表两个完全不同的概念。情况并非LocalDateTime
有一些隐含的UTC时区:它实际上有 no 时区(内部可能用UTC时区表示为DateTime
,但它只是一个实现细节,对使用它的程序员来说无关紧要)。
You can see in the API docs,虽然 DateTime
是“ Instant
”(世界时间线上的一个点,物理概念), LocalDateTime
不是这样的事情。 LocalDateTime
实际上是一个Partial
,(一个“民间”概念),在不同的类层次结构中。不幸的是,类名称可能会让您认为LocalDateTime
是DateTime
的某种特化:嗯,它不是。
LocalDateTime
应被视为一对{ Date
(Y/M/D
); Time
(hh:mm:ss.msec
)},一组数字,对应于与时间相关的数据的“民用”标准表示。如果我们获得LocalDateTime
,我们无法将其直接转换为DateTime
,我们需要指定时区;并且转换将我们带到另一种实体。 (类比:Java中的字符串和字节流:要在它们之间进行转换,您必须指定字符集编码,因为它们在概念上是不同的东西)
何时在应用程序中使用其中一个...它有时是有争议的,但是一旦理解了Jodatime概念,通常就足够清楚了。 IMO与“层”没有多大关系,或许更多的是用于案例或场景。
一个非平凡的边界线示例:您在Google工作,编写日历。您必须让用户管理(添加,查看,修改)包含日期时间的事件(让我们忽略重复发生的事件),说“我在2019年7月3日10:00与我的医生会面上午”。什么是在软件层中使用的时间 - 日期实体(对于此用例)?我会说:LocalDateTime
。因为用户并没有真正处理物理时间点,而是处理民用时间:在手腕或家中显示时钟的日期和时间。他甚至没有想到时区(让我们忽略在世界各地旅行的用户的特殊情况......)然后,在商业和表示层中,LocalDateTime
似乎是正确的实体。
但是假设您还必须编写不同的方案:提醒。当Google内部调度程序检测到用户存储的事件从现在开始是N分钟时,它必须向他发送提醒。在这里,“从现在起N分钟”是一个完全“物理”的时间概念,所以这里的“业务层”将处理DateTime
。例如,有几种选择:事件作为LocalDateTime
存储在数据库中(即只有时区和时间没有时区 - 一个经常使用UTC时间戳来表示,但这是一个实现细节)。在这种情况下(仅在此情况下),我们必须将其加载为DateTime
,我们使用时区进行转换,可能来自用户的个人资料。
答案 1 :(得分:0)
Answer by leonbloy是正确且至关重要的。我只是转换为替换Joda-Time项目的java.time类。
在时间轴上的特定时刻:
Instant
。 OffsetDateTime
表示。ZonedDateTime
表示偏移。这些都取代了Instant
& Joda-Time中的DateTime
课程。这些java.time类的分辨率均为nanoseconds,相对于Joda-Time使用的毫秒数。
午夜时分,Joda-Time项目总结“午夜”是一个模糊而无效的概念。与午夜相关的课程和午夜时间都在Joda-Time的后期版本中被弃用,取而代之的是“一天中的第一时刻”的实用概念。
java.time课程采用相同的课程,使用"当天的第一时刻"做法。在java.time类上查找atStartOfDay
方法,例如LocalDate
。
永远不要假设一天从00:00开始。夏令时(DST)等异常表示该日可能会在其他时间开始,例如01:00。
ZonedDateTime zdt =
LocalDate.of( 2017 , Month.MARCH , 12 ) // Instantiate a date-only value without time zone.
.atStartOfDay( ZoneId.of( "America/Havana" ) ) ; // Cuba jumps from 00:00 to 01:00 on Spring DST cut-over.
例如,看看古巴在春季DST切换时间凌晨1点开始。
zdt:2017-03-12T01:00-04:00 [America / Havana]
为了表示在约26-27小时范围内可能的时刻的模糊概念,而不是时间线上的实际时刻,请使用LocalDateTime
。此类故意缺少与UTC或时区的任何偏移。
LocalDateTime ldt = LocalDateTime.of( 2017 , Month.JANUARY , 23 , 1 , 2 , 3 , 0 ) ;
如果您的业务环境意味着特定时区,您可以应用它来获取ZonedDateTime
。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ; // Determine a specific point on timeline by providing the context of a time zone.
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。