登录

Instant 和 LocalDateTime 之间有什么区别?tl;博士不正确的推定InstantOffsetDateTimeZoneOffsetZoneIdZonedDateTime LocalDate, ,LocalTimeLocalDateTime 所有日期时间类型关于 java.time

datetime java java-8 jsr310
2022-08-31 04:30:09

我知道那件事:

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

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

您能举出一些应用程序示例,其中只应使用Instant或LocalDateTime吗?

编辑:当心误读LocalDateTime关于精度和时区的文档


答案 1

Table of all date-time types in Java, both modern and legacy

tl;博士

Instant并且是两种完全不同的动物:一种代表一刻,另一种则不然。LocalDateTime

  • Instant表示一个时刻,时间轴中的特定点。
  • LocalDateTime表示日期和时间。但是,如果没有时区或与 UTC 的偏移量,此类无法表示时刻。它代表了大约26到27小时范围内的潜在时刻,这是全球所有时区的范围。值本质上是模棱两可的LocalDateTime

不正确的推定

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

您的陈述不正确: LocalDateTime 没有时区。没有时区是该类的全部意义所在。

引用该类的文档:

此类不存储或表示时区。相反,它是对日期的描述,用于生日,并结合了挂钟上看到的当地时间。如果没有其他信息(如偏移量或时区),它就无法表示时间线上的某个时刻。

所以的意思是“不划区,没有偏移”。Local…

Instant

enter image description here

即时是 UTC时间轴上的一个时刻,自1970 UTC第一个时刻以来的 纳秒计数(基本上,请参阅类文档以获取细节)。由于大多数业务逻辑、数据存储和数据交换都应采用 UTC 格式,因此这是一个方便的类,可以经常使用。

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

OffsetDateTime

enter image description here

OffsetDateTime 类将某个时刻表示为日期和时间,其上下文在 UTC 之前或之后的小时-分钟-秒数。偏移量,即小时-分钟-秒数,由 ZoneOffset 类表示。

如果小时-分钟-秒数为零, 则 OffsetDateTime 表示 UTC 中与 即时相同的时刻。

ZoneOffset

enter image description here

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

A只是几小时-分-秒,仅此而已。区域要多得多,具有名称和偏移更改历史记录。因此,使用区域总是比仅使用偏移量更可取。ZoneOffset

ZoneId

enter image description here

时区由 ZoneId 类表示。

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

时区是一组规则,用于处理当地社区或地区实施的调整和异常。最常见的异常现象是被称为 夏令时(DST)的太流行的疯子。

时区具有过去规则、当前规则和确认在不久的将来的规则的历史记录。

这些规则的变化比您预期的要频繁。请务必使日期时间库的规则(通常是 “tz”数据库的副本)保持最新。在Java 8中保持最新状态比以往任何时候都更容易,Oracle发布了 时区更新器工具。

指定格式 为 的正确时区名称,例如 、 、 或 。切勿使用2-4个字母的缩写,例如或因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。Continent/RegionAmerica/MontrealAfrica/CasablancaPacific/AucklandESTIST

时区 = 偏移量 + 调整规则

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

ZonedDateTime

enter image description here

从概念上讲,可以将 ZonedDateTime 视为一个已分配的 .InstantZoneId

ZonedDateTime = ( Instant + ZoneId )

要捕捉特定地区(时区)的人们使用的挂钟时间中看到的当前时刻,请执行以下操作:

ZonedDateTime zdt = ZonedDateTime.now( z ) ;  // Pass a `ZoneId` object such as `ZoneId.of( "Europe/Paris" )`. 

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

ZonedDateTime zdt = instant.atZone( z ) ;
String output = zdt.toString() ;                 // Standard ISO 8601 format.

您可以使用 DateTimeFormatter 生成本地化格式的文本。

DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH ) ; 
String outputFormatted = zdt.format( f ) ;

mardi 30 avril 2019 à 23 h 22 min 55 s heure de l'Inde

LocalDate, ,LocalTimeLocalDateTime

Diagram showing only a calendar for a LocalDate.

Diagram showing only a clock for a LocalTime.

Diagram showing a calendar plus clock for a LocalDateTime.

“本地”日期时间类, LocalDateTimeLocalDateLocalTime,是一种不同类型的小动物。它们不与任何一个地方或时区相关联。它们与时间线无关。它们没有真正的意义,直到您将它们应用于某个位置以在时间轴上找到一个点。

这些类名中的“本地”一词可能对外行人有悖常理。这个词的意思是任何地方,或每个地方,但不是一个特定的地方。

因此,对于业务应用,“本地”类型并不常用,因为它们仅表示可能的日期或时间的一般概念,而不是时间轴上的特定时刻。业务应用程序倾向于关注发票到达的确切时刻,运送产品进行运输,雇用员工或出租车离开车库的确切时刻。因此,业务应用程序开发人员最常使用和类。InstantZonedDateTime

那么我们什么时候会使用?在三种情况下:LocalDateTime

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

请注意,这三种情况都没有涉及时间轴上的某个特定点,这些都不是时刻。

一天中的一个时间,多个时刻

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

例如,“圣诞节从 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公司有一项政策,即午餐时间从全球每个工厂的下午12:30开始”是一个.要获得真正的意义,您需要将其应用于时间轴,以计算 斯图加特工厂的12:30或 拉巴特工厂的12:30或 悉尼工厂的12:30的时刻。LocalTime

预约

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

对于约会,将 a 和 a 存储为单独的存储。稍后,在生成计划时,通过调用来生成对象来动态确定时刻。LocalDateTimeZoneIdLocalDateTime::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。从 中提取 。InstantZonedDateTime

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

Table of all date-time types in Java (both modern & legacy) as well as SQL standard.

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

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

转换。Instant

// 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

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

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

Joda-Time 项目现在处于 维护模式,建议迁移到 java.time 类。

您可以直接与数据库交换 java.time 对象。使用符合 JDBC 4.2 或更高版本的 JDBC 驱动程序。不需要字符串,不需要类。Hibernate 5 & JPA 2.2 支持 java.timejava.sql.*

从哪里获取 java.time 类?

  • Java SE 8Java SE 9Java SE 10Java SE 11和更高版本 - 具有捆绑实现的标准Java API的一部分。
    • Java 9带来了一些小功能和修复。
  • Java SE 6Java SE 7
    • 大多数java.time功能都向后移植到 ThreeTen-Backport中的Java 6和7。
  • 人造人
    • 更高版本的Android(26 +)捆绑了java.time类的实现。
    • 对于早期的Android(<26),一个称为 API desugaring的过程带来了最初未内置于Android 中的java.time功能的子集。
      • 如果脱糖不能提供你需要的东西, ThreeTenABP项目会将 ThreeTen-Backport(如上所述)适应Android。请参阅 如何使用 ThreeTenABP...

Table of which java.time library to use with which version of Java or Android

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


答案 2

一个主要区别是 的部分。如果您居住在德国并创建了一个实例,而其他人居住在美国并在同一时刻创建了另一个实例(前提是时钟设置正确), 则这些对象的值实际上会有所不同。这不适用于 独立于时区的 计算。LocalLocalDateTimeLocalDateTimeInstant

LocalDateTime存储不带时区的日期和时间,但它的初始值取决于时区。的不是。Instant

此外,还提供了用于操作日期组件(如天,小时,月)的方法。An 没有。LocalDateTimeInstant

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

这两个类具有相同的精度。 不存储时区。仔细阅读javadocs,因为你可能会犯一个重大的错误,这些无效的假设: Instant和 LocalDateTime。LocalDateTime


推荐
更多 »
  • datetime time java casting
    将 Java.Util.Date 转换为 Java.Sql.Date 时出错 )
  • datetime date-format timezone java iso8601
    解析日期格式时的 Java 时区tl;博士国际标准化组织 ISO 8601避免旧的日期时间类使用 java.time关于 java.time 我有解析日期的代码,如下所示: 它工作正常,突然间,它停止工作了。事实证明,管理员在服务器上进行了一些配置更改,并且日期当前返回为“2010-12-27T10:50:44.000-08:00”,上述模式无?
  • datetime date java datetime-conversion java-8
    Java 8 - 将 LocalDate 转换为 OffsetDateTime 我想知道是否可以在Java 8中从LocalDate转换为OffsetDateTime。 例如,假设我得到了这个LocalDate: 假设我们知道时区,例如美国/圣地亚哥。
  • datetime java iso8601
    在java中将iso8601日期转换为unix时间戳tl;博士java.time城大时间Unix Timestamp关于 java.time 我有一个日期字符串 如何将上述字符串转换为unix时间戳?谢谢
  • datetime localization java java-8 java-time
    如何使用 DateTimeFormatter 解析非标准月份名称 我需要解析以下列形式的(德语)日期: 但是,模式和模式都不符合缩短的日期。当然,我可以使用以下模式来匹配缩短的月份,但是我无法匹配3和4个字符的月份。我知道我可以有两个格式?
标签
更多 »
php pass-by-reference optional-parameters default-value javascript arrays dom function string object serialization tostring visibility syntax jslint use-strict operators equality equality-operator identity-operator datetime timestamp date-arithmetic redirect angularjs loops foreach iteration scope variables
推荐
更多 »
  • Java 8: DateTimeParseException
  • 约会的自然语言解析?
  • 使用Hibernate在MySQL上将TIMESTAMP复制到DATETIME
  • 如果我有一天的特定日期,我如何获得前一周中该天的日期?tl;博士java.time关于 java.time
  • 在 Java 中递减日期
  • 如何获取当前时间?
  • 将字符串“Jun 1 2005 1:33PM”转换为日期时间
  • 如何从日期中减去一天?
  • 将 unix 时间戳字符串转换为可读日期
  • 如何将日期时间转换为日期?
  • 在 Python 中将日期转换为日期时间

玻璃钢生产厂家芜湖玻璃钢雕塑制作厂家四川家用玻璃钢花盆瀍河玻璃钢雕塑价格香港玻璃钢商场美陈雕塑泉州石狮玻璃钢雕塑玻璃钢雕塑江苏黑色玻璃钢花盆彭州玻璃钢雕塑嵩明玻璃钢仿真雕塑河南锻铜校园玻璃钢雕塑大型商场创意商业美陈定制宁夏玻璃钢孙悟空雕塑厂家玻璃钢雕塑龙骨盐城玻璃钢仿真水果雕塑南京小区玻璃钢雕塑定做鞍山玻璃钢雕塑生产厂家玻璃钢小奶牛雕塑襄凡玻璃钢雕塑厂上海玻璃钢雕塑商道具玻璃钢雕塑价格计算广东花钵玻璃钢雕塑公司德兴玻璃钢门头雕塑景观卡通雕塑玻璃钢供应敦煌玻璃钢牌匾雕塑广场人像雕塑玻璃钢肇庆玻璃钢卡通雕塑厂家玻璃钢马车雕塑视频景观标识玻璃钢仿铜雕塑设计玻璃钢花盆批发1000商场dp点美陈租赁福建节庆商场美陈哪里买香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化