如何从JAVA中的时间戳偏移

时间:2018-01-25 07:56:34

标签: java timezone dst

我在1498329000000中有两个时间戳1485282600000Europe/Brussels -

其中第一个存在于Day Light中,第二个存在非白天节约

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

4 个答案:

答案 0 :(得分:1)

使用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 - 如果规则对所有时刻都有一个偏移量,则可以忽略找到偏移信息的时刻,而不是null,但是可以忽略null

         

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

  • Duration getDaylightSavings(Instant instant)

      

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

         

    这样可以访问有关夏令时数量随时间变化的历史信息。这是标准偏移和实际偏移之间的差异。通常,冬季为零,夏季为一小时。时区是第二个,因此持续时间的纳秒部分将为零。

         

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

         

    <强>参数:
      instant - 如果规则对所有时刻都有一个偏移量,则可以忽略找到夏令时的时间,而不是null,但是null可以忽略

         

    <强>返回:
      标准偏差和实际偏差之间的差异,不为空

  • ZoneOffsetTransition nextTransition(Instant instant)

      

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

         

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

         

    <强>参数:
      instant - 如果规则对所有时刻都有一个偏移量,那么获取下一次转换的时刻,不是null,但可以忽略null

         

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

获取您可以使用的ZoneRules

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

答案 1 :(得分:1)

使用此代码段,您可以在特定时间戳的布鲁塞尔时区获得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

答案 2 :(得分:1)

与其他答案一样,您不一定要经过ZonedDateTimeOffsetDateTime

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

您更喜欢的可能是品味问题。

答案 3 :(得分:1)

Oles答案是最好的,因为查询给定时刻的时区偏移量的简单问题不需要使用复杂类型,例如var box = document.querySelectorAll('.box'); function scrollTrigger() { box.forEach(function(item){ var boxPosition = item.getBoundingClientRect().top; var boxPositionPercent = (boxPosition / window.innerHeight) * 100; if (boxPositionPercent <= 70) { item.classList.add('scroll-active') } else { item.classList.remove('scroll-active') } }); } window.addEventListener("scroll", scrollTrigger);

Java-8或更高版本(另请参阅Oles答案):

ZonedDateTime

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

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