java.util.Date 和 Zoneddatetime 之间有什么区别?

2023-11-27

使用 util.date 并从浏览器提供日期和服务时间,然后保存到数据库并将其取回时,它会根据设置给出不同的日期时间zoneddatetime直接来自服务。

任何帮助,将不胜感激..


tl;dr

java.util.Date 和 Zoneddatetime 之间有什么区别?

  • Date代表 UTC 中的一个时刻,而ZonedDateTime代表特定时区的某个时刻。
  • Date是一个糟糕的类,充满了设计缺陷,永远不应该使用,而ZonedDateTime是一个现代班级java.time您会发现非常有用的软件包。

Java 带有两个截然不同的框架来处理日期时间工作:一组非常尴尬且失败的遗留类,以及一组在java.time包裹。

传统➙现代:

  • java.util.Date was replaced by java.time.Instant
    • 两者都代表 UTC 中的一个时刻。
  • java.util.GregorianCalendar was replaced by java.time.ZonedDateTime
    • 两者都代表特定时区的某个时刻。

table of legacy and modern classes for date-time handling in Java

java.util.Date

The Date类代表 UTC 中的一个时刻。即,日期、时间以及 UTC 上下文。

在内部,它是自 UTC 1970 年第一个时刻的纪元参考日期 1970-01-01T00:00:00Z 以来的毫秒数。

让事情变得复杂:

  • 创建时有一个时区捕获,存储在内部深处,没有 getter 或 setter。因此,在大多数情况下,我们可以忽略这个区域,尽管它确实适用于此类的实现equals.
  • 打电话时toString这个类有very在生成文本来表示该对象的值时,动态应用 JVM 当前时区的行为令人困惑。虽然本意是好的,但这种反特性给试图学习日期时间处理的 Java 程序员带来了难以估量的痛苦。

使困惑?是的,这个类令人困惑,是糟糕的设计决策的一团糟。加上后来的补充java.util.Calendar & GregorianCalendar.

所有这些与最早版本的 Java 捆绑在一起的麻烦的日期时间类现在都完全被java.time类。

尤其,java.util.Date被替换为java.time.Instant。两者都代表 UTC 中的一个时刻,从 1970 UTC 纪元开始计数。但Instant具有更精细的分辨率,纳秒而不是毫秒.

您可以在遗留类之间来回转换Date和现代阶级Instant通过调用添加到旧类中的新方法。通常,您会避免使用Date。但是当与尚未更新的旧代码交互时java.time,您可能需要转换。

java.time.ZonedDateTime

现代阶级ZonedDateTime代表某个地区(时区)人们使用的挂钟时间中看到的时刻。

So Instant and ZonedDateTime相似之处在于它们都代表一个时刻,即该时间线上的特定点。不同之处在于ZonedDateTime了解时区的规则。所以一个ZonedDateTime知道如何解释夏令时 (DST) 等异常现象或政客要求的其他计时变更。

您可以将其视为:

ZonedDateTime = ( Instant + ZoneId )

我们可以通过应用时区(ZoneId) to a Instant object.

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). 

看到这个代码在 IdeOne.com 上实时运行。请注意不同的日期和不同的时间,但同时发生的时刻相同。

instant.toString(): 2019-02-27T19:32:43.366Z

zdt.toString(): 2019-02-28T04:32:43.366+09:00[亚洲/东京]

关键概念:Instant and ZonedDateTime两者都代表同一时刻,时间轴上同一同时点。它们的挂钟时间不同。例如,如果日本的某人打电话给冰岛的某人(他们的时钟始终使用 UTC),并且他们都抬头看着挂在各自墙上的时钟,他们会看到不同的时间,并且可能甚至月历上的不同日期。同一时刻,不同的挂钟时间。

至于遗留类,相当于ZonedDateTime is GregorianCalendar,具体实现java.util.Calendar。确实,老班GregorianCalendar获得新的转换方法to/from ZonedDateTime.

ZonedDateTime zdt = myGregorianCalendar.toZonedDateTime();  // Convert from legacy to modern class.

…and…

GregorianCalendar gc = GregorianCalendar.from( zdt ) ;      // Convert from modern to legacy class.

结论

So a Date相当于一个Instant,都是 UTC 中的时刻。但一个ZonedDateTime与两者的不同之处在于,时区通过应用该地区人们的挂钟时间调整的镜头来调整对时刻的感知。

Tips:

  • 切勿使用Date.当递给一个Date,立即转换为Instant。然后继续您的业务逻辑。
  • 您的大部分工作都在 UTC 中完成。跟踪时刻、调试、记录、交换日期时间值以及保存到数据库通常应在 UTC 中完成。当程序员工作时,学会忘记自己狭隘的时区。将办公桌上的第二个时钟设置为 UTC。

Database

该问题提到了数据库工作。这是一个快速总结。搜索 Stack Overflow 以获取更多详细信息,因为这已经被处理过很多次了。

从 JDBC 4.2 开始,我们可以直接交换java.time与数据库的对象。使用PreparedStatement::setObject and ResultSet::getObject。无需再次接触可怕的事物java.sql.*类如java.sql.Timestamp.

You may能够交换一个Instant但 JDBC 规范并不要求这样做。相反,规范要求OffsetDateTime.

恢复。

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

和存储。

myPreparedStatement.setObject( … , odt ) ;

如果你有一个Instant手中,转换为OffsetDateTime使用常数ZoneOffset.UTC.

OffsetDateTime odt = Instant.atOffset( ZoneOffset.UTC ) ;

要通过某个地区的挂钟时间查看该时刻,请应用ZoneId.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

存储一个ZonedDateTime到数据库,转换为OffsetDateTime。这会剥离时区信息(该地区人民根据政治家的决定对偏移量进行过去、现在和未来更改的历史),留下日期、时间和偏移量-from-UTC(小时-分钟-秒数)。

OffsetDateTime odt = zdt.toOffsetDateTime(); 

大多数数据库为 SQL 标准类型的列存储 UTC 时刻TIMESTAMP WITH TIMESTAMP。当提交您的OffsetDateTime对于数据库,您的 JDBC 驱动程序可能会调整偏移量OffsetDateTime到零小时-分钟-秒(UTC 本身)。但我喜欢明确地这样做。它使调试变得更加容易,并向读者展示了我对存储在 UTC 中的时刻的理解。

OffsetDateTime odt = zdt.toOffsetDateTime().withOffsetSameInstant( ZoneOffset.UTC ) ; 

Table of date-time types in Java (both legacy and modern) and in standard SQL

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java.util.Date 和 Zoneddatetime 之间有什么区别? 的相关文章

随机推荐

  • 在 ConvertBack() 方法中获取 WPF 绑定中 IValueConverter 实现的 Source 值

    我将依赖属性绑定到 WPF 中的 textboxex 该属性是一个字符串 其中一些值由 分隔 例如 1 2 3 4 我需要将各个值绑定到单独的文本框 这对于以下实现来说很好Convert method public object Conve
  • 正则表达式“punct”字符类根据 Ruby 版本匹配不同的字符

    Ruby 的字符类标点符号 i e punct p Punct or p P 似乎根据我使用的 Ruby 版本匹配不同的字符 这是一个小例子 很抱歉弄乱了 SO 的语法荧光笔 punct rb chars lt lt EOD split l
  • 嵌套和重复的 angularjs 指令中链接函数的调用顺序

    我对 Javascript 编程相当陌生 而且只接触过 AngularJS 为了评估它 我决定编写一个简单的笔记应用程序 该模型非常简单 是一个笔记列表 其中每个笔记都有一个标签 一个文本和一个标签列表 然而 我在嵌套指令的隔离范围之间传递
  • 在 Ruby 和 PHP 之间共享会话

    是否可以在子域上的 PHP 应用程序和其他子域上的 Ruby 应用程序之间共享会话 我真的不知道该从这里把它带到哪里 我知道我可以手动将域设置为根域 以便 cookie 对所有子域都有效 但是我如何从会话中获取 设置内容 以便在子域之间共享
  • Django - 捕获异常

    看这段代码 try do something except raise Exception XYZ has gone wrong 即使DEBUG True 我不想要这个raise Exception给那个黄页 但确实如此 我想通过将用户重定
  • 如何控制面板内文本框的焦点顺序?

    我有一个带有许多文本框的表单 我需要一个组内的一些文本框 以及另一组内的其他文本框 按组划分 我只需要一种方法使这些文本框看起来彼此属于彼此 我制作了两个面板并向其中添加了文本框 然后 我在这些面板周围放置了边框 However my pr
  • WSDL、Enums 和 C#:仍然很模糊

    我试图在网上查找这一点 但所有 WSDL 示例似乎都没有真正解释我是否应该将事物标记为 WSDL 中的基本类型字符串或 int 基本上 我正在尝试制作 WSDL 以便可以表示枚举 我心里已经有一个 C 枚举 我想将它匹配到 public e
  • 在 Selenium 中设置隐藏输入值?

    我们的表单上隐藏了输入字段 我们需要 Selenium 来设置这些字段的值 通过 Selenium IDE 设置隐藏输入值的最佳方法是什么 我能找到的最简单的方法 命令 运行脚本 Value javascript this browserb
  • Xcode Bitcode,包括符号设置对 dSYM 生成的影响

    由于我使用 Crashlytics 来处理崩溃 所以我总是取消选中 包含应用程序符号 以便您的应用程序接收来自 Apple 的符号化崩溃日志 并保留 包含位码 在将我的应用程序提交到 iTunes Connect 之前进行了检查 Apple
  • 实体框架时间戳生成数据库问题

    我在使用 EF 4 0 时遇到问题 我用 时间戳 列创建实体 之后 我尝试生成数据库 在 SQL 脚本中 列看起来像 binary 8 而不是时间戳 怎么解决呢 问题已解决 EF 4 无法从 edmx 设计器生成时间戳列 解决方案很简单 将
  • 无论顺序如何,两列的唯一约束

    我有以下表定义 CREATE TABLE Car CarID int NOT NULL PRIMARY KEY IDENTITY 1 1 FirstColorID int FOREIGN KEY REFERENCES Colors Colo
  • 如何隐藏 django modelform 中的字段?

    例如 class TestModel models Model ref1 models ForeignKey RefModel text1 models TextField class TestModelForm ModelForm cla
  • 在代码后面附加行为

    我有以下 Xaml 用于在属性网格内用作编辑器的用户控件 问题是 从后面的代码附加行为的 C 会是什么样子
  • 在 Linux 中模拟硬盘

    作为研究项目的一部分 我开发了一个基于 FUSE 的文件系统 现在必须研究硬盘驱动器接收到的实际读 写请求 为了做到这一点 我正在考虑在 Linux 中创建虚拟硬盘驱动器的选项 它将拦截文件系统生成的请求并记录它们 互联网上是否有任何资源可
  • 订阅多个 Observables(例如 Promises 中的链接 then())

    我的 Angular 2 应用程序有 2 种方法 GetCategories and GetCartItems 在服务中 这两个方法都返回Observables 为了从我的组件中依次调用这两个方法 我编写了以下代码 ngOnInit thi
  • 如何在 IntelliJ IDEA 中添加链接到外部工具的按钮

    我创建了一些批处理工作并将其作为ExternalTool 集成到IntelliJ IDEA 中 如此处所述 配置Intellij IDEA运行批处理文件 但是 如何向工具栏添加按钮来激活定义为外部工具的批处理 这很容易 Assuming t
  • 现有数据库中的 Entity Framework Core 2.0 支架视图

    是否可以从 Entity Framework Core 2 0 中的现有数据库构建视图 类似于下面的命令 Scaffold DbContext Server xxx Database xxx User Id xxx Password xxx
  • 是否可以用BLE广播模式发送数据?

    我想请问您是否可以以广播模式从 BLE 设备 例如带有蓝牙适配器的 Raspberry Pi Onion 或 Arduino 向另一个设备 例如手机或另一个 Raspberry Pi 发送数据 字符串 这将在屏幕上显示数据 老实说 没有必要
  • delphi中打印到“Microsoft print to PDF”时如何设置文件名

    我试图在打印为 PDF 时设置文件名 设置 Printers pas Printer Title 适用于大多数 PDF 打印引擎 Adobe CutePDF 的默认 PDF 文件名 但不适用于 Microsoft 打印到 PDF 或 Mic
  • java.util.Date 和 Zoneddatetime 之间有什么区别?

    使用 util date 并从浏览器提供日期和服务时间 然后保存到数据库并将其取回时 它会根据设置给出不同的日期时间zoneddatetime直接来自服务 任何帮助 将不胜感激 tl dr java util Date 和 Zoneddat