Digital Q.DataBase поддерживается полный набор SQL типов даты и времени, приведенных в Таблица 2.5.9. Операции, доступные для данных типов данных, описаны в Раздел 2.6.9. Отсчет дат производится по григорианскому календарю, даже для лет, предшествующих его введению (см. Раздел 8.2.6 для получения дополнительной информации).
Таблица 2.5.9. Типы даты и времени
| Имя | Размер | Описание | Минимальное значение | Максимальное значение | Точность |
|---|---|---|---|---|---|
timestamp [ ( | 8 байт | комбинированные дата и время (без часового пояса) | 4713 до н. э. | 294276 н. э. | 1 микросекунда |
timestamp [ ( | 8 байт | дата и время с часовым поясом | 4713 до н. э. | 294276 н. э. | 1 микросекунда |
date | 4 байта | дата (без указания времени) | 4713 до н. э. | 5874897 н. э. | 1 день |
time [ ( | 8 байт | время (без указания даты) | 00:00:00 | 24:00:00 | 1 микросекунда |
time [ ( | 12 байт | время (без указания даты) с часовым поясом | 00:00:00+1559 | 24:00:00-1559 | 1 микросекунда |
интервал [ | 16 байт | временной интервал | -178000000 лет | 178000000 лет | 1 микросекунда |
Стандарт SQL требует, чтобы указание просто timestamp
было эквивалентно timestamp without time
zone, и Digital Q.DataBase следует этому
правилу. timestamptz принимается как сокращение для timestamp с часовым поясом; это
Digital Q.DataBase расширение.
time, timestamp, и
interval принимают необязательный параметр точности
p который определяет количество десятичных знаков в дробной части поля секунд. По умолчанию явное ограничение точности отсутствует. Допустимый диапазон значений
p составляет от 0 до 6.
Тип interval тип имеет дополнительный параметр, позволяющий ограничить набор хранимых полей с помощью одной из следующих фраз:
YEAR MONTH DAY HOUR MINUTE SECOND YEAR TO MONTH DAY TO HOUR DAY TO MINUTE DAY TO SECOND HOUR TO MINUTE HOUR TO SECOND MINUTE TO SECOND
Обратите внимание, что если указаны оба параметра поля и
p то
поля должен включать SECOND,
так как параметр точности применяется только к секундам.
Тип данных time с часовым поясом определен в стандарте SQL, однако его определение обладает свойствами, которые делают его практическую ценность сомнительной. В большинстве случаев сочетание типов
date, time, timestamp without time
zone, и timestamp с часовым поясом должно обеспечивать полный спектр функциональности для работы с датой и временем, необходимый любому приложению.
Данные типа даты и времени принимаются практически в любом стандартном формате, включая ISO 8601, SQL-совместимые,
традиционные форматы POSTGRES, и другие.
Для некоторых форматов порядок следования дня, месяца и года при вводе даты может быть
неоднозначным, поэтому предусмотрена возможность указания ожидаемого
порядка этих полей. Установите DateStyle параметр
в значение MDY для выбора интерпретации «месяц-день-год»,
DMY для выбора интерпретации «день-месяц-год» или
YMD для выбора интерпретации «год-месяц-день».
Digital Q.DataBase более гибко обрабатывает ввод даты и времени, чем того требует SQL стандарт. См. Приложение 8.2 для получения точных правил синтаксического анализа ввода даты/времени и списка распознаваемых текстовых полей, включая названия месяцев, дней недели и часовых поясов.
Помните, что любой литерал даты или времени должен быть заключен в одинарные кавычки, аналогично текстовым строкам. См. Раздел 2.1.1.2.7 для получения дополнительной информации. SQL требует использования следующего синтаксиса
тип[ (p) ] 'value'
где p — необязательный параметр точности, определяющий количество дробных разрядов в поле секунд. Точность может быть
указана для time, timestamp, и
interval типов и может принимать значения от 0 до 6. Если точность не задана при определении константы, по умолчанию используется точность литерального значения (но не более 6 знаков).
Таблица 2.5.10 содержит некоторые возможные
варианты ввода для date типа.
Таблица 2.5.10. Ввод даты
| Пример | Описание |
|---|---|
| 1999-01-08 | ISO 8601; 8 января в любом режиме (рекомендуемый формат) |
| 8 января 1999 г. | однозначно трактуется в любом datestyle режиме ввода |
| 1/8/1999 | 8 января в MDY режиме;
1 августа в DMY режиме |
| 1/18/1999 | 18 января в MDY режиме;
отклоняется в других режимах |
| 01/02/03 | 2 января 2003 г. в MDY режиме;
1 февраля 2003 г. в DMY режиме;
3 февраля 2001 г. в YMD режиме
|
| 1999-Jan-08 | 8 января в любом режиме |
| Jan-08-1999 | 8 января в любом режиме |
| 08-Jan-1999 | 8 января в любом режиме |
| 99-Jan-08 | 8 января в YMD режиме, в противном случае — ошибка |
| 08-Jan-99 | 8 января, за исключением возникновения ошибки в YMD режиме |
| Jan-08-99 | 8 января, за исключением возникновения ошибки в YMD режиме |
| 19990108 | ISO 8601; 8 января 1999 г. в любом режиме |
| 990108 | ISO 8601; 8 января 1999 г. в любом режиме |
| 1999.008 | год и день года |
| J2451187 | юлианская дата |
| 8 января 99 г. до н. э. | 99 год до н. э. |
К типам времени суток относятся time [
( и
p) ] without time zonetime [ (. p) ] with time
zonetime само по себе эквивалентно
time без часового пояса.
Допустимые входные данные для этих типов состоят из времени суток, за которым следует необязательный параметр часового пояса. (См. Таблица 2.5.11
и Таблица 2.5.12.) Если часовой пояс указан во входных данных для time без часового пояса,
он игнорируется без уведомления. Также можно указать дату, но она будет проигнорирована, за исключением тех случаев, когда используется имя часового пояса, предполагающее правила перехода на летнее время, например
America/New_York. В этом случае указание даты необходимо для определения того, действует ли в данный момент стандартное или летнее время. Соответствующее значение смещения часового пояса записывается в
time с часовым поясом значение и выводится в исходном виде;
оно не преобразуется в активный часовой пояс.
Таблица 2.5.11. Ввод времени
| Пример | Описание |
|---|---|
04:05:06.789 | ISO 8601 |
04:05:06 | ISO 8601 |
04:05 | ISO 8601 |
040506 | ISO 8601 |
04:05 AM | эквивалентно 04:05; параметр AM не влияет на значение |
04:05 PM | эквивалентно 16:05; вводимое значение часа должно быть <= 12 |
04:05:06.789-8 | ISO 8601, с часовым поясом в виде смещения UTC |
04:05:06-08:00 | ISO 8601, с часовым поясом в виде смещения UTC |
04:05-08:00 | ISO 8601, с часовым поясом в виде смещения UTC |
040506-08 | ISO 8601, с часовым поясом в виде смещения UTC |
040506+0730 | ISO 8601, с часовым поясом в виде смещения UTC с дробной частью часа |
040506+07:30:00 | Смещение UTC с точностью до секунд (не допускается в ISO 8601) |
04:05:06 PST | часовой пояс, указанный в виде аббревиатуры |
2003-04-12 04:05:06 America/New_York | часовой пояс, указанный полным названием |
Таблица 2.5.12. Ввод значений часового пояса
| Пример | Описание |
|---|---|
PST | Аббревиатура (для Тихоокеанского стандартного времени) |
America/New_York | Полное название часового пояса |
PST8PDT | Спецификация часового пояса в стиле POSIX |
-8:00:00 | Смещение UTC для PST |
-8:00 | Смещение UTC для PST (расширенный формат ISO 8601) |
-800 | Смещение UTC для PST (основной формат ISO 8601) |
-8 | Смещение UTC для PST (основной формат ISO 8601) |
zulu | Военная аббревиатура для обозначения UTC |
z | Краткая форма zulu (также используется в ISO 8601) |
См. Раздел 2.5.5.3 для получения дополнительной информации о способах указания часовых поясов.
Допустимые входные значения для типов меток времени представляют собой объединение даты и времени, за которыми может следовать необязательный параметр часового пояса, а затем необязательный параметр AD или BC.
(В качестве альтернативы, AD/BC может указываться
перед часовым поясом, однако такой порядок не является предпочтительным.)
Таким образом:
1999-01-08 04:05:06
и:
1999-01-08 04:05:06 -8:00
являются допустимыми значениями, соответствующими ISO 8601 стандарту. Кроме того, общепринятый формат:
January 8 04:05:06 1999 PST
поддерживается.
В SQL стандарте различаются
timestamp без часового пояса
и timestamp с часовым поясом литералы по наличию
«+» или «-» символа и смещения часового пояса после
значения времени. Следовательно, согласно стандарту,
TIMESTAMP '2004-10-19 10:23:54'
представляет собой timestamp без часового пояса, тогда как
TIMESTAMP '2004-10-19 10:23:54+02'
представляет собой timestamp с часовым поясом.
Digital Q.DataBase никогда не анализирует содержимое строкового литерала перед определением его типа и, следовательно, будет обрабатывать оба вышеуказанных выражения как timestamp без часового пояса. Чтобы гарантировать, что литерал будет интерпретирован как timestamp with time
zone, укажите для него правильный явный тип:
TIMESTAMP WITH TIME ZONE '2004-10-19 10:23:54+02'
В значении, которое было определено как тип timestamp without time
zone, Digital Q.DataBase любые указания часового пояса будут игнорироваться без вывода уведомлений. Таким образом, результирующее значение извлекается из полей даты и времени во входной строке и не корректируется с учётом часового пояса.
Для timestamp с часовым поясом значений входная строка,
содержащая явное указание часового пояса, будет преобразована в UTC
(Всемирное координированное
время) с использованием соответствующего смещения для этого часового пояса. Если часовой пояс не указан во входной строке, предполагается, что он соответствует часовому поясу, заданному системным
TimeZone параметром, и преобразуется в UTC с использованием смещения для timezone пояса.
В любом случае значение хранится внутри системы в формате UTC, а
первоначально указанный или предполагаемый часовой пояс не сохраняется.
Когда значение timestamp with time
zone выводится, оно всегда преобразуется из UTC в текущий timezone часовой пояс и отображается как местное время в этом поясе. Чтобы увидеть время в другом часовом поясе, либо измените
timezone либо используйте AT TIME ZONE конструкцию
(см. Раздел 2.6.9.4).
Преобразования между timestamp без часового пояса и
timestamp с часовым поясом обычно предполагают, что
timestamp без часового пояса значение должно приниматься или выдаваться
как timezone местное время. Для преобразования можно указать другой часовой пояс, используя AT TIME ZONE.
Digital Q.DataBase поддерживает несколько специальных входных значений даты и времени для удобства, как показано в Таблица 2.5.13. Значения
infinity и -infinity
имеют в системе специальное представление и будут отображаться
без изменений; остальные же являются лишь условными обозначениями,
которые при чтении преобразуются в обычные значения даты и времени.
(В частности, now и аналогичные строки преобразуются
в конкретное значение времени сразу же при чтении.)
Все эти значения при использовании в качестве констант в SQL-командах
должны заключаться в одинарные кавычки.
Таблица 2.5.13. Специальные значения для ввода даты и времени
| Входная строка | Допустимые типы данных | Описание |
|---|---|---|
epoch | date, timestamp | 1970-01-01 00:00:00+00 (нулевое системное время Unix) |
infinity | date, timestamp, interval | позже всех остальных меток времени |
-infinity | date, timestamp, interval | раньше всех остальных меток времени |
now | date, time, timestamp | время начала текущей транзакции |
сегодня | date, timestamp | полночь (00:00) сегодня |
завтра | date, timestamp | полночь (00:00) завтра |
вчера | date, timestamp | полночь (00:00) вчера |
allballs | time | 00:00:00.00 UTC |
Следующие SQL-совместимые функции могут также использоваться для получения текущего значения времени для соответствующего типа данных:
CURRENT_DATE, CURRENT_TIME,
CURRENT_TIMESTAMP, LOCALTIME,
LOCALTIMESTAMP. (См. Раздел 2.6.9.5.) Обратите внимание, что это функции SQL, и они не распознаются во входных строках данных.
Хотя входные строки now,
сегодня, завтра,
и вчера допустимо использовать в интерактивных SQL-командах,
однако их поведение может быть неожиданным, если команда
сохраняется для последующего выполнения, например в подготовленных операторах,
представлениях и определениях функций. Строка может быть преобразована в
конкретное значение времени, которое будет использоваться и после того, как оно станет
неактуальным. В таких контекстах вместо этого следует использовать одну из SQL-функций.
Например, CURRENT_DATE + 1 безопаснее, чем
'tomorrow'::date.
Для формата вывода типов даты/времени можно установить один из четырех стилей: ISO 8601,
SQL (Ingres), традиционный POSTGRES
(Unix date формат) или
German. По умолчанию
используется ISO формат. (В
SQL стандарте требуется использование формата ISO 8601. Название данного «SQL» формата вывода является
исторически сложившимся.) Таблица 2.5.14 содержит примеры для каждого
стиля вывода. Результат вывода date и
time типов обычно представляет собой только часть даты или времени
в соответствии с приведенными примерами. Однако
POSTGRES стиль выводит значения только даты в
ISO формате.
Таблица 2.5.14. Стили вывода даты/времени
| Спецификация стиля | Описание | Пример |
|---|---|---|
ISO | ISO 8601, стандарт SQL | 1997-12-17 07:37:16-08 |
SQL | традиционный стиль | 12/17/1997 07:37:16.00 PST |
Postgres | оригинальный стиль | Wed Dec 17 07:37:16 1997 PST |
German | региональный стиль | 17.12.1997 07:37:16.00 PST |
Стандарт ISO 8601 предписывает использование заглавной буквы T для разделения
даты и времени. Digital Q.DataBase принимает этот формат на входе, но на выходе использует пробел вместо T, как показано
выше. Это сделано для улучшения читаемости и обеспечения согласованности со спецификацией
RFC 3339 а также с некоторыми другими системами баз данных.
В стилях SQL и POSTGRES день располагается перед месяцем, если задан порядок полей DMY; в противном случае месяц располагается перед днем. (См. Раздел 2.5.5.1 информацию о том, как данный параметр также влияет на интерпретацию вводимых значений.) Таблица 2.5.15 приведены примеры.
Таблица 2.5.15. Соглашения о порядке дат
datestyle Параметр | Порядок полей при вводе | Пример вывода |
|---|---|---|
SQL, DMY | день/месяц/год | 17/12/1997 15:37:16.00 CET |
SQL, MDY | месяц/день/год | 12/17/1997 07:37:16.00 PST |
Postgres, DMY | день/месяц/год | Wed 17 Dec 07:37:16 1997 PST |
В стилях ISO стиле часовой пояс всегда отображается как
числовое смещение со знаком относительно UTC; при этом положительный знак используется для поясов
к востоку от Гринвича. Смещение отображается
в формате hh (только часы), если оно составляет целое
количество часов, в противном случае
в формате hh:mm если оно составляет
целое количество минут, в противном случае —
hh:mm:ss.
(Третий случай невозможен для современных стандартов часовых поясов,
но он может встретиться при работе с метками времени, предшествующими
принятию стандартизированных часовых поясов.)
В других стилях отображения даты часовой пояс указывается в виде буквенной
аббревиатуры, если она общепринята в данном поясе. В противном случае
он отображается как числовое смещение со знаком в базовом формате ISO 8601
(hh или hhmm).
Стиль представления даты и времени может быть выбран пользователем с помощью
SET datestyle команды, DateStyle параметра в
postgresql.conf или
PGDATESTYLE переменная окружения на сервере или клиенте.
Функция форматирования to_char
(см. Раздел 2.6.8) также может использоваться как более гибкий способ форматирования вывода даты и времени.
На часовые пояса и правила их использования влияют политические решения, а не только физическая география Земли. Система часовых поясов во всем мире была в некоторой степени стандартизирована в XX веке, но она по-прежнему подвержена произвольным изменениям, особенно в правилах перехода на летнее время. Digital Q.DataBase использует широко распространенную базу данных часовых поясов IANA (Olson), содержащую информацию об исторических правилах исчисления времени. При указании времени в будущем предполагается, что последние известные правила для данного часового пояса будут действовать неограниченно долго.
Digital Q.DataBase стремится обеспечить совместимость с требованиями SQL стандарта для типичных сценариев использования. Однако в SQL стандарте представлено неоднозначное сочетание типов даты и времени, а также их функциональных возможностей. Две наиболее очевидные проблемы:
Хотя date тип
не может иметь связанного часового пояса,
time тип допускает его использование.
В реальном мире часовые пояса имеют мало смысла, если они не
связаны одновременно с датой и временем,
поскольку величина смещения может изменяться в течение года при переходе на летнее
время.
Часовой пояс по умолчанию указывается как фиксированное числовое смещение от UTC. Вследствие этого невозможно учитывать переход на летнее время при выполнении арифметических операций с датой и временем через DST границы.
Для решения этих трудностей при использовании часовых поясов рекомендуется использовать типы даты/времени, содержащие одновременно и дату, и время. Мы не не рекомендуем использовать тип time with
time zone (хотя он и поддерживается
Digital Q.DataBase для устаревших приложений и
для соответствия SQL стандарту).
Digital Q.DataBase предполагает использование вашего локального часового пояса для любого типа, содержащего только дату или время.
Все значения даты и времени с часовыми поясами хранятся во внутреннем представлении в UTC. Они преобразуются в местное время в поясе, заданном TimeZone параметром конфигурации, перед отображением клиенту.
Digital Q.DataBase позволяет указывать часовые пояса в трех различных формах:
Полное название часового пояса, например America/New_York.
Список распознаваемых названий часовых поясов приведен в
pg_timezone_names представлении (см. Раздел 7.3.32).
Digital Q.DataBase использует широко распространенную базу данных
IANA о часовых поясах для этой цели, поэтому те же самые
названия часовых поясов распознаются и другим программным обеспечением.
Например, аббревиатура часового пояса PST. Подобная
спецификация лишь определяет конкретное смещение от UTC, в
отличие от полных названий часовых поясов, которые могут также
включать правила перехода на летнее время. Список поддерживаемых аббревиатур
приведен в pg_timezone_abbrevs представлении (см. Раздел 7.3.31). Вы не можете установить
параметры конфигурации TimeZone или
log_timezone в значение аббревиатуры
часового пояса, но их можно использовать во
входных значениях даты/времени и с AT TIME ZONE
оператором.
В дополнение к названиям и аббревиатурам часовых поясов, Digital Q.DataBase допускается использование спецификаций в стиле POSIX, как описано в Раздел 8.2.5. Данный вариант не обычно предпочтительнее использования именованного часового пояса, но это может быть необходимо, если подходящая запись часового пояса IANA отсутствует.
Вкратце, разница между сокращениями и полными названиями заключается в следующем: сокращения представляют собой конкретное смещение относительно UTC, тогда как многие полные названия подразумевают местное правило перехода на летнее время и, следовательно, имеют два возможных смещения UTC. Например,
2014-06-04 12:00 America/New_York представляет полдень по местному времени в Нью-Йорке, что для этой конкретной даты соответствовало восточному летнему времени (UTC-4). Таким образом, 2014-06-04 12:00 EDT указывает на тот же самый момент времени. Однако 2014-06-04 12:00 EST указывает на полдень по восточному стандартному времени (UTC-5) независимо от того, действовало ли номинально летнее время в этот день.
Ситуация осложняется тем, что в некоторых юрисдикциях одно и то же сокращение часового пояса использовалось для обозначения разных смещений UTC в разное время; например,
в Москве MSK означало UTC+3 в одни годы и
UTC+4 в другие. Digital Q.DataBase интерпретирует такие сокращения в соответствии с тем, что они означали (или означали в последний раз) на указанную дату; но, как и в EST примере
выше, это не обязательно совпадает с местным гражданским временем на эту дату.
Во всех случаях названия и сокращения часовых поясов распознаются без учета регистра. (Это изменение по сравнению с Digital Q.DataBase версиями до 8.2, в которых регистр учитывался в одних контекстах, но не учитывался в других.)
Ни названия часовых поясов, ни их сокращения не встроены в сервер жестко;
они извлекаются из конфигурационных файлов, хранящихся в
.../share/timezone/ и .../share/timezonesets/
каталога установки
(см. Раздел 8.2.4).
Значение TimeZone параметр конфигурации может
быть задан в файле postgresql.conf, или любым из других стандартных способов, описанных в Глава 3.4.
Существуют также некоторые специальные способы установки данного значения:
Функция SQL команда SET TIME ZONE
устанавливает часовой пояс для текущего сеанса. Данная форма записи является альтернативой
команде SET TIMEZONE TO и использует синтаксис, более соответствующий стандарту SQL.
Функция PGTZ переменная окружения используется
libpq клиентскими приложениями
для отправки SET TIME ZONE
команды серверу при установке соединения.
В Digital Q.DataBase также реализован параметр
qdb_server_timezone_only. С его помощью фиксируется временная зона
на уровне сервера, а временная зона, установленная на стороне клиента, игнорируется. Когда этот параметр установлен в
on (значение по умолчанию — off), все вызовы
SET TIMEZONE игнорируются без вывода ошибок или предупреждений,
а все временные функции используют значение, заданное в параметре
TimeZone в файле postgresql.conf.
Данный функционал глобально изменяет поведение системы. При включении серверного режима перед использованием в продуктивной среде необходимо протестировать режим репликации, а также режимы снятия и восстановления резервного копирования!
Пример настройки в postgresql.conf:
timezone = 'W-SU'
qdb_server_timezone_only = on
Пример использования:
SET TIMEZONE TO 'Asia/Vladivostok'; -- Будет проигнорировано
SELECT now(); -- Возвращает время в зоне сервера
interval значения могут быть записаны с использованием следующего подробного синтаксиса:
[@]количествоединица_измерения[количествоединица_измерения...] [направление]
где количество представляет собой число (возможно, со знаком);
единица_измерения является микросекунда,
миллисекунда, секунда,
минута, час, день,
неделя, месяц, год,
декада, век, тысячелетие,
либо сокращения или формы множественного числа этих единиц измерения;
направление может принимать значение ago или
пустое значение. Символ «@» (@) является необязательным элементом. Значения различных единиц неявно суммируются с учетом знака. ago инвертирует все поля.
Данный синтаксис также используется для вывода значений типа interval, если
IntervalStyle принимает значение
postgres_verbose.
Количество дней, часов, минут и секунд может быть указано без
явного обозначения единиц измерения. Например, '1 12:59:10' интерпретируется
так же, как '1 day 12 hours 59 min 10 sec'. Кроме того,
сочетание лет и месяцев может быть указано через дефис;
например, '200-10' интерпретируется так же, как '200 years
10 months'. (Эти краткие формы фактически являются единственными допустимыми
согласно SQL стандарту и используются для вывода, когда параметр
IntervalStyle принимает значение sql_standard.)
Значения интервалов также могут быть записаны как интервалы времени ISO 8601 с использованием либо «формата с обозначениями» из раздела 4.4.3.2 стандарта, либо «альтернативного формата» из раздела 4.4.3.3. Формат с обозначениями выглядит следующим образом:
Pколичествоединица_измерения[количествоединица_измерения...] [ T [количествоединица_измерения...]]
Строка должна начинаться с префикса P, а также может содержать символ
T , обозначающий начало единиц времени. Доступные сокращения единиц измерения приведены в Таблица 2.5.16. Единицы измерения могут быть опущены и указаны в произвольном порядке, но единицы меньше суток должны следовать после символа T. В частности, интерпретация символа
M зависит от того, указан он до или после символа
T.
Таблица 2.5.16. Сокращения единиц интервала ISO 8601
| Сокращение | Значение |
|---|---|
| Y | Годы |
| M | Месяцы (в части даты) |
| W | Недели |
| D | Дни |
| H | Часы |
| M | Минуты (в части времени) |
| S | Секунды |
В альтернативном формате:
P [годы-месяцы-дни] [ Tчасы:минуты:секунды]
строка должна начинаться с P, а символ
T разделяет дату и время в значении интервала.
Значения указываются в виде чисел, аналогично формату дат ISO 8601.
При записи константы типа interval со поля
спецификацией или при присваивании строки столбцу типа interval, определенному со поля спецификации интерпретация величин без указания единиц измерения зависит от поля. Например INTERVAL '1' YEAR интерпретируется как 1 год, тогда как
INTERVAL '1' означает 1 секунду. Кроме того, значения полей,
«расположенных справа» от наименее значимого поля, допускаемого
поля параметром спецификации, неявно отбрасываются. Например,
при указании INTERVAL '1 day 2:03:04' HOUR TO MINUTE
поле секунд будет отброшено, но поле дней сохранится.
Согласно SQL стандарту все поля значения интервала должны иметь одинаковый знак, поэтому ведущий знак минуса относится ко всем полям; например, знак минус в литерале интервала
'-1 2:03:04' относится и к дням, и к частям часов/минут/секунд. Digital Q.DataBase допускает наличие разных знаков у полей и традиционно обрабатывает каждое поле в текстовом представлении как имеющее собственный знак; таким образом, в данном примере часть часов/минут/секунд считается положительной. Если IntervalStyle принимает
значение sql_standard в этом случае ведущий знак
считается относящимся ко всем полям (но только если отсутствуют дополнительные знаки).
В противном случае используется традиционная Digital Q.DataBase используется интерпретация. Во избежание неоднозначности рекомендуется указывать явный знак для каждого поля, если хотя бы одно поле имеет отрицательное значение.
На внутреннем уровне interval значения хранятся в виде трёх целочисленных полей: месяцы, дни и микросекунды. Эти поля хранятся раздельно, так как количество дней в месяце может меняться, а в сутках может быть 23 или 25 часов при переходе на летнее или зимнее время. Строка ввода интервала, в которой используются другие единицы измерения, приводится к данному формату, а затем преобразуется в стандартный вид для вывода, например:
SELECT '2 years 15 months 100 weeks 99 hours 123456789 milliseconds'::interval;
interval
---------------------------------------
3 years 3 mons 700 days 133:17:36.789
В данном контексте недели, под которыми подразумеваются «7 дней», хранятся отдельно, в то время как более мелкие и крупные единицы времени были объединены и нормализованы.
Значения полей ввода могут содержать дробные части, например '1.5
weeks' или '01:02:03.45'. Однако,
поскольку interval внутренне хранит только целочисленные поля,
дробные значения должны быть преобразованы в более мелкие
единицы измерения. Дробные части единиц, превышающих месяц, округляются до целого числа месяцев, например '1.5 years'
преобразуется в '1 year 6 mons'. Дробные части
недель и дней вычисляются как целое число дней и
микросекунд из расчета 30 дней в месяце и 24 часов в сутках, например,
'1.75 months' преобразуется в 1 mon 22 days
12:00:00. Только секунды могут иметь дробную часть при выводе.
Таблица 2.5.17 приведены некоторые примеры
допустимых interval ввод.
Таблица 2.5.17. Ввод значений типа interval
| Пример | Описание |
|---|---|
1-2 | Формат стандарта SQL: 1 год 2 месяца |
3 4:05:06 | Формат стандарта SQL: 3 дня 4 часа 5 минут 6 секунд |
1 год 2 месяца 3 дня 4 часа 5 минут 6 секунд | Традиционный формат Postgres: 1 год 2 месяца 3 дня 4 часа 5 минут 6 секунд |
P1Y2M3DT4H5M6S | ISO 8601 «формата с обозначениями»: то же значение, что и выше |
P0001-02-03T04:05:06 | ISO 8601 «альтернативного формата»: то же значение, что и выше |
Как было пояснено ранее, Digital Q.DataBase
сохраняет interval значения в виде месяцев, дней и микросекунд. При выводе значение поля месяцев преобразуется в годы и месяцы путем деления на 12. Значение поля дней отображается без изменений. Значение поля микросекунд преобразуется в часы, минуты, секунды и доли секунды. Таким образом, значения месяцев, минут и секунд никогда не будут выходить за пределы диапазонов 0–11, 0–59 и 0–59 соответственно, тогда как отображаемые значения лет, дней и часов могут быть сколь угодно большими. (Параметр justify_days
и justify_hours
функции могут использоваться, если желательно преобразовать большие значения дней или часов с переходом в следующее, более старшее поле.)
Формат вывода типа interval можно задать в одном из четырех стилей sql_standard, postgres,
postgres_verbose, или iso_8601,
с помощью команды SET intervalstyle.
По умолчанию используется postgres формат.
Таблица 2.5.18 содержит примеры каждого
стиля вывода.
Значение sql_standard стиль формирует вывод, соответствующий спецификации стандарта SQL для строковых литералов интервала, если значение интервала отвечает ограничениям стандарта (только «год-месяц» или только «день-время», без смешивания положительных и отрицательных компонентов). В противном случае вывод выглядит как стандартный строковый литерал «год-месяц», за которым следует строковый литерал «день-время» с добавлением явных знаков для устранения неоднозначности в интервалах с разными знаками компонентов.
Вывод в стиле postgres соответствует выводу в
Digital Q.DataBase версиях до 8.4, когда
DateStyle параметр имел значение ISO.
Вывод в стиле postgres_verbose соответствует выводу в
Digital Q.DataBase версиях до 8.4, когда
DateStyle параметр был установлен в значение, отличное отISO вывода.
Вывод в стиле iso_8601 стиль соответствует «формату
с обозначениями» описанному в разделе 4.4.3.2 стандарта ISO 8601.
Таблица 2.5.18. Примеры стилей вывода интервалов
| Спецификация стиля | Интервал «год-месяц» | Интервал «день-время» | Смешанный интервал |
|---|---|---|---|
sql_standard | 1-2 | 3 4:05:06 | -1-2 +3 -4:05:06 |
postgres | 1 year 2 mons | 3 days 04:05:06 | -1 year -2 mons +3 days -04:05:06 |
postgres_verbose | @ 1 year 2 mons | @ 3 days 4 hours 5 mins 6 secs | @ 1 year 2 mons -3 days 4 hours 5 mins 6 secs ago |
iso_8601 | P1Y2M | P3DT4H5M6S | P-1Y-2M3DT-4H-5M-6S |