iCalendar 持续时间,其中持续时间的日期部分在 DST 不连续性内结束

iCalendar durations where the duration's date portion ends inside a DST discontinuity

RFC 5545 and other standards like JSCalendarP1DT12H 持续时间定义为名义上的一天加上 12 个准确的小时。通常这将是 36 个真实世界(“精确”或“准确”)小时,但是:

但是,如果开始 date/time 恰好是间断期之前的名义上的一天怎么办?例如,将 P1DT12H 持续时间添加到 America/Los_Angeles 中的 2020-03-07T02:30,其中夏令时从 2020-03-08T02:00 开始。在那种情况下,在该持续时间结束时计算的本地时间应该是多少?

2020-03-08T14:30吗? 2020-03-08T13:302020-03-08T15:30?还有别的吗?还有:为什么?

问题是计算确切持续时间的天真方法是使用标称单位添加持续时间的日期部分,然后将该中间结果转换为 UTC 并使用准确时间添加持续时间的时间部分。但是那个中间结果是一个被跳过的无效标称时间,那么那个中间值的本地时间是 2020-03-08T03:30(3:30AM,而不是 2:30AM),因为 RFC 5545 说:

If the local time described does not occur (when changing from standard to daylight time), the DATE-TIME value is interpreted using the UTC offset before the gap in local times.

因此使用规范的解释,添加 12 小时的时间部分后的最终结果应该是 2020-03-08T15:30 或 3:30PM。

根据 RFC 5455,这是“正确”的答案吗?如果不是,答案应该是什么?为什么?

或者这是标准中的歧义,没有客观正确的答案?

我希望有人能回答。这是我的理解:

这里有两个概念:

  • 任何一个都有 DTEND 并且正在计算 DURATION,正如您所确定的那样,如果在活动期间有夏令时变化,DURATION 会有所不同,或者
  • 有人知道持续时间并正在计算 DTEND。为了安全起见,最好在 UTC 中执行此操作。

回复你的问题: 但是,如果开始 date/time 恰好是一个不连续时期之前的名义上的一天呢?在那种情况下,在该持续时间结束时计算的本地时间应该是多少?

为了计算 DTEND,标称日同时将我们带到无效时间。如果使用 UTC 来计算标称日,则为凌晨 3.30。规范说:

In the case of discontinuities in the time scale, such as the change from standard time to daylight time and back, the computation of the exact duration requires the subtraction or addition of the change of duration of the discontinuity.

我理解这意味着是的,当计算出计算持续时间(即你有 DTSTART 和 DTEND 的地方)时,将根据日历中的事件点而有所不同,正如你所指出的。

回复你的问题 但是那个中间结果是一个被跳过的无效标称时间,那么那个中间值的本地时间是 2020-03-08T03:30(3:30AM,不是 2:30AM....."=57=]

是的,但是在进一步计算时,我认为你将 12H 添加到当地时间是错误的。规范说使用较早的 UTC 偏移量,我的意思是使用它来获取 UTC 时间,使用 UTC 进行计算,然后转换回来。

If the local time described does not occur (when changing from standard to daylight time), the DATE-TIME value is interpreted using the UTC offset before the gap in local times.

注意这是 UTC 偏移量。因此,名义上的一天将我们带到凌晨 2.30,而 3 月 8 日在洛杉矶不会 'exist',因此我们在时间间隔之前使用 UTC 偏移量。 -8 小时,这给了我们 UTC=10h30.
加上 12H 给我们 UTC 22H30。
如果我们为了计算目的而保留 -8 偏移量,我们将得到当地时间 14:30.

*规范中并未 100% 说明就是这样。更多的工作示例来确认会很好。

我在别处看到的建议是以 UTC 时间存储时间,以 UTC 时间进行计算,然后为了显示,计算本地时间。*

回复: 是2020-03-08T14:30吗? 根据 RFC 5455,这是“正确”的答案吗?如果不是,答案应该是什么?为什么?

我理解为 14H30。我使用 PHP 进行了交叉检查,在洛杉矶和 DST 之前和 DST 期间的 UTC 时间进行了计算,同时使用 datetime->add https://www.php.net/manual/en/datetime.add.php and https://www.php.net/manual/en/datetime.modify.php 并始终得到了答案。

我认为正确的是 2020-03-08T14:30 因为如果使用指定的 UTC 偏移量并以 UTC 计算,那就是结果。

PHP 工作

add a nominal day P01D
Before DST:
2020-03-06T02:30:00-08:00
2020-03-07T02:30:00-08:00 with modify
2020-03-07T02:30:00-08:00 add date interval

Over DST:
2020-03-07T02:30:00-08:00
2020-03-08T03:30:00-07:00 with modify
2020-03-08T03:30:00-07:00 add date interval



add a nominal day plus 12 H ie: P01DT12H
Before DST:
2020-03-06T02:30:00-08:00
2020-03-07T14:30:00-08:00 add date interval

Over DST:
2020-03-07T02:30:00-08:00
2020-03-08T14:30:00-07:00 with modify
2020-03-08T14:30:00-07:00 add date interval 

用于检查偏移量:https://www.timeanddate.com/worldclock/meetingtime.html?day=8&month=3&year=2020&p1=137&iv=0