RFC 5545 и другие стандарты, такие как JSCalendar определяет продолжительность P1DT12H как один номинальный день плюс 12 точных часов. . Обычно это 36 реальных («точных» или «точных») часов, но:

  • Если весенний переход на летнее время происходит в течение «одного номинального дня» этой продолжительности, то точная продолжительность будет только 35 часов.
  • Если осенний переход на летнее время происходит в течение «одного номинального дня», то точная продолжительность составит 37 часов.

Но что, если начальная дата / время - ровно за один номинальный день до прерывистого периода? Например, продолжительность P1DT12H добавлена ​​к 2020-03-07T02:30 в America/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 AM), потому что RFC 5545 говорит:

Если описанное местное время не наступает (при переходе со стандартного на летнее время), значение ДАТА-ВРЕМЯ интерпретируется с использованием смещения UTC перед разрывом в местном времени.

Таким образом, используя эту интерпретацию спецификации, окончательный результат после добавления 12-часового точного времени должен быть 2020-03-08T15:30 или 15:30.

Это «правильный» ответ согласно RFC 5455? Если нет, то каким должен быть ответ и почему?

Или это двусмысленность стандарта и нет объективно правильного ответа?

0
Justin Grant 25 Июн 2020 в 01:16

1 ответ

Лучший ответ

Я надеялся, что кто-нибудь ответит. Вот мое понимание:

Здесь две концепции:

  • Либо у одного есть DTEND, и он вычисляет ДЛИТЕЛЬНОСТЬ, которая, как вы установили, будет варьироваться, если во время мероприятия произойдет переход на летнее время, ИЛИ
  • у одного есть продолжительность и он вычисляет DTEND. Лучше сделать это в UTC в целях безопасности.

Повторите свой вопрос: Но что, если начальная дата / время - ровно за один номинальный день до прерывистого периода? В таком случае, каким должно быть местное время в конце этого периода?

Для расчета DTEND номинальный день в одно и то же время переводит нас в неверное время. Если использовать UTC для расчета этого номинального дня, получится 3.30 ночи. В спецификации говорится:

В случае разрывов в шкале времени, таких как переход от стандартного времени к летнему времени и обратно, вычисление точной продолжительности требует вычитания или добавления изменения продолжительности скачка.

Я понимаю, что это означает «да», при вычислении РАСЧЕТНОЙ длительности (т.е. когда у вас есть DTSTART и DTEND) будет варьироваться в зависимости от точки событий в календаре, как вы отметили.

Повторите свой вопрос Но этот промежуточный результат является недопустимым номинальным временем, которое пропущено, тогда местное время этого промежуточного значения - 2020-03-08T03: 30 (3:30, а не 2:30 ... "

Да, однако при дальнейших расчетах, я думаю, вы ошиблись, добавив 12H к местному времени. Спецификация говорит, что используйте более раннее смещение UTC, которое я понимаю, чтобы использовать его для получения времени UTC, использовать UTC для вычислений, а затем конвертировать обратно.

Если описанное местное время не наступает (при переходе со стандартного на летнее время), значение ДАТА-ВРЕМЯ интерпретируется с использованием смещения UTC перед разрывом в местном времени.

Обратите внимание, что это смещение по Гринвичу . Таким образом, один номинальный день приводит нас к 2.30 утра, чего «не существует» в Лос-Анджелесе 8 марта, поэтому мы используем смещение по всемирному координированному времени перед временным интервалом. -8 часов, что дает нам UTC = 10:30
Плюс 12H дает нам 22:30 по всемирному координированному времени.
Если мы оставим для расчетов смещение -8, мы получим 14:30 по местному времени.

* Это не на 100% прописано в спецификации. Было бы хорошо, если бы для подтверждения было больше отработанных примеров.

Совет, который я видел в другом месте, заключается в том, чтобы сохранять время во времени UTC, выполнять вычисления во времени UTC, а затем для отображения рассчитывать местное время. *

RE: Это 2020-03-08T14: 30? Это «правильный» ответ согласно RFC 5455? Если нет, то каким должен быть ответ и почему?

Я так понимаю, 14:30. Я перекрестно проверял с помощью PHP, с расчетами в LosAngeles и во времени UTC перед DST и во время DST, используя оба datetime-> add https://www.php.net/manual/en/datetime.add.php и 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

1
anmari 28 Июн 2020 в 10:01