Я пытаюсь объяснить это более понятно, чем упомянутая документация PostgreSQL.
Ни один из вариантов TIMESTAMP
не хранит часовой пояс (или смещение), несмотря на то, что предлагают названия. Разница заключается в интерпретации хранимых данных (и в предполагаемом приложении), а не в самом формате хранения:
TIMESTAMP WITHOUT TIME ZONE
хранит местное дата-время (aka. Дата и время настенного календаря). PostgreSQL может определить его часовой пояс (хотя ваше приложение может знать, что это такое). Следовательно, PostgreSQL не выполняет преобразование, связанное с часовым поясом, при вводе или выводе. Если значение было введено в базу данных как '2011-07-01 06:30:30'
, то не важно, в каком часовом поясе вы его отобразите позже, оно все равно будет содержать год 2011, месяц 07, день 01, 06 часов, 30 минут и 30 секунд (в некоторых формат). Кроме того, PostgreSQL игнорирует любое смещение или часовой пояс, которые вы указываете во входных данных, поэтому '2011-07-01 06:30:30+00'
и '2011-07-01 06:30:30+05'
такие же, как и '2011-07-01 06:30:30'
.
Для разработчиков Java: это аналог java.time.LocalDateTime
.
TIMESTAMP WITH TIME ZONE
сохраняет точку на временной шкале UTC. Как это выглядит (сколько часов, минут и т. Д.) Зависит от вашего часового пояса, но оно всегда относится к одному и тому же «физическому» моменту (например, моменту реального физического события).
Ввод внутренне преобразуется в UTC, и именно так он сохраняется. Для этого смещение ввода должно быть известно, поэтому, когда на входе нет явного смещения или часового пояса (например, '2011-07-01 06:30:30'
), предполагается, что он находится в текущем часовом поясе сеанса PostgreSQL, в противном случае явно указывается смещение или время зона используется (как в '2011-07-01 06:30:30+05'
). Выходные данные отображаются в преобразованном в текущий часовой пояс сеанса PostgreSQL.
Для разработчиков на Java: это аналог java.time.Instant
(хотя и с более низким разрешением), но с JDBC и JPA 2.2 вы должны отобразить его на java.time.OffsetDateTime
(или, конечно, java.util.Date
или java.sql.Timestamp
).
Некоторые говорят, что оба варианта TIMESTAMP
хранят дату и время UTC. Вроде, но, по моему мнению, это сбивает с толку. TIMESTAMP WITHOUT TIME ZONE
хранится как TIMESTAMP WITH TIME ZONE
, который отображается с часовым поясом UTC и дает те же год, месяц, день, часы, минуты, секунды и микросекунды, что и в местной дате-времени. Но он не предназначен для представления точки на временной шкале, которую говорит интерпретация UTC, это просто способ кодирования локальных полей даты и времени. (Это некоторая группа точек на временной шкале, поскольку реальный часовой пояс не является UTC; мы не знаем, что это такое.)