如何在 JAVA 中获取时间戳的偏移量



我有两个时间戳14983290000001485282600000Europe/Brussels-

其中第一个存在于夏令时,第二个存在于非夏令时

如何从UTC获得正或负(差)的偏移量?即 1 小时或 2 小时,基于DST

使用java.time-API 非常简单:

public static ZoneOffset getZoneOffset(long epochMillis, String zoneName) {
Instant instant = Instant.ofEpochMilli(epochMillis);
ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of(zoneName));
return zonedDateTime.getOffset();
}
public static void main(String[] args) {
System.out.println(getZoneOffset(1498329000000l, "Europe/Brussels")); // +02:00
System.out.println(getZoneOffset(1485282600000l, "Europe/Brussels")); // +01:00
}

另请查看类ZoneRules,其中具有处理时区和夏令时 (DST) 的有用方法:

  • boolean isDaylightSavings(Instant instant)

    检查指定的时刻是否为夏令时。

    这将检查指定时刻的标准偏移和实际偏移是否相同。如果不是,则假定夏令时正在运行。

    此默认实现比较实际偏移量和标准偏移量。

    参数:
    instant- 查找偏移量的时刻,不是空,但如果规则对所有时刻都有单个偏移量,则可以忽略空

    返回:
    标准偏移量,不为空

  • Duration getDaylightSavings(Instant instant)

    获取此区域中指定时刻使用的夏令时量。

    这提供了对有关夏令时量如何随时间变化的历史信息的访问。这是标准偏移量和实际偏移量之间的差值。通常,冬季的量为零,夏季为一小时。时区是基于秒的,因此持续时间的纳秒部分将为零。

    此默认实现根据实际偏移量和标准偏移量计算持续时间。

    参数:
    instant- 查找夏令时的时刻,不是空,但如果规则对所有时刻只有一个偏移量,则可以忽略空

    返回:
    标准偏移量与实际偏移量之差,不为空

  • ZoneOffsetTransition nextTransition(Instant instant)

    获取指定时刻之后的下一个转换。

    这将返回指定时刻之后下一个转换的详细信息。例如,如果 instant 表示应用"夏季"夏令时的点,则该方法将返回到下一个"冬季"时间的转换。

    参数:
    instant- 在之后获得下一个转换的时刻,不是 null,但如果规则对所有时刻都有单个偏移量,则可以忽略 null

    返回:
    指定时刻之后的下一个转换,如果这是在最后一个转换之后,则为 null

要获取您可以使用的ZoneRules

ZoneRules rules = ZoneId.of("Europe/Brussels").getRules();

您可以使用以下代码片段获取特定时间戳的布鲁塞尔时区中与 UTC 的时区偏移量(以秒为单位):

ZoneId zone = ZoneId.of("Europe/Brussels");
Instant instant = Instant.ofEpochMilli(timestamp);
OffsetDateTime dateTime = OffsetDateTime.ofInstant(instant, zone);
int offsetInSeconds = dateTime.get(ChronoField.OFFSET_SECONDS);

如果你想在几个小时内得到它,你需要做更多的工作,有些国家的时区偏移量不是整小时。

public static void main(String[] args) {
System.out.println(utcOffsetInHoursInBrussels(1498329000000L));
System.out.println(utcOffsetInHoursInBrussels(1485282600000L));
}
public static int utcOffsetInHoursInBrussels(long timestamp) {
ZoneId zone = ZoneId.of("Europe/Brussels");
Instant instant = Instant.ofEpochMilli(timestamp);
OffsetDateTime dateTime = OffsetDateTime.ofInstant(instant, zone);
int offsetInSeconds = dateTime.get(ChronoField.OFFSET_SECONDS);
if (offsetInSeconds % 3600 == 0) {
return offsetInSeconds / 3600;
} else {
throw new IllegalArgumentException("Offset is not a whole hour");
}
}

输出:

2
1

您不一定需要像其他答案那样经历ZonedDateTimeOffsetDateTime

ZoneOffset offset = ZoneId.of("Europe/Brussels")
.getRules()
.getOffset(Instant.ofEpochMilli(1_498_329_000_000L));

你喜欢哪个可能是一个品味问题。

Oles 答案是最好的,因为查询给定时刻的时区偏移量的简单问题根本不需要使用像ZonedDateTime这样的复杂类型。

Java-8或更高版本(另见Oles回答):

ZoneRules rules = ZoneId.of("Europe/Brussels").getRules();
ZoneOffset offsetDST = 
rules.getOffset(Instant.ofEpochMilli(1498329000000L));
System.out.println(offsetDST); // +02:00
ZoneOffset offsetSTD =
rules.getOffset(Instant.ofEpochMilli(1485282600000L));
System.out.println(offsetSTD); // +01:00

旧API(令人惊讶的是,即使是最简单的方法):

TimeZone tz = TimeZone.getTimeZone("Europe/Brussels");
System.out.println(tz.getOffset(1498329000000L)); // 7200000 ms
System.out.println(tz.getOffset(1485282600000L)); // 3600000 ms

相关内容

  • 没有找到相关文章

最新更新