Java TimeZone 让人头皮发麻

标签 java timezone

我想以夏令时格式保存一些用户时区。
我的目标是在代码执行时获得正确的 GMT 偏移量。
为了找出我的最佳选择,我写了以下内容:

ArrayList<String> list = new ArrayList<String>();
list.add( "EST");
list.add( "EDT");
list.add( "America/New_York");
long now = System.currentTimeMillis();
for( String tzID: list) {
    TimeZone tz = TimeZone.getTimeZone( tzID);
    System.out.println( tzID + " now=" + tz.getOffset( now) / 3600000 + " / +182=" + tz.getOffset( now + ( 182 * 86400000)) / 3600000);
}

简而言之,给我现在和182天后的偏移量
9月3日执行,输出为

EST now=-5 / +182=-5
EDT now=0 / +182=0
America/New_York now=-4 / +182=-4

出于几个原因,这是出乎意料的
1) 为什么 America/New_York 不给 -4/-5 ?它不应该对日期敏感吗?
2) 为什么 EDT == UTC?

最佳答案

java.time

问题和 accepted answer使用 java.util 日期时间 API,这在 2012 年是正确的做法。2014 年 3 月,modern Date-Time API作为 Java 8 标准库 的一部分发布,它取代了遗留的日期时间 API,从那时起强烈建议切换到现代日期时间 java.time时间 API。

使用java.time的解决方案

您可以使用 ZonedDateTime它会自动调整给定 ZoneId 的时区偏移量。

演示:

import java.time.ZoneId;
import java.time.ZonedDateTime;

class Main {
    public static void main(String[] args) {
        ZoneId zone = ZoneId.of("America/New_York");
        ZonedDateTime now = ZonedDateTime.now(zone);
        ZonedDateTime after182Days = now.plusDays(182);
        System.out.println(zone + " now=" + now.getOffset() + " / +182=" + after182Days.getOffset());
    }
}

截至目前的输出:

America/New_York now=-05:00 / +182=-04:00

ONLINE DEMO

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

不要使用三字母时区 ID:来自 Java 7 Timezone 的注释 documentation :

Three-letter time zone IDs

For compatibility with JDK 1.1.x, some other three-letter time zone IDs (such as "PST", "CTT", "AST") are also supported. However, their use is deprecated because the same abbreviation is often used for multiple time zones (for example, "CST" could be U.S. "Central Standard Time" and "China Standard Time"), and the Java platform can then only recognize one of them.

关于Java TimeZone 让人头皮发麻,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12248766/

相关文章:

java - Java 货币 API 中缺少一些货币符号

java - Tomcat 7 : Connection reset by peer or Software caused connection abort

c - 如何以特定格式打印time_t?

java - 从 Joda DateTime 对象中删除时区

java - 如何将字符串拆分为包含值列表的映射?

java - 如何根据用户输入在哈希表中添加某些值?

java - 如何修复Java中的 'Bound mismatch'

c - 获取 C 中时区的夏令时转换日期

linux - 如何使用 bash 提取特定日期和时间的 UTC 偏移量?

go - 你如何将时间偏移量转换为 Go 中的位置/时区