Viv*_*mar 0 java datetime java.util.date zoneddatetime
在使用util.date并从浏览器给日期提供服务时间,然后保存到db并取回它时,与直接从服务中设置zoneddatetime相比,它提供了不同的日期时间。
任何帮助,将不胜感激..
java.util.Date和Zoneddatetime有什么区别?
Date代表UTC时刻,而ZonedDateTime代表特定时区的时刻。Date是一个可怕的类,充满设计缺陷,永远不要使用,而它ZonedDateTime是java.time包中的一个现代类,您会发现它非常有用。Java带有两个非常不同的用于处理日期时间工作的框架:一组尴尬且失败的遗留类集,以及在java.time包中找到的一组业界领先的现代类。
旧版?现代:
java.util.Date 被替换为 java.time.Instant
java.util.GregorianCalendar 被替换为 java.time.ZonedDateTime
java.util.Date该Date课程代表UTC的时刻。即,日期,一天中的时间以及UTC的上下文。
在内部,它是自UTC 1970-01-01T00:00:00Z的1970年第一时刻的纪元参考日期以来的毫秒数。
使事情复杂化:
equals。toString此类时,在生成表示该对象值的文本时动态地应用JVM的当前时区具有非常令人困惑的行为。尽管有很好的意图,但这种反功能在试图学习日期时间处理的Java程序员中造成了难以估量的痛苦。困惑?是的,这堂课令人迷惑,糟糕的设计决策混乱不堪。后来又添加了java.util.Calendar&GregorianCalendar。
与最早的Java版本捆绑在一起的所有这些麻烦的日期时间类现在都完全被java.time类所取代。
特别java.util.Date是被代替java.time.Instant。从1970年UTC时代开始,两者都代表UTC的时刻。但是,Instant它具有更好的分辨率,即纳秒而不是毫秒。
您可以通过调用添加到旧类中的新方法来在旧类Date和现代类之间来回转换Instant。通常,您将避免使用Date。但是,当与尚未更新为java.time的旧代码接口时,可能需要进行转换。
java.time.ZonedDateTime现代班级ZonedDateTime代表了某个地区(时区)人们使用的挂钟时间中的时刻。
因此Instant,ZonedDateTime两者相似之处在于它们都代表一个时刻,即该时间轴上的特定点。区别在于ZonedDateTime知道时区的规则。因此,一个人ZonedDateTime知道如何解决诸如夏令时(DST)或政客要求的其他时间变更等异常情况。
您可以将其视为:
ZonedDateTime=(Instant+ZoneId)
通过将时区(ZoneId)应用于Instant对象,我们可以轻松地从UTC调整到某个时区。
Instant instant = Instant.now() ; // Capture the current moment as seen in UTC.
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Apply a time zone to see the same moment through the wall-clock time in use by the people of a particular region (a time zone).
Run Code Online (Sandbox Code Playgroud)
参见IdeOne.com实时运行此代码。注意不同的日期和不同的时间,但同时具有相同的时刻。
Instant.toString():2019-02-27T19:32:43.366Z
zdt.toString():2019-02-28T04:32:43.366 + 09:00 [亚洲/东京]
关键概念:Instant和ZonedDateTime都表示同一时刻,在时间轴上的相同点同时进行。它们的挂钟时间不同。例如,如果日本某人给冰岛某人打电话(一直使用UTC作为时钟),并且他们俩都抬头看着挂在各自墙上的时钟,他们会看到不同的时间,并且可能甚至每月日历上的另一个日期。相同的时刻,不同的时钟时间。
至于传统类,等效的ZonedDateTime是GregorianCalendar,具体实现的java.util.Calendar。事实上,老班GregorianCalendar获得了转换的新方法来 / 从 ZonedDateTime。
ZonedDateTime zdt = myGregorianCalendar.toZonedDateTime(); // Convert from legacy to modern class.
Run Code Online (Sandbox Code Playgroud)
…和…
GregorianCalendar gc = GregorianCalendar.from( zdt ) ; // Convert from modern to legacy class.
Run Code Online (Sandbox Code Playgroud)
因此,a Date等于a Instant,两者都是UTC中的时刻。但是ZonedDateTime两者的不同之处在于,时区通过应用区域人民的挂钟时间调整镜头来调整了对瞬间的感知。
提示:
Date。交到时Date,立即转换为Instant。然后继续您的业务逻辑。该课题提到数据库工作。这是一个简短的摘要。搜索堆栈溢出以获取更多详细信息,因为已经处理了很多次。
从JDBC 4.2开始,我们可以直接与数据库交换java.time对象。使用PreparedStatement::setObject和ResultSet::getObject。无需再碰到java.sql.*诸如的可怕类java.sql.Timestamp。
您也许可以交换,Instant但JDBC规范不要求这样做。规范反而要求OffsetDateTime。
恢复。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Run Code Online (Sandbox Code Playgroud)
和存储。
myPreparedStatement.setObject( … , odt ) ;
Run Code Online (Sandbox Code Playgroud)
如果您Instant手头上有,请转换为OffsetDateTime使用常量ZoneOffset.UTC。
OffsetDateTime odt = Instant.atOffset( ZoneOffset.UTC ) ;
Run Code Online (Sandbox Code Playgroud)
要通过某个区域的挂钟时间查看该时刻,请应用ZoneId。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
Run Code Online (Sandbox Code Playgroud)
要将a存储ZonedDateTime到数据库,请转换为OffsetDateTime。这会剥夺时区信息(该地区人民根据政客的决定对过去,现在和将来进行的更改的历史记录),留下日期,日期和偏移量-from-UTC(小时-分钟-秒的数量)。
OffsetDateTime odt = zdt.toOffsetDateTime();
Run Code Online (Sandbox Code Playgroud)
大多数数据库在UTC中为SQL标准类型的列存储时间TIMESTAMP WITH TIMESTAMP。将您OffsetDateTime的数据提交到数据库时,您的JDBC驱动程序可能会将偏移量调整OffsetDateTime为零小时-分钟-秒(以UTC本身为准)。但是我喜欢明确地这样做。它使调试更加容易,并且向读者展示了我对存储在UTC中的那一刻的理解。
OffsetDateTime odt = zdt.toOffsetDateTime().withOffsetSameInstant( ZoneOffset.UTC ) ;
Run Code Online (Sandbox Code Playgroud)
java.util.Date是一个几乎已弃用的类,它提供了毫秒值的包装器。它不提供任何有关时区的信息,没有任何有用的方法,您应该始终避免使用它。
ZonedDateTime是新日期 API 中的一个类JDK8,它提供 ISO-8601 日历系统中的日期时间和时区。你应该检查一下
| 归档时间: |
|
| 查看次数: |
832 次 |
| 最近记录: |