Java Instant和LocalDateTime有什么区别?
我知道:
即时是用于计算的“技术”时间戳表示(纳秒)。
LocalDateTime是日期/时钟表示形式,包括人类的时区。
最后,对于大多数应用程序用例,IMO都可以视为两种类型。例如:当前我正在运行一个批处理作业,我需要根据日期计算下一次运行,并且我正在努力寻找这两种类型之间的优缺点(除了Instant和时区部分的纳秒级精度优势)的LocalDateTime)。
您可以列举一些应用示例,仅应使用Instant或LocalDateTime吗?
编辑:提防有关精度和时区的LocalDateTime的误读文档
回答:
Instant
和LocalDateTime
是两个完全不同的动物:一个表示了一下,其他没有。
Instant
代表时刻,是时间轴中的特定点。LocalDateTime
代表日期和时间。但是由于缺少时区或UTC偏移量,因此此类无法表示一个时刻。它代表了大约26到27小时(全球所有时区的范围)内的潜在时刻。
LocalDateTime
而是日期/时钟表示,包括人类的时区。
你的说法是不正确:一个LocalDateTime
有没有时区。没有时区是该课程的重点。
引用该类的文档:
此类不存储或表示时区。相反,它是对用于生日的日期的描述,以及在墙上时钟上看到的本地时间。如果没有其他信息(例如偏移或时区),则无法在时间线上表示时刻。
因此Local…
意味着“不分区,不偏移”。
An Instant
是UTC时间轴上的一刻,是自1970年UTC的第一刻的纪元以来的十亿分之一秒(基本上,请参阅class doc
了解更多细节)。由于大多数业务逻辑,数据存储和数据交换都应使用UTC,因此这是经常使用的方便类。
Instant instant = Instant.now() ; // Capture the current moment in UTC.
class OffsetDateTime
类将时刻表示为日期和时间,上下文比UTC早或晚一些小时-分钟-秒。偏移量(小时-分钟-秒的数量)由此ZoneOffset
类表示。
如果时分秒数为零,则OffsetDateTime
表示UTC中与相同的时刻Instant
。
所述ZoneOffset类表示偏移从-UTC,若干小时-分钟-秒比UTC或后面UTC。
A ZoneOffset
仅是小时-分钟-秒的数量,仅此而已。区域更多,具有名称和偏移更改的历史记录。因此,使用区域总是优于仅使用偏移量。
在此处输入图片说明
阿时区是由表示ZoneId类。
例如,巴黎的新黎明比蒙特利尔早。因此,我们需要移动时钟指针以更好地反映给定区域的正午(当太阳直接在头顶上方)。西欧/非洲的UTC线向东/向西越远,偏移量越大。
时区是一组规则,用于处理本地社区或区域所实施的调整和异常情况。最常见的异常是称为“ 夏令时(DST)”的太流行的疯狂。
时区具有过去规则,当前规则和在不久的将来已确认的规则的历史。
这些规则更改的频率超出你的预期。确保保持日期时间库的规则(通常是’tz’数据库的副本)是最新的。通过Oracle
发布Timezone Updater Tool
,在Java 8
中保持最新状态比以往更加容易。
指定适当的时区名称,格式Continent/Region,如America/Montreal,Africa/Casablanca
或Pacific/Auckland
。切勿使用2-4字母的缩写,例如EST或,IST因为它们不是真实的时区,不是标准化的,甚至不是唯一的(!)。
Time Zone = Offset + Rules of Adjustments
ZoneId z = ZoneId.of( “Africa/Tunis” ) ;
在此处输入图片说明
在ZonedDateTime概念上将其视为Instant具有分配的对象ZoneId。
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
“本地”的日期时间类,LocalDateTime,LocalDate,LocalTime
,有一种别样的小动物的。不受任何地区或时区的限制。它们不受时间限制。除非你将它们应用于某个地方以在时间轴上找到一个点,否则它们没有真正的意义。
这些类名称中的“本地”一词可能与未使用的单词相反。该词表示任何地点,或每个地点,但不是特定地点。
因此,对于商务应用程序,“本地”类型不常用,因为它们仅表示可能的日期或时间的一般概念,而不是时间轴上的特定时刻。商业应用程序倾向于关心发票到达的确切时间,运送产品的运输,雇用员工或出租车离开车库的确切时间。因此,业务应用程序开发人员最常使用Instant
和ZonedDateTime
分类。
那我们LocalDateTime
什么时候用?在以下三种情况下:我们要在多个位置应用特定的日期和时间,我们要预约的位置,或者我们有一个尚未确定的时区。请注意,这三种情况都不是时间轴上的某个特定点,所有这些都不是片刻。
有时我们想代表某个日期的某个特定时间,但又想将其应用于跨时区的多个地区。
例如,“圣诞节从2015年12月25日午夜开始”是一个LocalDateTime
。巴黎的午夜罢工与蒙特利尔的罢工时间不同,西雅图和奥克兰的午夜罢工又有所不同。
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 PM” LocalTime
。要具有实际意义,你需要将其应用于时间轴,以计算斯图加特工厂的12:30时刻或拉巴特工厂的12:30时刻或悉尼工厂的12:30时刻。
使用的另一种情况LocalDateTime是用于预订将来的事件(例如:牙医约会)。这些任命将来可能远远不够,你可能会冒着政治家重新定义时区的风险。政客们很少发出警告,甚至根本没有警告。如果你的意思是“明年1月23日下午3点”,无论政客如何打钟,那么你就无法记录时刻-如果该地区采用或取消了夏时制,那将导致下午3点变成下午2点或下午4点,例如。
对于约会,请分别存储a LocalDateTime
和a ZoneId
。稍后,在生成时间表时,通过调用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。Instant
从中提取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标准定义的日期和时间。这可能有助于将Instant&LocalDateTime
类放在更大的上下文中。
Java(现代和传统)以及SQL标准中所有日期时间类型的表格。
注意Java团队在设计JDBC 4.2时所做出的奇怪选择。他们选择支持所有java.time时间……,除了两个最常用的类:Instant&ZonedDateTime
。
但是不用担心。我们可以轻松地来回转换。
正在转换Instant
。
// StoringOffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;
// Retrieving
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Instant instant = odt.toInstant() ;
正在转换ZonedDateTime。
// StoringOffsetDateTime 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 8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.Date
,Calendar
,和SimpleDateFormat
。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
你可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要类。java.sql.*
在哪里获取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捆绑了java.time类的实现。
- 对于早期的Android(<26),ThreeTenABP项目改编了ThreeTen-Backport(如上所述)。请参阅如何使用ThreeTenABP…。
该ThreeTen-额外项目与其他类扩展java.time。该项目是将来可能向java.time添加内容的试验场。你可能在这里找到一些有用的类,比如Interval,YearWeek,YearQuarter
,和更多。
以上是 Java Instant和LocalDateTime有什么区别? 的全部内容, 来源链接: utcz.com/qa/424378.html