Instant和LocalDateTime有什么区别?

问题

我知道:

  • Instant是用于计算的"技术"时间戳表示(纳秒)。
  • LocalDateTime是日期/时钟表示,包括人类的时区。

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

你能说出一些应用示例,其中只应使用Instant或LocalDateTime吗?

编辑:注意有关精度和时区的LocalDateTime的误读文档


#1 热门回答(265 赞)

#推定不正确

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

你的陈述不正确:ALocalDateTime具有时区。没有时区是该课程的全部内容。

引用该课程'doc:

此类不存储或表示时区。相反,它是用于生日的日期的描述,结合在挂钟上看到的当地时间。如果没有附加信息(如偏移或时区),它不能代表时间线上的瞬间。

SoLocal…意思是"没有划分"。

#即时

enter image description here

AnInstantUTC时间轴上的一个时刻,自1970年UTC第一时刻以来的计数为nanoseconds(基本上,参见类文档的细节)。由于你的大多数业务逻辑,数据存储和数据交换都应该是UTC,因此这是一个经常使用的方便类。

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

#ZoneId

enter image description here

AZoneId是atime zone

时区是距离UTC数小时和分钟的偏移量。例如,新的一天早于Paris,见于Montréal。因此,对于给定区域,我们需要移动时钟的指针以更好地反映noon(当太阳直接在头顶上时)。从西欧/非洲的UTC线向东/向西越远,偏移越大。

此外,时区是一组用于处理当地社区或地区实施的调整和异常的规则。最常见的异常现象是称为Daylight Saving Time (DST)的过于流行的疯狂。

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

这些规则的更改频率高于你的预期。请务必保留日期时间库的规则,通常是最新的the 'tz' database。在Oracle 8发布aTimezone Updater Tool的Java 8中,保持最新状态比以往任何时候都更容易。

Useproper time zone names。这些名称采用大陆加SLASH加上城市或地区的形式。避免使用3-4个字母代码,如ESTIST。它们既不标准也不独特。他们进一步混淆了夏令时的混乱。

时区=偏移调整规则

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;

有时我们只有一个没有规则的偏移量。 Java为此目的提供了ZoneOffset,它是ZoneId的子类。注意那里定义的方便常量,ZoneOffset.UTC

ZoneOffset offset = ZoneOffset.of( -5 , 0 ) ;  // "-05:00"

#ZonedDateTime

enter image description here

可以将ZonedDateTime视为anInstant,并指定为ZoneId

ZonedDateTime =(Instant ZoneId)

几乎所有的后端,数据库,业务逻辑,数据持久性,数据交换都应该是UTC。但是要向用户演示,你需要调整到用户期望的时区。这是用于生成这些日期时间值的字符串表示的ZonedDateTimeclass和formatter classes的目的。

ZonedDateTime zdt = instant.atZone( z ) ;

#LocalDateTime,LocalDate,LocalTime

enter image description here

"本地"日期时间类,LocalDateTime,LocalDate,LocalTime,是一种不同的生物。它们与任何一个地区或时区无关。它们与时间轴无关.它们没有实际意义直到你将它们应用到某个地点才能在时间轴上找到一个点。

例如,"圣诞节从2015年12月25日午夜开始"是aLocalDateTime。巴黎不同时刻的午夜罢工比蒙特利尔罢工,并且在SeattleAuckland再次不同。

LocalDate ld = LocalDate.of( 2018 , Month.DECEMBER , 25 ) ;
LocalTime lt = LocalTime.MIN ;   // 00:00:00
LocalTime ldt = LocalDateTime.of( ld , lt ) ;  // Xmas morning anywhere.

另一个例子,"Acme公司有一项政策,午餐时间从世界各地的每家工厂下午12:30开始"是aLocalTime。要有真正的意义,你需要将其应用到时间线,以便在6点半的时候在617602255factory或12点30分在Rabatfactory或12点30分在Sydneyfactory。

因此,对于商业应用,通常不使用"本地"类型,因为它们仅代表可能的日期或时间的一般概念,而不是时间线上的特定时刻。商业应用程序倾向于关注发票到达的确切时刻,运输的产品,雇用的员工或出租车离开车库。因此,业务应用程序开发人员仅使用InstantZonedDateTime。另一方面,你应该考虑使用Local…类型来预订未来的事件(例如:牙医约会),将来你可能会像往常那样在没有预警的情况下改善时区的风险。

#关于java.time

thejava.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧类8418141885日期类,如java.util.Date,CalendarSimpleDateFormat

TheJoda-Timeproject,现在在maintenance mode,建议迁移到java.time类。

要了解更多信息,请参阅Oracle教程。并搜索Stack Overflow以获取许多示例和解释。规格是JSR 310

你可以直接将exchangejava.timeobjects与数据库联系起来。使用aJDBC driver符合313A11205或更高版本。不需要字符串,不需要java.sql.*classes。

从哪里获取java.time类?

  • Java SE 8,Java SE 9,Java SE 10和更高版本内置。带有捆绑实现的标准Java API的一部分。 Java 9增加了一些小功能和修复。
  • Java SE 6和Java SE 7大部分java.time功能都被反向移植到ThreeTen-Backport中的Java 6和7。
  • Android更新版本的Android捆绑java.time类的实现。对于早期的Android(<26),ThreeTenABP项目采用ThreeTen-Backport(如上所述)。请参见如何使用ThreeTenABP ....

TheThreeTen-Extraproject使用其他类扩展了java.time。该项目是未来可能添加到java.time的试验场。你可以在这里找到一些有用的类,如Interval,YearWeek,YearQuartermore


#2 热门回答(12 赞)

一个主要区别是838081009的LocalDateTime。如果你居住在德国并创建了一个LocalDateTime实例并且其他人居住在美国并且在同一时刻创建了另一个实例(假设时钟已正确设置) - 这些对象的值实际上会有所不同。这不适用于Instant,它是独立于时区计算的。

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

此外,LocalDateTime提供了操作日期,小时,月份等日期组件的方法。 AnInstant不是。

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

两个类具有相同的精度.LocalDateTime不存储时区。彻底阅读javadocs,因为你可能会犯这样无效的假设:InstantLocalDateTime


#3 热门回答(9 赞)

你错了LocalDateTime:它不存储任何时区信息,它具有纳秒精度。引用Javadoc(强调我的):

ISO-8601日历系统中没有时区的日期时间,例如2007-12-03T10:15:30。 LocalDateTime是一个不可变的日期时间对象,表示日期时间,通常被视为年 - 月 - 日 - 小时 - 分 - 秒。还可以访问其他日期和时间字段,例如日期,星期几和星期。时间表示为纳秒精度。例如,值"2007年10月2日13:45.30.123456789"可以存储在LocalDateTime中。

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