为什么calendar.get(calendar.dst_offset)在夏令时给出0?

mznpcxlj  于 2021-08-25  发布在  Java
关注(0)|答案(2)|浏览(448)

我有一个日历对象,对应于2021-07-05t18:00:00.000-04:00(东部夏时制)。然而,calendar.get(dst_offset)和calendar.gettimezone().getDSTSaviations()都给出了0,应该是1小时。我错过了什么,或者我做错了什么?我使用的所有其他方法都返回预期值。
我正在使用settimeinmillis()创建日历,并使用偏移量创建时区。这就是它不起作用的原因吗?显示的民用时间总是正确的。。。
虽然我很想使用新的java时间,但我正在使用java for android。上一次我只检查了最新版本的android支持新的java时间。他们最终可能会为旧版本添加支持。

ifsvaxew

ifsvaxew1#

一个问题是,输入定义了与utc的偏移量,但没有定义具有特定规则的实时时区(如是否应用了dst,如果应用了dst,何时应用dst)。 Calendar 显然不能处理这些规则,所以类(可能还有整个api)并不是设计成这样的。
这就是为什么要这样做的原因之一 java.time 已经在Java8中引入。
下面是使用 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

编辑:

你的评论让我提供了一个使用 long 作为输入:

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);
}

输出与上面的示例相同。

x759pob2

x759pob22#

在java bug跟踪器中,您将发现您的问题。
在“回退”期间,日历不支持消除歧义,给定的本地时间被解释为标准时间。要避免标准时间的意外dst更改,请调用add()重置该值。
可以通过将set()替换为

cal.add(Calendar.MINUTE, -cal.get(Calendar.MINUTE));

相关问题