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

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

TimeZone.getTimeZone("America/New_York")

TimeZone.getTimeZone("EST")

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

【问题讨论】:

    标签: java calendar timezone


    【解决方案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

      1. EST(冬令时):时区偏移为-05:00 小时
      2. 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 answerthis 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 desugaringHow to use ThreeTenABP in Android Project

      【讨论】:

        猜你喜欢
        • 2015-01-26
        • 1970-01-01
        • 2017-04-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多