首页 > 其他分享 >Instant 和 LocalDateTime 有什么区别?

Instant 和 LocalDateTime 有什么区别?

时间:2024-12-19 12:10:48浏览次数:3  
标签:UTC java 区别 LocalDateTime Instant time Java 时区

我知道那件事:

Instant 是一种用于计算的“技术”时间戳表示形式(纳秒)。
LocalDateTime 是日期/时钟表示形式,包括人类的时区。
尽管如此,最终 IMO 都可以作为大多数应用程序用例的类型。例如:当前,我正在运行一个批处理作业,我需要根据日期计算下一次运行,并且我正在努力寻找这两种类型之间的优/弊(除了纳秒精度优势和时区部分)。InstantLocalDateTime

您能否列举一些仅使用或应该使用的应用示例?InstantLocalDateTime
另外:
Java 中所有日期时间类型的表,包括现代日期时间和传统日期时间类型
tl;博士
Instant并且是两种完全不同的动物:一个代表一个时刻,另一个则不代表。LocalDateTime

Instant表示一个时刻,即时间轴中的特定点。
LocalDateTime表示日期和时间。但是,由于缺少时区或与 UTC 的偏移量,此类无法表示时刻。它表示大约 26 到 27 小时范围内的潜在时刻,即全球所有时区的范围。值本质上是不明确的。LocalDateTime
不正确的推定
LocalDateTime而是日期/时钟表示,包括人类的时区。

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

引用该类的文档:

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

So 的意思是 “未分区,无偏移”。Local…

Instant
在此处输入图像描述

瞬间是 UTC 时间轴上的一个时刻,自 1970 UTC 的第一个时刻以来的纳秒计数(基本上,请参阅类 doc 了解细节)。由于您的大多数业务逻辑、数据存储和数据交换都应该使用 UTC,因此这是一个经常使用的方便类。

Instant instant = Instant.now() ; // Capture the current moment in UTC.
OffsetDateTime
在此处输入图像描述

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

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

ZoneOffset
在此处输入图像描述

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

A 只是小时-分钟-秒的数量,仅此而已。区域的作用要多得多,它有一个名称和要偏移的更改历史。因此,使用 zone 总是比仅使用 offset 更可取。ZoneOffset

ZoneId
enter image description here

时区由 ZoneId 类表示。

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

时区是当地社区或地区用于处理调整和异常的一组规则。最常见的异常情况是被称为夏令时 (DST) 的非常流行的疯狂。

时区包含过去规则、当前规则和近期确认规则的历史记录。

这些规则的更改频率可能比您预期的要高。请务必使日期时间库的规则(通常是 'tz' 数据库的副本)保持最新。在 Java 8 中,随着 Oracle 发布了 Timezone Updater Tool,保持最新状态比以往任何时候都更容易。

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

时区 = 偏移量 + 调整规则

ZoneId z = ZoneId.of( “Africa/Tunis” ) ;
ZonedDateTime
在此处输入图像描述

从概念上将 ZonedDateTime 视为具有分配的 .InstantZoneId

ZonedDateTime = ( 即时 + 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.

显示 LocalDateTime 的日历加时钟的图表。

“本地”日期时间类 LocalDateTime、LocalDate、LocalTime 是一种不同类型的小动物。它们不局限于任何一个地方或时区。它们不受时间线的约束。它们没有真正的意义,直到你把它们应用到一个地方,在时间轴上找到一个点。

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

因此,对于商业应用程序,“Local” 类型并不经常使用,因为它们只表示可能的日期或时间的一般概念,而不是时间轴上的特定时刻。商业应用程序往往关心发票到达的确切时间、产品运输、员工被雇用或出租车离开车库的确切时间。因此,商业应用程序开发人员最常使用 and 类。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 Company 有一项政策,即其全球每个工厂的午餐时间从下午 12:30 开始”是一个 .要获得真正的意义,您需要将其应用于时间线,以计算斯图加特工厂的 12:30 或拉巴特工厂的 12:30 或悉尼工厂的 12:30 的时刻。LocalTime

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

对于约会,将 a 和 a 分开保存。稍后,在生成计划时,通过调用 Generate Object 来动态确定时刻。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。从 中提取 an 。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

Java(包括现代和遗留的)以及SQL标准中的所有日期时间类型的表。

请注意 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.Date、Calendar和SimpleDateFormat。

要了解更多信息,请参阅 Oracle 教程。并在 Stack Overflow 中搜索许多示例和解释。规范为 JSR 310。

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

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

从哪里获得 java.time 类?

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

ThreeTen-Extra 项目使用其他类扩展了 java.time。该项目是将来可能添加到 java.time 的试验场。您可以在此处找到一些有用的类,例如 Interval、YearWeek、YearQuarter 等。

共享
改进此答案
跟随
编辑于 2022 年 8 月 15 日 14:35
Ahmed Sayed 的用户头像
艾哈迈德·赛义德
46611 枚金徽章99 枚银质徽章1616 枚铜牌
回答 2015年9月 7日 (星期日) 16:40
Basil Bourque 的用户头像
巴兹尔·布尔克
336 千米119119 枚金质徽章917917 枚银质徽章1,2千米1.2k 铜徽章
88
很好的回答。我认为一些混淆(至少是我的)来自本地命名。我对 Local 的直觉意味着与我所处的位置和我何时 (?!) 有关,这让我相信它实际上就是 ZonedDateTime 是什么。

mkobit
评论9月 8, 2015 在 13:55
8
是的,这很令人困惑。这就是为什么 java.time 巧妙地在其前身 Joda-Time(生成 ZonedDateTime)使用的 DateTime 类名中添加“Zoned”一词,以强调与“Local”类的区别。将名称 “Local” 视为 “need to be applied to some particular locality” 的简写。

巴兹尔·布尔克
评论9月 8, 2015 在 16:14
2
以单词 Local 为前缀也可能是与 java.util 包区分开来的一种方式,尽管不知何故,我觉得可能有更好的单词选择。

riddle_me_this
评论3月 31, 2016 在 18:23
2
@simonh 恰恰相反......当该新员工签署他/她的招聘文件,定义他们的福利(包括人寿保险),然后该新员工走出去喝咖啡却被卡车撞死时,会有很多人,如人力资源经理、保险代理人和律师,他们想知道新工作生效的确切时间。

巴兹尔·布尔克
评论4月 7, 2017 在 21:45
3
@simonh 是的,在某些情况下,“本地”日期时间是合适的。除了我的回答中提到的那些之外,商业中的另一个常见情况是在未来几个月内进行预约,时间足够长,以至于政客们可能会改变时区规则,通常几乎没有预先警告。政客经常进行这些更改,例如更改开启/关闭夏令时 (DST) 的日期或永久开启/关闭 DST。

标签:UTC,java,区别,LocalDateTime,Instant,time,Java,时区
From: https://www.cnblogs.com/johnsena/p/18616890

相关文章

  • Linux中,使用 ./ 和 sh 执行脚本的区别是什么
    这些区别主要体现在执行环境、权限要求和子进程管理等方面一.可执行权限(不一样)./:使用./script.sh执行脚本时,脚本必须具有可执行权限。这意味着你需要先使用chmod+xscript.sh命令来赋予脚本执行权限。chmod+xscript.sh./script.shsh:使用shscript.sh执行脚......
  • 信创适配证书、兼容性互认证书、信创产品认证证书有什么区别?
    一、三种信创证书有哪些区别?1、信创适配认证证书:发证单位:由适配中心发放;目的:证明产品在信创环境中可以安装和卸载,即证明产品“能不能用”。性质:属于企业之间的证书,主要是证明产品基本可用性。2、兼容性互认证书:常见厂商:如鲲鹏、麒麟等。目的:针对特定CPU或操作系统,证明......
  • JavaScript中var、let和const的区别是什么?
    1.变量声明关键字概述1.1var关键字的特点var是JavaScript中传统的变量声明关键字,它具有以下特点:函数作用域:使用var声明的变量在函数内部是局部的,仅在该函数内部可见。全局作用域:在函数外部声明的var变量是全局的,在整个程序中都可访问。变量提升:var声明的变......
  • 你认为领导和管理有什么区别?
    领导和管理在前端开发领域(乃至任何组织环境)中都扮演着至关重要的角色,但它们之间存在明显的区别。以下是对领导和管理在前端开发中的差异进行的详细分析:一、职责与任务领导:领导的主要任务是确立组织的前进方向,为前端开发团队设定明确、具有挑战性的目标。领导者需要具备前瞻性和......
  • 说说你对H5、小程序、APP三者之间区别的理解?
    H5、小程序和APP之间的区别主要体现在运行环境、开发成本、用户体验和功能权限等方面。以下是对这三者区别的详细理解:一、运行环境H5:H5是基于HTML5技术的移动端网页,通过浏览器访问,无需下载安装,可跨平台运行。它主要依赖于浏览器内核来渲染页面,因此其运行环境是浏览器。小程......
  • 请解释下utf8和utf8mb4的区别
    utf8和utf8mb4的区别主要体现在对Unicode字符的支持范围、编码的最大字符长度以及存储空间需求上。以下是对这两者区别的详细解释,特别从前端开发的角度进行阐述:Unicode字符支持范围:utf8:主要支持Unicode字符集中的基本多语言平面(BMP)范围内的字符,即码点范围从0x0000到0xFFFF。......
  • su和sudo的区别
    su和sudo是Linux和Unix系统中用于权限管理的两个命令,它们的主要区别如下:1.功能和用途su(SwitchUser):su命令用于切换用户身份,默认情况下,它会切换到超级用户(root)。使用su时,用户需要输入目标用户的密码。例如,执行su后,系统会提示输入root用户的密码,成功后会......
  • 前置++与后置++的区别
    前置++与后置++都是对变量值进行+1类似于a=a+1 但他们的区别就在于前置后置关系我们先来看后置++ 后置++就是先使用变量再对变量进行+1我们来给出一个代码举例↓#include<stdio.h>intmain(){ inta=10; intb=a++;//后置++是先使用再++ printf("%d%d"......
  • GRU与LSTM的区别
    GRU(门控循环单元,GatedRecurrentUnit)和LSTM(长短期记忆网络,LongShort-TermMemory)是两种常见的递归神经网络(RNN)变种。它们主要用于处理序列数据(如文本、时间序列数据等),但它们在结构上有所不同,导致它们在一些任务上的表现不同。以下是它们的主要区别、优缺点:1.结构区别LSTM(......
  • Java深入理解深拷贝和浅拷贝区别
    一、拷贝的引入(1)、引用拷贝创建一个指向对象的引用变量的拷贝。publicclassQuoteCopy{publicstaticvoidmain(String[]args){Teacherteacher=newTeacher("riemann",28);TeacherotherTeacher=teacher;System.out.println(teach......