B.2. Обработка недопустимых или неоднозначных значений даты/времени
Обычно, если строка даты/времени синтаксически корректна, но содержит поля со значениями вне допустимого диапазона, выдаётся ошибка. Например, не будет принята строка с числом 31 февраля.
Однако с учётом перевода часов на летнее время визуально корректная строка с датой/временем может указывать не несуществующий или неоднозначный момент времени. Такие значения, тем не менее, принимаются; для разрешения неоднозначности учитывается смещение от UTC. Например, в предположении, что значение TimeZone — America/New_York
, рассмотрите следующий пример:
=> SELECT '2018-03-11 02:30'::timestamptz; timestamptz ------------------------ 2018-03-11 03:30:00-04 (1 row)
Так как в этот день в данном часовом поясе стрелки часов переводились вперёд, по гражданским часам не существовал момент времени 2:30; они перескочили с 2:00 (EST) на 3:00 (EDT). PostgreSQL воспринимает заданное время, как если бы оно было стандартным временем (в часовом поясе UTC-5), в результате чего оно преобразуется в 3:30AM (в часовом поясе EDT или UTC-4).
И наоборот, рассмотрите поведение в случае перевода времени назад:
=> SELECT '2018-11-04 02:30'::timestamptz; timestamptz ------------------------ 2018-11-04 02:30:00-05 (1 row)
В этот день возможны две интерпретации времени 2:30; сначала было 2:30 в часовом поясе EDT, а час спустя, после возврата к стандартному времени, наступило 2:30 в часовом поясе EST. Так же и в этом случае PostgreSQL интерпретирует заданное время, как если бы оно было стандартным (UTC-5). Мы можем выбрать другой момент, указав часовой пояс летнего времени:
=> SELECT '2018-11-04 02:30 EDT'::timestamptz; timestamptz ------------------------ 2018-11-04 01:30:00-05 (1 row)
Этот момент времени можно представить как 2:30 в UTC-4 или 1:30 в UTC-5; код вывода timestamp выбирает последний вариант.
Точное правило, применяемое в таких случаях, звучит так: несуществующий момент времени, попадающий в интервал перевода часов вперёд, привязывается к смещению от UTC, действовавшему в данном часовом поясе до перевода, а неоднозначный момент времени, попадающий в оба интервала при переводе часов назад, привязывается к смещению от UTC, действующему после перевода. Для большинства часовых поясов это равносильно правилу «в случае неясности предпочитать интерпретацию со стандартным временем».
В любом случае смещение от UTC, связанное с меткой времени, можно задать явно, добавив либо числовое смещение, либо аббревиатуру часового пояса, которой соответствует некоторое фиксированное смещение. Вышеприведённое правило применяется, только когда необходимо вычислить смещение от UTC для часового пояса, в котором оно меняется.