0

RFC 5545和JSCalendar等其他标准将持续时间定义P1DT12H为一个标称天加上 12 个精确小时。通常这将是 36 个真实世界(“精确”或“准确”)小时,但是:

  • 如果春季 DST 转换发生在该持续时间的“名义上的一天”部分,则准确的持续时间仅为 35 小时。
  • 如果秋季 DST 转换发生在“名义上的一天”部分,那么准确的持续时间将为 37 小时。

但是,如果开始日期/时间恰好是不连续时期之前的名义上的一天怎么办?例如,P1DT12H添加到2020-03-07T02:30DSTAmerica/Los_Angeles开始处的持续时间2020-03-08T02:00。在这种情况下,该持续时间结束时计算的本地时间应该是多少?

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

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

如果没有出现所描述的本地时间(从标准时间更改为夏令时),则使用本地时间间隙之前的 UTC 偏移量解释 DATE-TIME 值。

因此,使用规范的这种解释,添加 12 个精确小时时间部分后的最终结果应该是2020-03-08T15:30下午 3:30。

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

或者这是标准中的模棱两可并且没有客观正确的答案?

4

1 回答 1

1

我希望其他人会回答。以下是我的理解:

这里有两个概念:

  • 任何一个都有 DTEND 并且正在计算 DURATION,正如您所建立的,如果活动期间有夏令时更改,则 DURATION 会有所不同,或者
  • 一个有持续时间并正在计算 DTEND。为了安全起见,最好在 UTC 中执行此操作。

请回答您的问题:但是,如果开始日期/时间恰好是不连续时期之前的名义上的一天怎么办?在这种情况下,该持续时间结束时计算的本地时间应该是多少?

为了计算 DTEND,同时标称天数将我们带到无效时间。如果一个人使用 UTC 来计算那个名义上的日子,一个人会得到 3.30 am。规范说:

在时间尺度不连续的情况下,例如从标准时间到白天时间的变化以及返回,精确持续时间的计算需要减去或增加不连续持续时间的变化。

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

重新回答您的问题但是该中间结果是跳过的无效标称时间,然后该中间值的本地时间为 2020-03-08T03:30(凌晨 3:30,而不是凌晨 2:30 ......”

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

如果没有出现所描述的本地时间(从标准时间更改为夏令时),则使用本地时间间隙之前的 UTC 偏移量解释 DATE-TIME 值。

请注意,这是UTC 偏移量。因此,名义上的一天将我们带到 3 月 8 日洛杉矶不“存在”的凌晨 2.30,因此我们使用时间间隔之前的 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.phphttps:// 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

于 2020-06-28T10:01:54.057 回答