【问题标题】:iCalendar durations where the duration's date portion ends inside a DST discontinuityiCalendar 持续时间,其中持续时间的日期部分在 DST 不连续内结束
【发布时间】:2020-10-15 07:01:41
【问题描述】:

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

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

但是,如果开始日期/时间正好是一个不连续时期的名义上的一天呢?例如,America/Los_Angeles 中的 2020-03-07T02:30 添加了 P1DT12H 持续时间,其中 DST 从 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:30PM。

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

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

【问题讨论】:

    标签: icalendar dst jscalendar


    【解决方案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 偏移量。

    请注意,这是 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

    【讨论】:

    • 使用偏移量的好主意。它解决了这个问题。谢谢!
    猜你喜欢
    • 2018-05-06
    • 2012-01-09
    • 1970-01-01
    • 2016-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 2022-01-18
    相关资源
    最近更新 更多