当前位置: 首页 > 知识库问答 >
问题:

Instant和LocalDateTime之间有什么区别?

上官兴昌
2023-03-14

我知道:

  • 即时是一种用于计算的“技术性”时间戳表示(纳秒)。
  • LocalDateTime是包含人类时区的日期/时钟表示形式。

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

共有1个答案

杨飞
2023-03-14

instantlocaldatetime是两种完全不同的动物:一种代表瞬间,另一种不代表瞬间。

  • instant表示时刻,即时间线中的特定点。
  • localdatetime表示日期和一天中的时间。但由于缺少时区或与UTC的偏移量,这个类不能表示一个时刻。它代表了大约26到27小时范围内的潜在时刻,这是全球所有时区的范围。localdatetime值本质上不明确。

localdatetime是包含人类时区的日期/时钟表示。

引用该类'DOC:

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

所以local…的意思是“没有分区,没有偏移”。

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

如果时-分-秒的数目为零,则offsetdatetime表示与instant相同的以UTC表示的时刻。

ZoneOffset类表示从-UTC偏移量,即在UTC之前或之后的小时、分钟、秒数。

zoneoffset仅仅是小时-分钟-秒的数字,仅此而已。一个区域要多得多,它有一个名称和一个要抵消的更改历史记录。因此使用区域总是比仅使用偏移量更可取。

时区由zoneid类表示。

例如,巴黎的新一天比蒙特利尔的新一天来得早。所以我们需要移动时钟指针,以更好地反映给定区域的正午(当太阳直接在头顶时)。西欧/非洲的UTC线向东/向西越远,偏移量就越大。

时区是一组规则,用于处理当地社区或地区所实行的调整和异常。最常见的反常现象是日光节约时间(DST)这一非常流行的疯狂现象。

时区包含过去的规则、现在的规则和为不久的将来确认的规则的历史。

这些规则变化的频率比你想象的要高。一定要保持您的日期-时间库的规则,通常是'tz'数据库的副本,是最新的。在Java8中,Oracle发布了时区更新工具,保持最新比以往任何时候都容易。

大陆/地区格式指定适当的时区名称,例如美国/蒙特利尔非洲/卡萨布兰卡太平洋/奥克兰。切勿使用estist等2-4个字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( “Africa/Tunis” ) ; 

zoneddatetime概念上视为具有分配的zoneid即时

ZonedDateTime=(即时+区域ID)

捕捉特定地区(时区)的人们使用的挂钟时间所看到的当前时刻:

ZonedDateTime zdt = ZonedDateTime.now( z ) ;  // Pass a `ZoneId` object such as `ZoneId.of( "Europe/Paris" )`. 
ZonedDateTime zdt = instant.atZone( z ) ;
String output = zdt.toString() ;                 // Standard ISO 8601 format.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH ) ; 
String outputFormatted = zdt.format( f ) ;

“本地”日期时间类localdatetimelocaldatelocaltime是一种不同的生物。不与任何一个地方或时区绑定。它们不与时间线绑在一起。它们没有真正的意义,直到你把它们应用到一个地方,找到时间线上的一个点。

这些类名中的“local”一词对不熟悉的人来说可能是违反直觉的。这个词的意思是任何地方,或每一个地方,但不是一个特定的地方。

因此对于商业应用程序来说,“本地”类型并不常用,因为它们代表的只是一个可能的日期或时间的一般概念,而不是时间线上的一个特定时刻。商业应用程序往往关心发票到达的确切时间、产品运输的确切时间、员工被雇佣的确切时间或出租车离开车库的确切时间。因此商业应用程序开发人员最常用的是instantzoneddatetime类。

  • 我们希望在多个位置上应用某个日期和时间。
  • 我们正在预约。
  • 我们有一个尚未确定的时区。

注意,这三种情况都不涉及时间线上的某个特定点,都不是一个时刻。

有时我们希望在某个日期上表示某一天中的某一个时间,但希望将其应用到跨时区的多个地方。

例如,“圣诞节在2015年12月25日午夜开始”是一个localdatetime。巴黎和蒙特利尔的午夜钟声不同,西雅图和奥克兰的午夜钟声也不同。

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

另一个例子,“Acme Company有一个策略,它在全球的每个工厂的午餐时间从下午12:30开始”是localtime。要有真正的意义,你需要将它应用到时间线上,计算出斯图加特工厂的12:30或者拉巴特工厂的12:30或者悉尼工厂的12:30。

使用localdatetime的另一种情况是预订将来的活动(例如:牙医约会)。这些任命在未来可能会很遥远,以至于你冒着政客们重新定义时区的风险。政客们往往很少预先警告,甚至根本没有警告。如果你指的是“明年1月23日下午3点”,不管政客们如何摆弄时钟,那么你就不能记录一个时刻--比如,如果该地区采用或取消夏令时,那么下午3点就会变成下午2点或下午4点。

对于约会,存储分别保存的localdatetimezoneid。稍后,在生成计划时,通过调用LocalDateTime::AtZone(ZoneId)生成ZonedDateTime对象来即时确定时刻。

ZonedDateTime zdt = ldt.atZone( z ) ;  // Given a date, a time-of-day, and a time zone, determine a moment, a point on the timeline.

如果需要,您可以调整为UTC。从ZonedDateTime中提取即时

Instant instant = zdt.toInstant() ;  // Adjust from some zone to UTC. Same moment, same point on the timeline, different wall-clock time.

有些人可能在时区或偏移量未知的情况下使用localdatetime

我认为这个案子是不恰当和不明智的。如果区域或偏移量是预定的,但未确定,则数据不正确。这就像存储一个产品的价格,而不知道预期的货币(美元、英镑、欧元等)。不是个好主意。

为了完整起见,这里列出了所有可能的日期-时间类型,包括Java中的现代和遗留类型,以及SQL标准定义的类型。这可能有助于将InstantLocalDateTime类放置在更大的上下文中。

请注意Java团队在设计JDBC4.2时做出的奇怪选择。他们选择支持所有java.time时间…除了两个最常用的类:instantzoneddatetime

但不用担心。我们可以很容易地来回转换。

正在转换即时

// Storing
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;

// Retrieving
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Instant instant = odt.toInstant() ;

正在转换zoneddatetime

// Storing
OffsetDateTime odt = zdt.toOffsetDateTime() ;
myPreparedStatement.setObject( … , odt ) ;

// Retrieving
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = odt.atZone( z ) ; 

您可以直接与数据库交换java.time对象。使用与JDBC4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要java.sql.*类。Hibernate5&JPA2.2支持java.time。

从哪里获取java.time类?

  • Java SE 8、Java SE 9、Java SE 10、Java SE 11和更高版本--带有捆绑实现的标准Java API的一部分。
    • Java 9带来了一些小功能和修补程序。
      null
      null

 类似资料:
  • 问题内容: 我知道: 即时是用于计算的“技术”时间戳表示(纳秒)。 LocalDateTime是日期/时钟表示形式,包括人类的时区。 最后,对于大多数应用程序用例,IMO都可以视为两种类型。例如:当前我正在运行一个批处理作业,我需要根据日期计算下一次运行,并且我正在努力寻找这两种类型之间的优缺点(除了Instant和时区部分的纳秒级精度优势)的LocalDateTime)。 您可以列举一些应用示例

  • 问题内容: 在此示例中: 无法编译为: 而被编译器接受。 这个答案说明唯一的区别是,与不同,它允许您稍后引用类型,似乎并非如此。 是什么区别,并在这种情况下,为什么不第一编译? 问题答案: 通过使用以下签名定义方法: 并像这样调用它: 在jls§8.1.2中,我们发现(有趣的部分被我加粗了): 通用类声明定义了一组参数化类型(第4.5节), 每种可能通过类型arguments调用类型参数节的类型

  • 问题内容: 今天,我按照一些说明在Linux中安装软件。有一个脚本需要首先运行。它设置一些环境变量。 指令告诉我要执行,但是我执行错误了。因此未设置环境。最后,我注意到了这一点并继续进行。 我想知道这两种调用脚本方法的区别。我对Linux完全陌生,所以请尽可能详细。 问题答案: 运行脚本,将启动一个新的运行脚本的外壳。新的外壳程序不会影响启动脚本的父外壳程序。 是的简写形式,它将在当前shell中

  • 问题内容: 我刚开始使用Spring。我遇到了很多教程。我看到使用更多的例子比。我查看了Spring文档,但无法弄清楚使用其中一个的好处。有人可以提供一些解释吗? 问题答案: 是的便捷子类。 JavaDoc描述了一些添加的属性,这些属性在某些情况下可能有用: UrlBasedViewResolver的便利子类,它支持InternalResourceView(即Servlet和JSP)以及诸如Jst

  • 问题内容: 我刚刚看到了包含标签的CSS代码。我看着MDN看看是什么,但我真的不明白。 有人可以解释它是如何工作的吗? 它会在我们通过CSS选择之前创建DOM元素吗? 问题答案: 根据这些文档,它们是等效的: 唯一的区别是CSS3中使用了双冒号,而单冒号是旧版本。 推理: CSS 3中引入了:: before表示法,以便在伪类和伪元素之间建立区别。浏览器还接受:在CSS 2中引入的表示法。

  • 问题内容: 以下哪个更好? 要么 我知道的唯一区别是,当“ a”为null时,第一个返回false,而第二个抛出异常。除此之外,它们是否总是给出相同的结果? 问题答案: 使用时,你需要B在编译时知道类。使用时可以是动态的,并且可以在运行时更改。