Java 8:Instant和LocalDateTime有什么区别?

我知道:

  • 即时是计算的“技术”时间戳表示(纳秒)。
  • LocalDateTime是date/时钟表示,包括人类的时区。

仍然在最后IMO可以作为types的大多数应用程序的用例。 举个例子:目前我正在运行一个批处理作业,我需要根据date计算下一次运行,而我正在努力寻找这两种types之间的优点/缺点(除了Instant和时区部分的纳秒精度优势LocalDateTime)。

你能命名一些应用程序的例子,只有即时或LocalDateTime应该使用?

编辑:谨防LocalDateTime有关精度和时区的文件误读

错误的推定

LocalDateTime是date/时钟表示,包括人类的时区。

您的声明不正确: LocalDateTime 没有时区 。 没有时区是这个class级的全部要点。

引用那个类'doc:

这个class不存储或代表一个时区。 相反,它是用于生日的date的描述,结合在挂钟上看到的当地时间。 它不能代表时间线上没有附加信息,如偏移量或时区。

所以Local…意味着“不被划分”。

瞬间

Instant是UTC时间线上的一个时刻,自UTC 1970年第一时刻开始,这个时间为纳秒 (基本上,请参阅class doc了解细节)。 由于您的大部分业务逻辑,数据存储和数据交换应该使用UTC,因此这是一个经常使用的方便的类。

了zoneid

ZoneId是一个时区 。

一个时区是距离UTC很多小时和分钟的偏移量。 例如, 巴黎的一个新的一天比在蒙特利尔更早。 所以我们需要移动时钟的手,以更好地反映一个给定地区的中午 (当太阳直接在头顶上)。 距离欧洲的UTC线越远,偏移量越大。

另外,时区是一套处理当地社区或地区实行的调整和exception的规则。 最常见的exception是被称为夏令时(DST)的非常stream行的恶梦。

时区具有过去规则的历史,现在的规则,以及近期确认的规则。

这些规则的变化比你预期的要多。 一定要保持date – 时间库的规则,通常是“tz”数据库的副本, 是最新的。 在Oracle8发布Timezone Updater Tool的 Java 8中,保持最新状态比以往任何时候都容易。

使用适当的时区名称 。 这些名称以大陆加SLASH加上一个城市或地区的forms出现。 避免使用诸如ESTIST类的3-4字母代码。 它们既不标准也不唯一。 他们进一步混淆了DST的混乱。

时区=偏移+调整规则

有时候我们只有一个没有规则的偏移。 Java为此提供了ZoneOffset ,它是ZoneOffset的一个子类。 请注意在此定义的方便常数ZoneOffset.UTC

ZonedDateTime

ZonedDateTime类是带有指定ZoneId的Instant。

ZonedDateTime = Instant + ZoneId

几乎所有的后端,数据库,业务逻辑,数据持久性,数据交换都应该是UTC。 但是为了向用户展示,您需要调整到用户期望的时区。 这是ZonedDateTime类和用于生成这些date时间值的string表示的格式化程序类的用途。

LocalDateTime,LocalDate,LocalTime

“本地”date时间类LocalDateTimeLocalDateLocalTime是另一种生物。 这不是绑定到任何一个地区或时区。 他们不受时间限制。 他们没有真正的意义,直到你将它们应用到一个地方在时间线上find一个点。

例如,“圣诞节从2015年12月25日午夜开始”是LocalDateTime。 巴黎不同时刻的午夜打击比蒙特利尔要晚,在西雅图和奥克兰又有所不同。

另一个例子,“Acme公司有一个政策,午餐时间在下午12:30在其全球各工厂”是LocalTime。 要有实际意义,您需要将其应用于时间线,以便在斯图加特工厂12:30或在拉巴特工厂12:30或悉尼工厂12:30。

所以对于商业应用程序来说,“本地”types并不经常被使用,因为它们仅代表可能date或时间的一般概念,而不是时间线上的特定时刻。 商业应用程序倾向于关注发票到达的确切时刻,运输产品,雇用员工,或出租车离开车库。 所以商业应用程序开发人员几乎完全使用InstantZonedDateTime 。 另一方面,你应该考虑使用Local…types来预订未来的事件(例如:牙医预约),将来你可能会冒着政治家的风险去提前预测时间。

一个主要区别是LocalDateTimeLocal部分。 如果你住在德国,并创build一个LocalDateTime实例,而其他人住在美国,并在同一时刻创build另一个实例(假设时钟设置正确) – 那些对象的价值实际上是不同的。 这不适用于Instant ,这是从时区独立计算。

LocalDateTime存储没有时区的date和时间,但它的初始值是依赖于时区的。 Instant的不是。

此外, LocalDateTime提供了操作date组件的方法,如日,小时,月。 Instant不。

除了Instant的纳秒精度优势和LocalDateTime的时区部分之外

两个类都具有相同的精度。 LocalDateTime不存储时区。 彻底阅读javadocs,因为你可能会犯这样一个非常错误的假设: 即时和LocalDateTime 。

LocalDateTime是错误的:它不存储任何时区信息,精度达到纳秒级。 引用Javadoc(强调我的):

ISO-8601日历系统中没有时区的date时间 ,例如2007-12-03T10:15:30。

LocalDateTime是一个不可变的date – 时间对象,代表date – 时间,通常被视为年 – 月 – 日 – 时 – 分 – 秒。 还可以访问其他date和时间字段,例如年,日和星期。 时间表示为纳秒精度 。 例如,“2007年10月2日13:45.30.123456789”的值可以存储在LocalDateTime中。

两者之间的区别在于, Instant表示与时代(01-01-1970)的偏移,因此表示时间线上的特定时刻。 同时在地球的两个不同的地方创build的两个Instant对象将具有完全相同的值。

Instant对应于主要子午线(格林威治)的时间。

LocalDateTime相对于操作系统的时区设置和

如果没有附加信息(如偏移量或时区),则不能表示瞬间。