EST与America/New_York时区的差异

Gau*_*rav 48 java timezone calendar

有人可以告诉我,以下两个陈述之间的区别是什么:

TimeZone.getTimeZone("America/New_York")
Run Code Online (Sandbox Code Playgroud)

TimeZone.getTimeZone("EST")
Run Code Online (Sandbox Code Playgroud)

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

Aff*_*ffe 118

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

  • 这需要方式,更多的赞成. (10认同)

Jon*_*eet 63

EST实际上是纽约时区的一半.它总是在标准时间 - 它没有夏令时部分.这不是真的在自己的权利的正确的时区,IMO -这是一个更全面的时区的"标准"的一部分.当写一个时区只是一个固定的偏移并且与某个地方无关时,我宁愿使用"Etc/GMT + 5"或类似的明显固定的东西.(我一般不喜欢"东部时间"之类的东西,因为观察"东部时间"的不同地方的DST过渡可能会有所不同.这有点像调用编码"扩展ASCII"......它告诉你一些信息,但还不够.)

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

一般来说,远离缩写.从文档:

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

(就我个人而言,我也建议你远离,Date并且尽可能Calendar使用Joda Time.但这确实是另一回事.)

  • @JamesAylett:我建议它不是一个合适的时区,不是因为它没有观察DST,而是因为它显然是**观察DST的一部分 - 否则"标准"部分将是多余的.当然,"GMT"在1969年左右变得棘手,当它偏离了尚未存在的UTC时:( (2认同)
  • 我认为,对日期/时间算术的混乱有任何意义的唯一方法是强制执行严格的约定."纽约时报"有时候是"EDT",有时候是"EST",这一区别意味着你必须坚持纽约时区才能明确无误. (2认同)

Arv*_*ash 5

时区,America/New_York观察两个不同的时区偏移

  1. EST(冬季时间):时区偏移-05:00数小时
  2. EDT(夏令时):时区偏移-04:00数小时

在此输入图像描述

java.time

日期java.util时间 API 及其格式化 APISimpleDateFormat已经过时且容易出错。建议完全停止使用它们并切换到现代 Date-Time API *

另外,下面引用的是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);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

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]
Run Code Online (Sandbox Code Playgroud)

ONLINE DEMO

避免使用缩写的时区名称

以下文档中的引用清楚地说明了问题:

三字母时区 ID

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

那么,我应该使用什么日期时间对象来实现固定时区偏移?

用于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);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

2020-10-22T00:00-04:00
2021-08-17T12:36:09.123599-04:00
Run Code Online (Sandbox Code Playgroud)

ONLINE DEMO

注意:无论出于何种原因,如果您需要将 的对象转换为 的对象OffsetDateTimeZonedDateTime将 的对象转换为 的对象java.util.Date,可以按如下方式进行:

Date date = Date.from(odtNow.toInstant());
Run Code Online (Sandbox Code Playgroud)

或者

Date date = Date.from(zdtNow.toInstant());
Run Code Online (Sandbox Code Playgroud)

Trail: Date Time了解有关现代日期时间 API *的更多信息。

检查此答案此答案以了解如何将java.timeAPI 与 JDBC 结合使用。


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,则可以使用ThreeTen-Backport,它将大多数java.time功能向后移植到 Java 6 和 7。如果您正在处理 Android 项目和 Android API level 仍然不符合 Java-8,请检查通过脱糖可用的 Java 8+ API以及如何在 Android 项目中使用 ThreeTenABP