Java 为什么 Calendar.get(Calendar.DST_OFFSET) 在夏令时期间给出 0?
Java why does Calendar.get(Calendar.DST_OFFSET) give 0 during daylight savings time?
我有一个对应于 2021-07-05T18:00:00.000-04:00(东部夏令时)的日历对象。然而 Calendar.get(DST_OFFSET) 和 Calendar.getTimeZone().getDSTSavings() 都给出 0。应该是 1 小时。我错过了什么或者我出了什么问题?我使用的所有其他方法都返回预期值。
我正在使用 setTimeInMillis() 创建日历,并使用偏移量创建时区。这是它不起作用的原因吗?显示的民国时代总是对的...
尽管我想使用新的 Java 时间,但我正在为 Android 使用 Java。最后我检查了 Android 的最新版本是否支持新的 Java 时间。他们最终可能会添加对旧版本的支持。
在 java 错误中 tracker 你会发现你的问题。
在“回退”期间,日历不支持消歧,给定的当地时间被解释为标准时间。
为避免 DST 意外更改为标准时间,请调用 add() 重置值。
您可以通过将 set() 替换为
来解决它
cal.add(Calendar.MINUTE, -cal.get(Calendar.MINUTE));
一个问题是输入定义了与 UTC 的偏移量,但不是具有特定规则的实时时区(例如 如果完全应用 DST,如果是,什么时候应用夏令时)。
Calendar
显然无法处理这些规则,class(可能还有整个 API)并非旨在如此。
这是在 Java 8 中引入 java.time
的原因之一。
下面是一些在像您这样的情况下使用 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);
}
输出与上面的例子一样。
我有一个对应于 2021-07-05T18:00:00.000-04:00(东部夏令时)的日历对象。然而 Calendar.get(DST_OFFSET) 和 Calendar.getTimeZone().getDSTSavings() 都给出 0。应该是 1 小时。我错过了什么或者我出了什么问题?我使用的所有其他方法都返回预期值。
我正在使用 setTimeInMillis() 创建日历,并使用偏移量创建时区。这是它不起作用的原因吗?显示的民国时代总是对的...
尽管我想使用新的 Java 时间,但我正在为 Android 使用 Java。最后我检查了 Android 的最新版本是否支持新的 Java 时间。他们最终可能会添加对旧版本的支持。
在 java 错误中 tracker 你会发现你的问题。
在“回退”期间,日历不支持消歧,给定的当地时间被解释为标准时间。 为避免 DST 意外更改为标准时间,请调用 add() 重置值。
您可以通过将 set() 替换为
来解决它cal.add(Calendar.MINUTE, -cal.get(Calendar.MINUTE));
一个问题是输入定义了与 UTC 的偏移量,但不是具有特定规则的实时时区(例如 如果完全应用 DST,如果是,什么时候应用夏令时)。
Calendar
显然无法处理这些规则,class(可能还有整个 API)并非旨在如此。
这是在 Java 8 中引入 java.time
的原因之一。
下面是一些在像您这样的情况下使用 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);
}
输出与上面的例子一样。