Существует длинный и довольно разъясняющий ответ о различиях между
TIMESTAMP WITH TIME ZONE
vs-TIMESTAMP WITHOUT TIME ZONE
доступны в этом посте . То, что я хотел бы знать: есть ли действительные варианты использования для фактического использования, TIMESTAMP WITHOUT TIME ZONE
или это следует рассматривать как анти-паттерн.
postgresql
Маркус Юний Брут
источник
источник
Ответы:
Об этом говорится во многих местах, но я думаю , что стоит отметить , всегда , когда мы сравним
timestamp with time zone
сtimestamp without time zone
типами: не хранит часовой пояс информацию вместе с меткой времени . Что он делает, чтобы хранить все данные в часовом поясе UTC, как указано в документации :timestamp WITH time zone
Для некоторых считается допустимым использование
timestamp WITHOUT time zone
в ситуациях, когда (1) все находится в одном часовом поясе или (2) прикладной уровень обрабатывает часовой пояс и просто хранит все в определенном часовом поясе (обычно UTC). Но это также считается анти-паттерном, простым, потому что правильное решение для (1) состоит в том, чтобы настроить параметр TimeZone для данного единого часового пояса для системы, и (2) уже решен, поскольку PostgreSQL уже хранит все в одном часовом поясе. (УНИВЕРСАЛЬНОЕ ГЛОБАЛЬНОЕ ВРЕМЯ).Теперь, с этими двумя, у меня может быть только одна веская причина
timestamp WITHOUT time zone
. Это когда вы хотите сохранить события в будущем, и когда мы дойдем до этого времени, должно быть запущено какое-то предупреждение. Это может быть полезно,timestamp WITH time zone
если и только если правила, определенные законами региона о часовом поясе, никогда не менялись. Наиболее распространенное правило, которое изменяется, касается принятия или не перехода на летнее время (DST).Например, представьте, что вы, скажем,
2013-06-15
(еще не в летнее время) запланировали какое-то событие,2013-01-15 10:00
которое должно было произойти (которое уже было бы в летнее время), и в2013-06-15
вашем регионе было назначено принять летнее время; но через некоторое время после этого правительство изменило правило и заявило, что ваш регион больше не будет использовать DST, и внезапно ваше запланированное время станет2013-01-15 11:00
(а не10:00
), что если вы используетеtimestamp WITH time zone
и будете поддерживать свои конфигурации TZ в актуальном состоянии. Конечно, вы также можете заметить, что такие случаи можно обрабатывать и с часовым поясом, если вы отслеживаете изменения правил в интересующих вас регионах / часовых поясах и обновляете затронутые записи.Стоит отметить, что некоторые регионы часто меняют эти правила (как, например, в Бразилии, некоторые штаты - не вся страна - часто меняются), но в большинстве случаев это меняет это очень рано, поэтому на ваших пользователей будут влиять только события, запланированные очень далеко от текущее время
После всего сказанного у меня есть только одно предложение. Если у вас есть пользователи, журналы или что-то в разных часовых поясах, сохраните часовой пояс, откуда они поступают, выберите и используйте
timestamp with time zone
. Таким образом, вы можете (1) пересекать события, происходящие ближе друг к другу для разных источников (независимо от их часовых поясов) и (2) показывать исходное время (время часов), когда событие произошло.источник
Да. Есть варианты использования для
TIMESTAMP WITHOUT TIME ZONE
.TIMESTAMP WITH TIME ZONE
, а неWITHOUT
.TIMESTAMP WITHOUT TIME ZONE
значения не являются точкой на временной шкале, а не фактическими моментами. Они представляют приблизительное представление о потенциальных моментах, возможных точках на временной шкале в диапазоне около 26-27 часов (диапазон часовых поясов вокруг земного шара). Они не имеют реального смысла, пока вы не примените часовой пояс или смещение от UTC .Пример: Рождество
Например, скажем, вам нужно записать начало праздников / праздников.
Чтобы зафиксировать тот факт, что Рождество начинается после полуночи 25 декабря этого года, мы должны сказать,
2016-12-25 00:00:00
без какого-либо часового пояса. В начале дня Санты он посещает Окленд в Новой Зеландии сразу после полуночи, так как это одна из самых ранних ночей в мире. Затем он направляется на запад, как и в следующую полночь, вскоре достигнув Филиппин. Затем олени двигаются в западном направлении, достигая Индии в полночь, что происходит через несколько часов после этой полуночи в Окленде. Намного позже все еще полночь в Париже FR, и еще позже полночь в Монреале, Калифорния. Все эти посещения Санта-Клауса происходят в разные моменты времени , но все они происходили вскоре после полуночи, в каждую полночь каждого населенного пункта.Поэтому запись
2016-12-25 00:00:00
без какого-либо часового пояса, как начало Рождества, является информативной и законной, но только смутно. Пока вы не скажете «Рождество в Окленде» или «Рождество в Монреале», у нас нет определенного момента времени. Если вы записываете фактический момент каждый раз, когда сани приземляются, вы должны использовать,TIMESTAMP WITH TIME ZONE
а неWITHOUT
тип.Похоже на Рождество в канун Нового года. Когда нью-йоркский бал Таймс-сквер падает , люди в Сиэтле все еще пьют шампанское и готовят рога для вечеринки . И все же мы записали бы идею новогоднего момента как
2017-01-01 00:00:00
вTIMESTAMP WITHOUT TIME ZONE
. Напротив, если мы хотим записать, когда мяч упал в Нью-Йорке или когда люди в Сиэтле взорвали свои рога, мы бы вместо этого использовалиTIMESTAMP WITH TIME ZONE
(неWITHOUT
), чтобы записать эти реальные моменты, каждые три часа друг от друга.Пример: заводские смены
Другим примером может быть запись политики, которая включает настенное время в разных местах. Скажем, у нас есть заводы в Детройте, Дюссельдорфе и Дели. Если мы скажем, что на всех трех фабриках первая смена начинается в 6 утра с перерыва на обед в 11:30, это можно записать как
TIMESTAMP WITHOUT TIME ZONE
. Опять же, эта информация полезна неопределенным образом, но не указывает конкретный момент времени, пока мы не применим часовой пояс. Новый день наступает раньше на востоке. Таким образом, фабрика в Дели будет открыта первой в 6 часов утра. Через несколько часов фабрика в Дюссельдорфе начинает работу в 6 часов утра. Но фабрика в Детройте на самом деле не откроется еще через шесть часов, когда наступит ее 6 утра.Сравните эту идею (о том, когда обычно начинается заводская смена) с историческим фактом, когда каждый заводской рабочий начал свою смену в определенный день. Часы - это реальный момент, фактическая точка на временной шкале. Таким образом, мы записали бы это в столбце типа,
TIMESTAMP WITH TIME ZONE
а неWITHOUT
типа.Так что да, есть законные варианты использования для
TIMESTAMP WITHOUT TIME ZONE
. Но по моему опыту с бизнес-приложениями, они относительно редки. В бизнесе мы склонны заботиться о реальных моментах: когда фактический счет-фактура поступил, когда именно этот контракт вступил в силу, в какой момент была выполнена эта банковская транзакция. Поэтому в таких распространенных ситуациях нам нуженTIMESTAMP WITH TIME ZONE
тип.Для получения дополнительной информации см. Мой ответ на аналогичный вопрос. Должен ли я хранить метки времени UTC или местное время для смен?
Postgres
Обратите внимание, что Postgres специально никогда не сохраняет информацию о часовом поясе, указанную при вставке временной метки.
TIMESTAMP WITH TIME ZONE
TIMESTAMP WITH TIME ZONE
какTIMESTAMP WITH RESPECT FOR TIME ZONE
.TIMESTAMP WITHOUT TIME ZONE
Стандарт SQL практически не затрагивает вопросы типов данных и поведения даты и времени. Таким образом, база данных широко варьируется в обработке даты и времени.
источник
21:00
)Я хотел бы добавить к этому еще одно мнение, которое противоречит большей части того, что было написано в других ответах. На мой взгляд,
timestamp with time zone
есть очень мало действительных вариантов использования, иtimestamp without time zone
в целом должно быть предпочтительным.Во-первых, вы должны понимать шаблон «UTC везде», который обычно рекомендуется для всех приложений, которые не предъявляют особых требований. Это просто означает, что ваше приложение должно представлять все свои метки времени в UTC, везде и всегда. Конечно, вы будете показывать локальную дату / время пользователям, но идея заключается в том, чтобы преобразовать их на самом краю вашей программы при рендеринге представления. Это правильное место для объединения временной метки UTC (которую вы, возможно, загрузили из базы данных) и временной зоны пользователя (которая может быть получена из браузера) в локальную временную метку.
Если вы следуете этому шаблону, тогда
timestamp with time zone
это анти-шаблон. Все, что делает этот тип, - это заставляет PostgreSQL выполнять преобразование часовых поясов при чтении и записи временных отметок на основе вашейTimeZone
переменной сеанса PostgreSQL . Вместо того, чтобы работать с часовыми поясами на самом краю вашего приложения, вы внедрили их в самое сердце, в саму связь с вашей базой данных. Вы должны позаботиться о том, чтобы всегдаTimeZone
правильно настраивать PostgreSQL , добавляя еще одну ненужную точку сбоя и путаницы.А для чего? Если вы следуете шаблону UTC везде, ваше приложение в любом случае имеет только временные метки UTC; так зачем просить вашу базу данных делать преобразования часовых поясов на них? Вы можете просто хранить их в
timestamp without time zone
столбце и обращаться с ним так, как будто это всегда UTC. Без конверсий, часовых поясов, без осложнений.источник
Instance
в NodaTime / JodaTime). Вы в основном описываете ситуацию, когда «UTC везде» почти соблюдается, или вроде как…timestamptz
. Весь смысл этого типа в том, чтобы выполнять преобразование часового пояса в виде значений, считанных и записанных в PostgreSQL (внутренне в базе данных отметка времени всегда сохраняется как UTC). Всегда установка часового пояса сеанса в UTC эффективно отключает эти преобразования, так зачемtimestamptz
вообще их использовать ? Иными словами, если значения в базе данных являются UTC, а значения, входящие и выходящие из базы данных, всегда являются UTC, то почему в вашей базе данных вообще есть информация о часовом поясе?date
Метка времени также не включает в себя информацию о временных зонах, тем не менее, многие люди используют его.Конечно, это само по себе не является ответом.
Оно действует использовать
timestamp
иdate
для любых временных отметок и дат , которые всегда находятся в одной и той же временной зоны, или хранящихся относительно некоторой известной часовой пояс.Если часовой пояс всегда один и тот же или неявный, то лучше хранить его, чем не хранить (избыточная информация).
Отметки времени также можно использовать для хранения технической информации, например, в журналах приложений или для измерения производительности. В этом случае часовой пояс также может быть неважным.
И наоборот, если вы проектируете или работаете в распределенной системе или в какой-либо системе, где части системы будут распределены по разным часовым поясам, это может рассматриваться как запрет на использование
timestamp with timezone
, хотя некоторые системы могут быть разработаны для запуска в одном часовом поясе, например, UTC. В этом случае логика часового пояса может быть перенесена на прикладной уровень - но я бы посчитал это анти-паттерном, да.источник
timestamp without timezone
, но покупает ли оно мне что-нибудь? Иначе зачем мне беспокоиться, еслиtimestamp with timezone data
тип всегда одинаково или более уместен?timestamp without timezone
тоже будет быстрее, но это, вероятно, важно, только если вы обрабатываете миллиарды строк ...timestamp
иtimestamptz
оба хранятся одинаково. Информация о часовом поясе не сохраняется в atimestamptz
, но вместо этого она преобразуется в UTC для хранения. Я бы сказал, всегда используйте,timestamptz
когда метки времени означают абсолютное время . Это все, чтоtimestamptz
значит. Я написал об этом здесь .Может показаться заманчивым сохранять и обрабатывать даты / время по местному времени, если ваше приложение ограничено одним часовым поясом, но я считаю, что это ошибка.
При переключении с летнего времени на стандартное время час по местному времени повторяется (при условии, что разница равна часу). Там, где я живу, это обычно происходит около 2 часов ночи, поэтому местное время идет 01:58, 01:59, 01:00 и продвигается только до 02:00 в конце повторного часа.
Если вы пытаетесь упорядочить события по времени, используя местное время, это означает, что события из двух отдельных часов смешиваются вместе и не отображаются в том порядке, в котором они действительно произошли.
Для сравнения, UTC не имеет этой проблемы и заказывает чисто. Таким образом, даже при работе только с одним часовым поясом вы хотите, чтобы БД сохраняла и обрабатывала время в UTC и преобразовывала в / из местного времени для ввода / отображения. Это поведение TIMESTAMP с зоной времени.
источник