为什么java 8现在具有LocalDateTime类

时间:2016-12-22 15:21:24

标签: date java-8 java-time

正如我们所知,在java中我们可以使用现有的API来获取当前的日期和时间,并与新的LocalDateTime类now()方法之间的区别进行比较。

1 个答案:

答案 0 :(得分:2)

TL;博士

  • 如果提到DateCalendarSimpleDateFormat,这些都是可怕的旧课程,现在已经遗留下来了。 永远不要使用。
  • 仅使用现代java.time类。
  • LocalDateTime 无法代表片刻,因为它故意缺少任何时区概念或偏离UTC的概念。所以LocalDateTime.now没有实际用处。
  • 使用Instant.now表示UTC,或ZonedDateTime.now表示特定时区的当前时刻。

避免遗留日期时间类

如果通过“现有API' s”表示旧的日期时间类,例如DateCalendarSimpleDateFormat,则应避免使用这些类。尽管他们在日期时间处理方面是出于好意的行业领先尝试,但事实证明它们设计糟糕,令人困惑且麻烦。他们现在是legacy

使用java.time

相反,请使用java.time类。添加到Java 8及更高版本。许多功能都被反向移植到Java 6& 7& Android也是如此。

Local…个类型

“本地...”类缺少offset-from-UTCtime zone的任何概念。因此,他们对可能的时刻只是一个模糊的想法。没有偏移或区域,没有实际意义。

本地日期时间的一个例子是圣诞节开始时,2016-12-25T00:00:00。在我们应用偏移量或区域之前,这不会确定时间线上的特定点。圣诞节在东部早些时候开始。这就是为什么Santa开始他在太平洋地区的交付,例如在新西兰奥克兰的午夜,并在午后的晚些时候前往亚洲,然后在午夜开始后将驯鹿送往印度,依此向西飞行。

LocalDateTime不经常使用

enter image description here

因此虽然可能会在now上调用LocalDateTime的用例,但我无法想象。

LocalDateTime的主要用途是解析缺少任何偏移或区域指示的字符串。这些字符串的设计很差,因为它们不完整。你会在没有指明货币的情况下传达价格吗?指定日期和时间但没有偏移/区域也是不明智的。无论如何,当你确实有这样的字符串缺少偏移/区域时,用LocalDateTime进行解析。

LocalDateTime ldt = LocalDateTime.parse( "2016-01-23T12:34:56.789" );

如果您因为给定的方案而知道预期的偏移量,请应用它。

ZoneOffset offset = ZoneOffset.ofHours( -7 );
OffsetDateTime odt = ldt.atOffset( offset );  // Now we have a moment, a specific point on the timeline.

更好的是,如果您因为给定的场景而知道时区,请使用而不是偏移量。区域是偏移加上处理异常(例如夏令时)(DST)的规则集。

ZoneId zone = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ldt.atZone( zone );  // Now we have a moment, a specific point on the timeline.

在常见的商业应用中,我们倾向于关注精确的时刻:发票何时到达,合同何时到期,约会开始时间等等。对于此类时间点上的值,我们使用InstantOffsetDateTimeZonedDateTime。搜索 Stack Overflow 以获取许多示例和更多讨论。其中每个都提供now方法。在捕获当前时刻时,调用其now方法会保留重要的偏移/区域信息。相比之下,有意识地调用 LocalDateTime.now丢弃偏移/区域信息,很少是你想要的。

提示:始终将可选的offset或zone参数传递给now
如果省略,则会隐式依赖JVM当前应用的默认时区。在运行期间,可以通过该JVM中任何应用程序上的任何代码随时更改此默认值。最好明确指定您想要的/预期的偏移量或区域。恕我直言,应该要求可选参数提醒程序员他们必须始终有意识地了解时区。

当前时刻

enter image description here

使用Instant捕获UTC中的当前时刻。

可以以几纳秒的分辨率捕获,但更可能是微秒或毫秒,具体取决于JVM实现,主机硬件时钟和主机操作系统的限制。

Instant instant = Instant.now() ;  // Capture current moment in UTC.

enter image description here

从UTC调整到特定地区(时区)人员使用的挂钟时间。

ZoneId z = ZoneId.of( "Africa/Casablanca" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

或者,作为快捷方式,请跳过Instant部分。

ZonedDateTime zdt = ZonedDateTime.now( z ) ;

如果省略zone参数,则隐式应用JVM的当前默认时区。最好指定您想要的/预期的时区。

关于 java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore