【发布时间】:2012-04-09 10:54:55
【问题描述】:
谁能告诉我,以下两种说法有什么区别:
TimeZone.getTimeZone("America/New_York")
和
TimeZone.getTimeZone("EST")
换句话说,为什么 EST 与 America/New_York 不同。同样在我的应用程序中,要获取美国的当前时区,我应该使用 America/New_York 还是 EST。
【问题讨论】:
谁能告诉我,以下两种说法有什么区别:
TimeZone.getTimeZone("America/New_York")
和
TimeZone.getTimeZone("EST")
换句话说,为什么 EST 与 America/New_York 不同。同样在我的应用程序中,要获取美国的当前时区,我应该使用 America/New_York 还是 EST。
【问题讨论】:
EST 实际上是纽约时区的一半。 总是在标准时间 - 它没有夏令时部分。它真的本身并不是一个合适的时区,IMO - 它是更完整时区的“标准”部分。当写一个时区只是一个固定的偏移量并且与特定的地方无关时,我更喜欢使用“Etc/GMT+5”或类似的明显固定的东西。 (我通常不喜欢“东部时间”之类的东西,因为观察“东部时间”的不同地方的 DST 转换可能会有所不同。这有点像将编码称为“扩展 ASCII”......它告诉你 一些信息,但还不够。)
因此,如果您想知道纽约在任何特定时刻的实际当地时间,请使用 America/New_York。
一般来说,远离缩写词。来自the documentation:
为了与 JDK 1.1.x 兼容,还支持一些其他的三字母时区 ID(例如“PST”、“CTT”、“AST”)。但是,不推荐使用它们,因为相同的缩写通常用于多个时区(例如,“CST”可能是美国“中部标准时间”和“中国标准时间”),Java 平台只能识别其中之一他们。
(我个人还建议您远离Date 和Calendar,尽可能使用Joda Time。不过那是另一回事,真的。)
【讨论】:
EST 是 UTC - 5 小时。 America/New_York 在冬天是 EST,在夏天是 E*D*T,所以现在纽约是 UTC - 4 小时。
【讨论】:
时区,America/New_York 观察two different timezone offsets:
-05:00 小时-04:00 小时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]
documentation 的以下引用清楚地说明了问题:
三个字母的时区 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);
}
}
输出:
2020-10-22T00:00-04:00
2021-08-17T12:36:09.123599-04:00
注意:出于任何原因,如果您需要将OffsetDateTime或ZonedDateTime的对象转换为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。
【讨论】: