EST 和 America/New_York 时区之间的差异

Posted

技术标签:

【中文标题】EST 和 America/New_York 时区之间的差异【英文标题】:Difference between EST and America/New_York time zones 【发布时间】:2012-04-09 10:54:55 【问题描述】:

谁能告诉我,以下两种说法有什么区别:

TimeZone.getTimeZone("America/New_York")

TimeZone.getTimeZone("EST")

换句话说,为什么 EST 与 America/New_York 不同。同样在我的应用程序中,要获取美国的当前时区,我应该使用 America/New_York 还是 EST。

【问题讨论】:

【参考方案1】:

EST 实际上是纽约时区的一半总是在标准时间 - 它没有夏令时部分。它真的本身并不是一个合适的时区,IMO - 它是更完整时区的“标准”部分。当写一个时区只是一个固定的偏移量并且与特定的地方无关时,我更喜欢使用“Etc/GMT+5”或类似的明显固定的东西。 (我通常不喜欢“东部时间”之类的东西,因为观察“东部时间”的不同地方的 DST 转换可能会有所不同。这有点像将编码称为“扩展 ASCII”......它告诉你 一些信息,但还不够。)

因此,如果您想知道纽约在任何特定时刻的实际当地时间,请使用 America/New_York。

一般来说,远离缩写词。来自the documentation:

为了与 JDK 1.1.x 兼容,还支持一些其他的三字母时区 ID(例如“PST”、“CTT”、“AST”)。但是,不推荐使用它们,因为相同的缩写通常用于多个时区(例如,“CST”可能是美国“中部标准时间”和“中国标准时间”),Java 平台只能识别其中之一他们。

(我个人还建议您远离DateCalendar,尽可能使用Joda Time。不过那是另一回事,真的。)

【讨论】:

我认为暗示它不是正确的时区是一种误导,因为某些时区没有 DST/非 DST 拆分。像 EST 这样的名称是否用于航海时区,还是仅使用偏移量? @JamesAylett:通过。我真的希望不会,因为它们是模棱两可的。 (IIRC,CST 在“中部标准时间”和“澳大利亚中部夏令时间”之间是模棱两可的,这特别无用 - 尽管其中一个已经很多年没有使用了。)很高兴见到你,顺便说一句 :) @JamesAylett:我的意思是这不是一个合适的时区,不是因为它不遵守 DST,而是因为它显然是确实遵守 DST 的东西的一部分 - 否则“标准”部分将是多余的。当然,“GMT”在 1969 年左右也变得棘手,当时它偏离了尚不存在的 UTC :( 我认为唯一能理解日期/时间算术混乱的方法是强制执行严格的约定。 “纽约时间”有时是“EDT”,有时是“EST”的区别意味着你必须坚持纽约时区才能明确。 您可以使用新的Java8日期API:java.time.LocalDate java.time.LocalTime java.time.LocalDateTime java.time.ZonedDateTime【参考方案2】:

EST 是 UTC - 5 小时。 America/New_York 在冬天是 EST,在夏天是 E*D*T,所以现在纽约是 UTC - 4 小时。

【讨论】:

【参考方案3】:

时区,America/New_York 观察two different timezone offsets:

    EST(冬令时):时区偏移为-05:00 小时 EDT(夏令时):时区偏移为-04:00 小时

java.time

java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用,改用modern Date-Time API*

另外,下面引用的是来自home page of Joda-Time的通知:

请注意,从 Java SE 8 开始,用户被要求迁移到 java.time (JSR-310) - JDK 的核心部分,它取代了这个项目。

我应该使用什么日期时间对象来自动调整偏移量?

使用ZonedDateTime,它旨在自动调整时区偏移量。

演示:

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Month;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Main 
    public static void main(String[] args) 
        ZoneId zoneId = ZoneId.of("America/New_York");

        // Custom times
        ZonedDateTime zdtDstOn = ZonedDateTime.of(LocalDate.of(2020, Month.OCTOBER, 22), LocalTime.MIN, zoneId);
        ZonedDateTime zdtDstOff = ZonedDateTime.of(LocalDate.of(2020, Month.NOVEMBER, 22), LocalTime.MIN, zoneId);
        System.out.println(zdtDstOn);
        System.out.println(zdtDstOff);

        // Current time
        ZonedDateTime zdtNow = ZonedDateTime.now(zoneId);
        System.out.println(zdtNow);
    

输出:

2020-10-22T00:00-04:00[America/New_York]
2020-11-22T00:00-05:00[America/New_York]
2021-08-17T12:19:41.854781-04:00[America/New_York]

ONLINE DEMO

避免使用缩写的时区名称

documentation 的以下引用清楚地说明了问题:

三个字母的时区 ID

为了与 JDK 1.1.x 兼容,一些 其他三个字母的时区 ID(例如“PST”、“CTT”、“AST”)是 也支持。但是,它们的使用已被弃用,因为相同 缩写通常用于多个时区(例如,“CST” 可能是美国“中部标准时间”和“中国标准时间”),以及 Java 平台只能识别其中之一。

那么,对于固定时区偏移,我应该使用什么 Date-Time 对象?

OffsetDateTime 用于固定时区偏移量。

演示:

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Month;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;

public class Main 
    public static void main(String[] args) 
        ZoneOffset zoneOffset = ZoneOffset.of("-04:00");

        // A custom time
        OffsetDateTime odt = OffsetDateTime.of(LocalDate.of(2020, Month.OCTOBER, 22), LocalTime.MIN, zoneOffset);
        System.out.println(odt);

        // Current time
        OffsetDateTime odtNow = OffsetDateTime.now(zoneOffset);
        System.out.println(odtNow);
    

输出:

2020-10-22T00:00-04:00
2021-08-17T12:36:09.123599-04:00

ONLINE DEMO

注意:出于任何原因,如果您需要将OffsetDateTimeZonedDateTime的对象转换为java.util.Date的对象,您可以这样做:

Date date = Date.from(odtNow.toInstant());

Date date = Date.from(zdtNow.toInstant());

通过 Trail: Date Time 了解有关 modern Date-Time API* 的更多信息。

查看this answer 和this answer 了解如何将java.time API 与JDBC 结合使用。


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport 将大部分 java.time 功能反向移植到 Java 6 和 7 . 如果您正在为一个 android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。

【讨论】:

以上是关于EST 和 America/New_York 时区之间的差异的主要内容,如果未能解决你的问题,请参考以下文章

如何查找当前时区 EST 或 EDT

是否有可能两个用户以“America/New_York”格式报告相同的时区名称,但一个正在观察 DST 而另一个不是?

转帖linux date 显示指定时区的时间 借助TZ 环境变量 export TZ=Asia/Shanghai 或 America/New_York

将 UTC 时间戳插入 MySQL - 夏令时时区

夏令时更改的 generate_series - 不同的结果取决于服务器时区

时刻时区和 DST