0

我有一个对应于 2021-07-05T18:00:00.000-04:00(东部夏令时间)的日历对象。然而 Calendar.get(DST_OFFSET) 和 Calendar.getTimeZone().getDSTSavings() 都给出 0。它应该是 1 小时。我错过了什么或我出了什么问题?我使用的所有其他方法都返回预期值。

我正在使用 setTimeInMillis() 和 TimeZone 使用偏移量创建日历。这是它不起作用的原因吗?显示的民间时代总是正确的......

尽管我想使用新的 Java 时间,但我正在使用 Java for Android。最后我只检查了最新版本的 Android 是否支持新的 Java 时间。他们最终可能会增加对旧版本的支持。

4

2 回答 2

3

一个问题是输入定义了与 UTC 的偏移量,但不是具有特定规则的实时时区(例如是否完全应用 DST,如果是,何时应用 DST)。

Calendar显然无法处理这些规则,该类(可能还有整个 API)并不是设计的。

java.time这就是在 Java 8 中引入的原因之一。

java.time这是在像您这样的情况下使用的一些示例:

public static void main(String[] args) {
    // example String in ISO format
    String dateString = "2021-07-05T18:00:00.000-04:00";
    // define your time zone
    ZoneId americaNewYork = ZoneId.of("America/New_York");
    // parse the (zone-less) String and add the time zone
    ZonedDateTime odt = OffsetDateTime.parse(dateString)
                                      .atZoneSameInstant(americaNewYork);
    // then get the rules of that zone
    long hours = americaNewYork.getRules()
                               // then get the daylight savings of the datetime
                               .getDaylightSavings(odt.toInstant())
                               // and get the full hours of the dst offset
                               .toHoursPart();
    
    // use a formatter to format the output (nearly) as desired
    System.out.println(odt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME)
                        + " has a daylight saving offset of "
                        + hours);
}

这打印

2021-07-05T18:00:00-04:00[America/New_York] has a daylight saving offset of 1

编辑:

您的评论让我提供了一个使用 along作为输入的类似版本:

public static void main(String[] args) {
    // example String in ISO format
    long input = 1625522400000L;
    // create an Instant from the input
    Instant instant = Instant.ofEpochMilli(input);
    // define your time zone
    ZoneId americaNewYork = ZoneId.of("America/New_York");
    // then get the rules of that zone
    long hours = americaNewYork.getRules()
                               // then get the daylight savings of the Instant
                               .getDaylightSavings(instant)
                               // and get the full hours of the dst offset
                               .toHoursPart();
    
    // use a formatter to format the output (nearly) as desired
    System.out.println(ZonedDateTime.ofInstant(instant, americaNewYork)
                                    .format(DateTimeFormatter.ISO_ZONED_DATE_TIME)
                        + " has a daylight saving offset of "
                        + hours);
}

输出与上面的示例相同。

于 2021-07-06T10:11:56.213 回答
0

在 java 错误跟踪器中,您会发现您的问题。

在“回退”期间,日历不支持消歧,给定的本地时间被解释为标准时间。为避免 DST 到标准时间的意外更改,请调用 add() 重置该值。

您可以通过将 set() 替换为

cal.add(Calendar.MINUTE, -cal.get(Calendar.MINUTE));
于 2021-07-06T09:53:07.470 回答