【问题标题】:On DST(America/Los_Angeles), if i add one day it adds only 23 hours instead of 24在 DST(美国/洛杉矶)上,如果我添加一天,它只会增加 23 小时而不是 24 小时
【发布时间】:2017-06-19 04:46:43
【问题描述】:

这里是示例代码

public class DateFormatSampleCode {
    public static void main(String[] args) throws ParseException {
        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
        Calendar cal = Calendar.getInstance();
        cal.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
        cal.setTime(sdf.parse("2016-03-12T02:00:00-0800"));
        sdf.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
        System.out.println(sdf.format(cal.getTime()));
        cal.add(Calendar.DATE, 1);
        System.out.println(sdf.format(cal.getTime()));  
    }
}

答案在这里

“2016-03-12T01:00:00-0800”

,但在我看来应该是“

2016-03-12T03:00:00-0700

"。

【问题讨论】:

  • 如果在添加日期后重新设置时区怎么办?另外,我推荐java.time,而不是使用Calendar
  • @OleV.V.:谢谢,在 Java 7 之前,我们可以增加几小时而不是几天。从 java8 我们有 ZonedDateTime 和 LocalDateTime。
  • 一般最佳实践。对于 Java 8,请使用 java.time。对于 Java Joda-Time。恕我直言,试图解决导致这些改进必要性的边缘情况是不值得的。
  • @OleV.V. - 哈哈。语言太多了! :) 已修复。

标签: java dst


【解决方案1】:

如您所知,“在 2016 年,夏令时 (DST) 从 2016 年 3 月 13 日凌晨 2 点(当地时间)到 2016 年 11 月 6 日凌晨 2 点(当地时间)”(https://www.nist.gov/pml/time-and-frequency-division/popular-links/daylight-saving-time-dst) .因此,如果您将 24 小时添加到 3 月 12 日凌晨 2 点,您将准确地击中时钟从凌晨 2 点向前移动到凌晨 3 点的时间。所以我不认为期待什么结果很清楚。我会立即期待02:00:00-080003:00:00-0700(后者是您所期望的)。

您使用的是 Java-8 之前的 Calendar 类。如果结果记录准确,我就错过了。文档只说添加是“基于日历的规则”。想一想,问题是如果您从 3 月 12 日 2 到 3 之间的时间开始会发生什么。在 2 之前,您在 24 小时后的 3 月 13 日获得相同的时间。 3 之后也很容易,你得到相同的时间,只是因为变化而晚了 23 小时。对于 2 和 3 之间的时间,3 月 13 日不存在相同的时间,因此必须做出选择。似乎选择是减去一小时。此外,他们还选择在凌晨 2:00:00 执行此操作,但不是在 3:00:00 执行此操作,以便使规则在半开间隔一小时内有效。至少这是一致的。我们可能无法完全避免意想不到的结果。

Java 8 java.time 类(例如 ZonedDateTime)有更好的文档记录,因此更可靠。例如,ZonedDateTime.plusDays() 将 day/s 添加到本地日期时间并转换回 ZonedDateTime。如果本地日期时间处于间隙中(如此处),则“将根据间隙长度向前调整”(此处为 1 小时)。因此,您的结果将是 2016-03-13T03:00-07:00[America/Los_Angeles],与您预期的完全一样。

一个可能的教训是,如果您可以使用 Java 8,请使用 java.time 类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-25
    • 2011-12-03
    相关资源
    最近更新 更多