分区日期时间未给出 est 时间 [duplicate]

Zoned date time is not giving est time [duplicate]

提问人:HARI KRISHNA 提问时间:10/16/2023 最后编辑:AnonymousHARI KRISHNA 更新时间:10/18/2023 访问量:102

问:

我想将日期和时间转换为 EST 区域,并且由于某种原因我尝试使用日历,即使它正确设置了时区,它也无法转换时间。我正在尝试zonedDateTime,它的工作方式也一样。

ZoneId estZone = ZoneId.of("America/New_York");
ZonedDateTime estTime =       ZonedDateTime.now(estZone);
 System.out.println(Date.from(estTime.toInstant()));

我的输出是: 10 月 16 日星期一 16:17:13 IST 2023。

但是我将我的区域ID设置为美国。和 estTime.toLocalDateTime 在 EST 中给出了更正的时间,但我无法将其转换为 Date 返回类型,因为它会引发 Instant 类错误

我需要对此进行一些解释

java spring timezone zoneddatetime

评论

5赞 Jon Skeet 10/16/2023
首先,美国/New_York目前没有观测美国东部标准时间——它正在观测美国东部时间。但更重要的是,你的问题表明你相信一个值“有”一个时区。事实并非如此。查看 codeblog.jonskeet.uk/2017/04/23/all-about-java-util-datejava.util.Date
2赞 Jon Skeet 10/16/2023
“因此,我们无法将 ZonedDateTime 转换为 Date” - 您绝对可以,但只能表示时间上的一个瞬间,精度为毫秒。如果你期望它做得更多,你会失望的。(从根本上说,我会尽量避免使用日期。Date
3赞 Jon Skeet 10/16/2023
不,因为我们不知道你想做什么。如果你试图获得“一个代表特定时区的时刻的日期”,那么这是不可能的。(你说“它正在抛出即时类错误”而没有提供更多细节,这无济于事......
1赞 Anonymous 10/16/2023
如果可能的话,你能帮我一个适合我的场景的代码片段吗只要像乔恩已经建议的那样完全省略任何用途。那个班级设计得很差,早就过时了,永远无法做你想做的事。永远不可能有时区。这是它的方法,当它打印一个谎言时。阅读@JonSkeet的链接。DateDatetoString
2赞 Anonymous 10/16/2023
使用 JDBC?SQL中的哪种数据类型?你不需要为此而烦恼。从 JDBC 4.2 开始,您可以通过 JDBC 直接存储 java.time 类型。至少从 Hibernate 5 开始,Hibernate 可以做同样的事情。我想使用日期对不起,我读了这篇文章,因为我想麻烦Date

答:

2赞 Basil Bourque 10/16/2023 #1

使用实时时区

ZoneId estZone = ZoneId.of("America/New_York");

美国东部标准时间不是一个真实的时区。此类伪区域仅用于向用户演示,而不用于逻辑或数据。伪区域不是标准化的,甚至不是唯一的(!

通常与“东部”时间相关的时区目前正在遵守夏令时 (DST)。因此,伪区域标签将是 而不是 .EDTEST

所以,让我们使用它:

ZoneId zoneNewYork = ZoneId.of( "America/New_York" ) ;

使用 java.time

ZonedDateTime zdtNewYork = ZonedDateTime.now( zoneNewYork );

好。你捕捉到了纽约地区人们使用的挂钟时间和日历所看到的当前时刻。

若要生成标准 ISO 8601 格式的文本,并明智地扩展以在括号中附加时区名称,只需调用 toString

String output = zdtNewYork.toString() ;

要生成本地化文本,请使用 。DateTimeFormatter.ofLocalizedDateTime

避免使用旧版日期时间类

Date.from(estTime.toInstant())

坏。你不必要地卷入了有严重缺陷的遗留类.java.util.Date

避免使用旧版日期时间类。仅使用 java.time 类。

至于你遇到的行为,方法在于我们。在生成文本时,该方法会动态应用 JVM 的当前默认时区。避免此类的众多原因之一。Date#toString

JDBC的

您评论了将这一刻存储在数据库中。

表列的类型应类似于 SQL 标准类型。TIMESTAMP WITH TIME ZONE

JDBC 标准将 Java 类 OffsetDateTime 映射到该类型。

OffsetDateTime odt = zdtNewYork.toOffsetDateTime() ;
myPreparedStatement.setObject( … , odt ) ;

检索。

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZonedDateTime zdtNewYork = odt.atZoneSameInstant( zoneNewYork ) ;

搜索以了解更多信息。这在 Stack Overflow 上已经多次介绍过。

使用旧类

您评论道:

我们需要将日期用于旧用途,因此我需要一个可以表示当前时间的日期对象,如 EST 中的

java.util.Date 类表示与 UTC 时间子午线偏移量为 0 小时-分钟-秒的时刻。因此,要求一个对象来表示在时区中看到的时刻是不可能的。java.util.DateAmerica/New_York

替换是 java.time.Instant。两者都表示在 UTC 中看到的时刻(偏移量为零)。您可以通过添加到旧类的新方法来回转换。java.util.Date

Instant instant = Instant.now() ;
java.util.Date d = java.util.Date.from( instant ) ;

然后朝另一个方向走:

Instant instant = d.toInstant() ;

转换时,请注意可能的数据丢失。传统类的分辨率为毫秒,而现代类的分辨率要精细得多,为纳秒

java.util.Calendar 类,或者更确切地说是它的子类 java.util.GregorianCalendar,可以表示在特定时区看到的时刻。如果需要,您可以在其替换类 java.time.ZonedDateTime 之间来回转换。

尽可能避免这些旧类。它们是一团糟的糟糕设计和古怪的功能。

如果您有需要与尚未更新到 java.time 的旧代码进行互操作的特定情况,请在 Stack Overflow 上发布包含这些特定详细信息的问题。