java - 当时区更改时如何向 DateTime 添加时间?

标签 java datetime time timezone dst

我有以下代码来向 DateTime 实例添加时间:

        DateTime d1 = new DateTime();
        d1 = d1.withZone(DateTimeZone.forID("Europe/London"));
        ArrayList<String> timeList = new ArrayList<String>();

        for(int x = 1; x <= 10; x++) {
        //Adds six hours to the DateTime instance.
                d1 = d1.plusHours(6);
                d1 = d1.plusMinutes(0);
                d1 = d1.plusSeconds(0);
                timeList.add(d1.toString());
        }

这将创建一组 10 次添加到数组列表中。然而,假设添加了 6 个小时后,夏令时发生了变化。由于时区更改而添加/删除额外时间时,如何生成正确的时间?目前,它不会使用此方法删除/添加额外的时间。

例如,如果我要在 2015 年 10 月 24 日上午 10:00 开始运行代码,我预计会生成以下时间。请注意,时区于 2015 年 10 月 25 日凌晨 02:00 发生变化。

24/10/2015 10:00:00 BST
24/10/2015 16:00:00 BST
24/10/2015 22:00:00 BST
25/10/2015 05:00:00 GMT
25/10/2015 11:00:00 GMT
25/10/2015 17:00:00 GMT
25/10/2015 23:00:00 GMT
26/10/2015 05:00:00 GMT
26/10/2015 11:00:00 GMT
26/10/2015 17:00:00 GMT

最佳答案

通常情况下,我会把正确的答案留给乔恩·斯基特(在我看来,他最后的评论或多或少是一个答案),但现在还有另外两个 Not Acceptable 答案,它们错过了关键点。

您的“问题”可以缩小为以下几行和(错误的)期望:

24/10/2015 22:00:00 BST

25/10/2015 05:00:00 GMT

您正确地写道,夏令时切换回冬令时发生在英国,时间为 2015 年 10 月 25 日凌晨 2:00。这意味着标记为“01”的小时发生了两次(重叠情况),因为时钟被调回并重复这一小时。因此,作为时钟位置的标称小时数必须增加一小时才能获得以小时为单位的实际物理持续时间。数学上:

nominal duration + one hour = real duration (= 6 real hours)
=> nominal duration = (6 - 1) hours = 5 virtual hours

请记住,像“24/10/2015 22:00:00 BST”这样的时间戳(采用 ISO 偏移表示法:“2015-10-24T22:00:00+01”)代表全局物理时刻,因此这些时刻之间的时间增量表示物理持续时间。在原始瞬间添加六小时的持续时间包含一个额外的小时,因此您必须从实际小时数中删除一小时才能获得标称持续时间(以时钟位置 - 请参阅上面给定方程的第二部分)。因此,用即时表示法来说:

[2015-10-24T22:00+01] + 6 physical hours = 
  [2015-10-25T04:00+01] = [2015-10-25T03:00+00] = [2015-10-25T03:00Z]

并以标称本地时间戳表示法(仅观察时钟位置):

[2015-10-24T22:00] + 5 virtual hours (clock positions) = [2015-10-25T03:00]

因此重复时钟位置会减少标称持续时间,但不会增加它。

这就是 Joda-Time 的正确做法:

DateTime d1 = new DateTime(2015, 10, 24, 10, 0, 0, 0, DateTimeZone.forID("Europe/London"));

for (int x = 1; x <= 10; x++) {
    d1 = d1.plusHours(6);
    System.out.println("> " + d1.toString());
}

> 2015-10-24T16:00:00.000+01:00
> 2015-10-24T22:00:00.000+01:00
> 2015-10-25T03:00:00.000Z
> 2015-10-25T09:00:00.000Z
> 2015-10-25T15:00:00.000Z
> 2015-10-25T21:00:00.000Z
> 2015-10-26T03:00:00.000Z
> 2015-10-26T09:00:00.000Z
> 2015-10-26T15:00:00.000Z
> 2015-10-26T21:00:00.000Z

关于java - 当时区更改时如何向 DateTime 添加时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30396648/

相关文章:

java - JFreeChart图表渲染问题

sql - 如何在 SQL 中将事件计数分配给相对日期值?

c# - ASP MVC Web API + EF 中带有时区的日期时间

c - 使用 clock() 确定函数的运行时间

javascript - Twitter 风格的前一段时间格式化 ("2h")与 Javascript

Netbeans - 跟踪项目中花费的时间

java - 为什么检查文件是否存在于 hadoop 中会导致 NullPointerException?

java - 根据输入参数调用不同的方法

Java:用于测试的模拟外部库

c# - .Net DateTime 与本地时间和 DST