如何在考虑夏令时的情况下获得实时时区偏移量?

How to get real time zone offset taking into account daylight saving?

我现在在+3时区。
现在 UTC 时间是 16:30 而在我这里是 19:30

我发现时区 America/Los_Angeles

存在问题

理论上是 -8 (rawOffset) 我得到了意想不到的时间。 我预计如果在我的地方 20:00,那么在 ths timezoe 时间应该少 11 小时(8+3),但在现实生活中,由于夏令时,它比我的地方少 10 小时。

如果我的代码中有 America/Los_Angeles zoneId,我如何获得 -7 偏移量?

TimeZone.getTimeZone("America/Los_Angeles").getRawOffset()/(3600*1000)

returns -8 但现在与 UTC 相差 7 小时

如果您需要知道针对 DST 正确调整的时区偏移量,请不要使用 getRawOffset(),因为那是没有 DST 的具体偏移量。正如文档所说:

Returns the amount of time in milliseconds to add to UTC to get standard time in this time zone. Because this value is not affected by daylight saving time, it is called raw offset.

要知道 DST 是否有效,系统需要知道 日期,而不仅仅是 时间。如果您知道完整的 date/time,那么您可以通过调用例如getOffset(long date).

要立即获取生效的时区偏移量,请调用:

int offset = TimeZone.getTimeZone("America/Los_Angeles")
                     .getOffset(System.currentTimeMillis());
int minutes = offset / 60000;

加上Java8次API,等价代码为:

ZoneOffset offset = ZoneId.of("America/Los_Angeles")
                          .getRules().getOffset(Instant.now());
int minutes = offset.getTotalSeconds() / 60;

java.time

是正确的。这个答案提供了使用现代日期时间 API.

的解决方案

java.util 日期时间 API 及其格式 API、SimpleDateFormat 已过时且容易出错。建议完全停止使用它们并切换到 modern Date-Time API*,于 2014 年 3 月作为 Java SE 8 标准库的一部分发布。

解决方案使用 java.time,现代日期时间 API:

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

public class Main {
    public static void main(String[] args) {
        ZoneOffset offset = ZonedDateTime.now(ZoneId.of("America/Los_Angeles")).getOffset();
        System.out.println(offset);
    }
}

输出:

-07:00

ONLINE DEMO

Trail: Date Time.

了解有关现代日期时间 API 的更多信息

* 无论出于何种原因,如果您必须坚持Java 6 或Java 7,您可以使用ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and