9.9. Функции и операторы даты/времени#
9.9. Функции и операторы даты/времени #
Таблица 9.33 показывает доступные функции для обработки значений даты/времени, с подробностями, появляющимися в следующих подразделах. Таблица 9.32 иллюстрирует поведение основных арифметических операторов (+
, *
и т. д.). Для функций форматирования см. Раздел 9.8. Рекомендуем ознакомиться с общей информацией о типах данных даты/времени из Раздел 8.5.
Кроме того, для типов данных даты/времени доступны обычные операторы сравнения, показанные в Таблица 9.1. Даты и временные метки (с или без часового пояса) могут быть сравниваемыми, в то время как времена (с или без часового пояса) и интервалы могут быть сравниваемыми только с другими значениями того же типа данных. При сравнении временной метки без часового пояса с временной меткой с часовым поясом предполагается, что первое значение задано в часовом поясе, указанном в параметре конфигурации TimeZone, и поворачивается в UTC для сравнения со вторым значением (которое уже находится внутри UTC). Аналогично, значение даты предполагается представлять полночь в зоне TimeZone
при сравнении с временной меткой.
Все функции и операторы, описанные ниже, которые принимают входные данные типа time
или timestamp
, на самом деле имеют два варианта: один принимает time with time zone
или timestamp with time zone
, а другой принимает time without time zone
или timestamp without time zone
. В целях краткости эти варианты не показаны отдельно. Также операторы +
и *
представлены в коммутативных парах (например, как date
+
integer
и integer
+
date
); мы показываем только одну из каждой такой пары.
Таблица 9.32. Операторы даты/времени
Оператор Описание Пример(ы) |
---|
Добавление определенного количества дней к дате
|
Добавление интервала к дате
|
Добавление времени суток к дате
|
Добавление интервалов
|
Добавление интервала к метке времени
|
Добавление интервала к времени
|
Отрицание интервала
|
Вычитайте даты, получая количество прошедших дней
|
Вычтите определенное количество дней из даты
|
Вычесть интервал из даты
|
Вычитание времени
|
Вычесть интервал из времени
|
Вычесть интервал из метки времени
|
Вычитание интервалов
|
Вычесть метки времени (преобразование 24-часовых интервалов в дни,
аналогично
|
Умножение интервала на скаляр
|
Разделение интервала на скаляр
|
Таблица 9.33. Функции даты/времени
Функция Описание Пример(ы) |
---|
Вычтите аргументы, получив “символический” результат, который использует годы и месяцы, а не только дни.
|
Вычтите аргумент из
|
Текущая дата и время (изменяется во время выполнения оператора); см. Раздел 9.9.5
|
Текущая дата; см. Раздел 9.9.5
|
Текущее время суток; см. Раздел 9.9.5
|
Текущее время суток с ограниченной точностью; см. Раздел 9.9.5.
|
Текущая дата и время (начало текущей транзакции); см. Раздел 9.9.5
|
Текущая дата и время (начало текущей транзакции), с ограниченной точностью; см. Раздел 9.9.5.
|
Добавить
|
Bin вводится в указанный интервал, выровненный с указанным началом; см. Раздел 9.9.3
|
Получите подполе временной метки (эквивалентно
|
Получить подполе интервала (эквивалентно
|
Вычесть
|
Сократите до указанной точности; см. Раздел 9.9.2.
|
Усечь до указанной точности в указанном часовом поясе; см. Раздел 9.9.2
|
Сократите до указанной точности; см. Раздел 9.9.2.
|
Получите подполе временной метки; см. Раздел 9.9.1.
|
Получите подполе интервала; см. Раздел 9.9.1.
|
Тест на конечную дату (не +/-бесконечность)
|
Тест на конечную временную метку (не +/-бесконечность)
|
Тест для конечного интервала (в настоящее время всегда истинный)
|
Корректировка интервала, преобразование 30-дневных периодов времени в месяцы
|
Настроить интервал, преобразуя 24-часовые периоды времени в дни
|
Измените интервал, используя функции
|
Текущее время суток; см. Раздел 9.9.5
|
Текущее время суток с ограниченной точностью; см. Раздел 9.9.5.
|
Текущая дата и время (начало текущей транзакции); см. Раздел 9.9.5
|
Текущая дата и время (начало текущей транзакции), с ограниченной точностью; см. Раздел 9.9.5
|
Создание даты из полей года, месяца и дня (отрицательные годы обозначают до нашей эры)
|
Создайте интервал из полей лет, месяцев, недель, дней, часов, минут и секунд, каждое из которых может быть установлено по умолчанию в ноль
|
Создание времени из полей часов, минут и секунд
|
Создание метки времени из полей года, месяца, дня, часа, минуты и секунд (отрицательные годы обозначают до нашей эры)
|
Создайте метку времени с часовым поясом из полей года, месяца, дня, часа, минуты и секунды (отрицательные годы обозначают до нашей эры).
Если параметр
|
Текущая дата и время (начало текущей транзакции); см. Раздел 9.9.5
|
Текущая дата и время (начало текущего оператора); см. Раздел 9.9.5
|
Текущая дата и время (как
|
Текущая дата и время (начало текущей транзакции); см. Раздел 9.9.5
|
Преобразование Unix-эпохи (секунды с 1970-01-01 00:00:00+00) в метку времени с часовым поясом
|
В дополнение к этим функциям, поддерживается оператор SQL OVERLAPS
:
(start1
,end1
) OVERLAPS (start2
,end2
) (start1
,length1
) OVERLAPS (start2
,length2
)
Это выражение возвращает true, когда два временных периода (определенных своими конечными точками) перекрываются, и false, когда они не перекрываются. Конечные точки можно указать в виде пар дат, времен, или временных меток; или в виде даты, времени или временной метки, за которыми следует интервал. Когда предоставляется пара значений, начало или конец могут быть записаны первыми; OVERLAPS
автоматически берет более раннее значение из пары в качестве начала. Каждый временной период считается полуоткрытым интервалом start
<=
time
<
end
, если только start
и end
не равны, в этом случае он представляет один момент времени. Это означает, например, что два временных периода, имеющих только общую конечную точку, не перекрываются.
SELECT (DATE '2001-02-16', DATE '2001-12-21') OVERLAPS (DATE '2001-10-30', DATE '2002-10-30'); Результат:true
SELECT (DATE '2001-02-16', INTERVAL '100 days') OVERLAPS (DATE '2001-10-30', DATE '2002-10-30'); Результат:false
SELECT (DATE '2001-10-29', DATE '2001-10-30') OVERLAPS (DATE '2001-10-30', DATE '2001-10-31'); Результат:false
SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS (DATE '2001-10-30', DATE '2001-10-31'); Результат:true
При добавлении значения interval
к (или вычитании значения interval
из) значения timestamp
или timestamp with time zone
, поля месяцев, дней и микросекунд значения interval
обрабатываются поочередно. Сначала ненулевое поле месяцев увеличивает или уменьшает дату временной метки на указанное количество месяцев, сохраняя день месяца тем же, если только он не выходит за пределы нового месяца, в этом случае используется последний день этого месяца. (Например, 31 марта плюс 1 месяц становится 30 апреля, но 31 марта плюс 2 месяца становится 31 мая.) Затем поле дней увеличивает или уменьшает дату временной метки на указанное количество дней. На обоих этих этапах местное время суток остается тем же. Наконец, если есть ненулевое поле микросекунд, оно добавляется или вычитается буквально. При выполнении арифметических операций с значением timestamp with time zone
в часовом поясе, который признает летнее время (DST), это означает, что добавление или вычитание (например) interval '1 day'
не обязательно имеет тот же результат, что и добавление или вычитание interval '24 hours'
. Например, с установленным часовым поясом сессии America/Denver
:
SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '1 day'; Результат:2005-04-03 12:00:00-06
SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; Результат:2005-04-03 13:00:00-06
Это происходит потому, что час был прне указан из-за изменения летнего времени в 2005-04-03 02:00:00
в часовом поясе America/Denver
.
Примечание: может возникнуть неоднозначность в поле months
, возвращаемом функцией age
, поскольку разные месяцы имеют разное количество дней. Подход Tantor SE-1C использует месяц из более ранней из двух дат при вычислении частичных месяцев. Например, age('2004-06-01', '2004-04-30')
использует апрель, чтобы получить 1 мес 1 день
, в то время как использование мая дало бы 1 мес 2 дня
, потому что в мае 31 день, а в апреле только 30.
Вычитание дат и временных меток также может быть сложным. Одним из концептуально простых способов выполнить вычитание является преобразование каждого значения в количество секунд с помощью EXTRACT(EPOCH FROM ...)
, затем вычитание результатов; это дает количество секунд между двумя значениями. Это позволяет учесть количество дней в каждом месяце, изменения часового пояса и переход на летнее время. Вычитание значений даты или временной метки с использованием оператора “-
” возвращает количество дней (24 часа) и часы/минуты/секунды между значениями, сделав те же корректировки. Функция age
возвращает годы, месяцы, дни и часы/минуты/секунды, выполняя вычитание поля за полем, а затем корректируя отрицательные значения полей. В следующих запросах показаны различия в этих подходах. Примеры результатов были получены с использованием timezone = 'US/Eastern'
; между двумя использованными датами происходит переход на летнее время.
SELECT EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') - EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00'); Результат:10537200.000000
SELECT (EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') - EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00')) / 60 / 60 / 24; Результат:121.9583333333333333
SELECT timestamptz '2013-07-01 12:00:00' - timestamptz '2013-03-01 12:00:00'; Результат:121 days 23:00:00
SELECT age(timestamptz '2013-07-01 12:00:00', timestamptz '2013-03-01 12:00:00'); Результат:4 mons
9.9.1. EXTRACT
, date_part
#
EXTRACT(field
FROMsource
)
Функция extract
извлекает подполя, такие как год или час, из значений даты/времени.
source
должен быть выражением значения типа timestamp
, date
, time
или interval
. (Метки времени и время могут быть с часовым поясом или без него.)
field
является идентификатором или строкой, которая выбирает, какое поле извлечь из исходного значения.
Не все поля допустимы для каждого типа входных данных; например, поля меньше дня не могут быть извлечены из date
, в то время как поля дня или более не могут быть извлечены из time
.
Функция extract
возвращает значения типа numeric
.
Следующие имена полей являются допустимыми:
century
Век; для значений
interval
поле года, деленное на 100SELECT EXTRACT(CENTURY FROM TIMESTAMP '2000-12-16 12:21:13'); Результат:
20
SELECT EXTRACT(CENTURY FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:21
SELECT EXTRACT(CENTURY FROM DATE '0001-01-01 AD'); Результат:1
SELECT EXTRACT(CENTURY FROM DATE '0001-12-31 BC'); Результат:-1
SELECT EXTRACT(CENTURY FROM INTERVAL '2001 years'); Результат:20
day
День месяца (1–31); для
interval
значений, количество днейSELECT EXTRACT(DAY FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:
16
SELECT EXTRACT(DAY FROM INTERVAL '40 days 1 minute'); Результат:40
decade
Поле года, разделенное на 10.
SELECT EXTRACT(DECADE FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:
200
dow
День недели от воскресенья (
0
) до субботы (6
)SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:
5
Обратите внимание, что нумерация дней недели функции
extract
отличается от нумерации функцииto_char(..., 'D')
.doy
День года (1–365/366)
SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:
47
epoch
Для значений типа
timestamp with time zone
количество секунд с 1970-01-01 00:00:00 UTC (отрицательное для времен до этого момента); для значений типаdate
иtimestamp
номинальное количество секунд с 1970-01-01 00:00:00, без учета часового пояса или правил перехода на летнее время; для значений типаinterval
общее количество секунд в интервале.SELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40.12-08'); Результат:
982384720.120000
SELECT EXTRACT(EPOCH FROM TIMESTAMP '2001-02-16 20:38:40.12'); Результат:982355920.120000
SELECT EXTRACT(EPOCH FROM INTERVAL '5 days 3 hours'); Результат:442800.000000
Вы можете преобразовать значение эпохи обратно в тип
timestamp with time zone
с помощью функцииto_timestamp
:SELECT to_timestamp(982384720.12); Результат:
2001-02-17 04:38:40.12+00
Будьте осторожны при применении функции
to_timestamp
к эпохе, извлеченной из значения типаdate
илиtimestamp
, так как это может привести к неправильному результату: результат будет предполагать, что исходное значение было задано в формате UTC, что может не соответствовать действительности.hour
Поле часа (0–23 в метках времени, неограничено в интервалах)
SELECT EXTRACT(HOUR FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:
20
isodow
День недели от понедельника (
1
) до воскресенья (7
)SELECT EXTRACT(ISODOW FROM TIMESTAMP '2001-02-18 20:38:40'); Результат:
7
Это идентично
dow
, за исключением воскресенья. Это соответствует нумерации дня недели в соответствии с ISO 8601.isoyear
Год нумерации недель по ISO 8601, в который попадает дата
SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-01'); Результат:
2005
SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02'); Результат:2006
Каждый год недельной нумерации ISO 8601 начинается с понедельника недели, содержащей 4 января, поэтому в начале января или в конце декабря ISO год может отличаться от григорианского года. См. поле
week
для получения дополнительной информации.julian
Юлианская дата, соответствующая дате или временной метке. Временные метки, которые не соответствуют местному полуночи, приводят к дробному значению. См. Раздел B.7 для получения дополнительной информации.
SELECT EXTRACT(JULIAN FROM DATE '2006-01-01'); Результат:
2453737
SELECT EXTRACT(JULIAN FROM TIMESTAMP '2006-01-01 12:00'); Результат:2453737.50000000000000000000
microseconds
Поле секунд, включая дробные части, умноженное на 1 000 000; обратите внимание, что это включает полные секунды.
SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5'); Результат:
28500000
millennium
Тысячелетие; для значений
interval
, поле года делится на 1000SELECT EXTRACT(MILLENNIUM FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:
3
SELECT EXTRACT(MILLENNIUM FROM INTERVAL '2001 years'); Результат:2
Годы в 1900-х годах находятся во втором тысячелетии. Третье тысячелетие началось 1 января 2001 года.
milliseconds
Поле секунд, включая дробные части, умноженное на 1000. Обратите внимание, что это включает полные секунды.
SELECT EXTRACT(MILLISECONDS FROM TIME '17:12:28.5'); Результат:
28500.000
minute
Поле минут (0–59)
SELECT EXTRACT(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:
38
month
Номер месяца в году (1–12); для значений
interval
, количество месяцев по модулю 12 (0–11)SELECT EXTRACT(MONTH FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:
2
SELECT EXTRACT(MONTH FROM INTERVAL '2 years 3 months'); Результат:3
SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months'); Результат:1
quarter
Четверть года (1–4), в которой находится дата
SELECT EXTRACT(QUARTER FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:
1
second
Поле секунд, включая любые доли секунд
SELECT EXTRACT(SECOND FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:
40.000000
SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); Результат:28.500000
timezone
Смещение часового пояса относительно UTC, измеряемое в секундах. Положительные значения соответствуют часовым поясам на восток от UTC, отрицательные значения - на запад от UTC. (Технически, Tantor SE-1C не использует UTC, потому что не обрабатывает високосные секунды).
timezone_hour
Компонент часового пояса смещения
timezone_minute
Компонент минут смещения часового пояса
week
Количество недели года в нумерации недель ISO 8601. По определению, недели ISO начинаются в понедельник, и первая неделя года содержит 4 января этого года. Другими словами, первый четверг года находится в неделе 1 этого года.
В системе нумерации недель ISO возможно, что даты начала января могут быть частью 52-й или 53-й недели предыдущего года, а даты конца декабря могут быть частью первой недели следующего года. Например,
2005-01-01
является частью 53-й недели 2004 года, а2006-01-01
является частью 52-й недели 2005 года, в то время как2012-12-31
является частью первой недели 2013 года. Рекомендуется использовать полеisoyear
вместе с полемweek
для получения последовательных результатов.SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:
7
year
Поле года. Имейте в виду, что нет 0 года н.э.
0 AD
, поэтому вычитание летBС
до н.э. изAD
н.э. следует делать внимательно.SELECT EXTRACT(YEAR FROM TIMESTAMP '2001-02-16 20:38:40'); Результат:
2001
При обработке значения interval
,
функция extract
производит значения полей,
которые соответствуют интерпретации, используемой функцией вывода интервала.
Это может привести к неожиданным результатам, если начать с ненормализованного
представления интервала, например:
SELECT INTERVAL '80 minutes'; Результат:01:20:00
SELECT EXTRACT(MINUTES FROM INTERVAL '80 minutes'); Результат:20
Примечание
Когда входное значение равно +/-Infinity, функция extract
возвращает +/-Infinity для монотонно возрастающих полей (epoch
, julian
, year
, isoyear
, decade
, century
и millennium
). Для других полей возвращается NULL. В предыдущих версиях PostgreSQL до 9.6 для всех случаев бесконечного ввода возвращался ноль.
Функция extract
предназначена в основном для вычислительной обработки. Для форматирования значений даты/времени для отображения см. Раздел 9.8.
Функция date_part
моделируется по аналогии с традиционной функцией Ingres, эквивалентной стандартной функции extract
в SQL:
date_part('field
',source
)
Обратите внимание, что здесь параметр field
должен быть строковым значением, а не именем. Допустимые имена полей для функции date_part
такие же, как и для функции extract
.
По историческим причинам функция date_part
возвращает значения типа double precision
. Это может привести к потере точности в некоторых случаях. Рекомендуется использовать функцию extract
вместо нее.
SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40'); Результат:16
SELECT date_part('hour', INTERVAL '4 hours 3 minutes'); Результат:4
9.9.2. date_trunc
#
Функция date_trunc
концептуально похожа на функцию trunc
для чисел.
date_trunc(field
,source
[,time_zone
])
source
- это выражение значения типа
timestamp
, timestamp with time zone
или
interval
.
(Значения типа date
и
time
автоматически приводятся к типу timestamp
или
interval
, соответственно).
field
выбирает точность, до которой
усекается входное значение. Возвращаемое значение также имеет тип
timestamp
, timestamp with time zone
или
interval
,
и все поля, которые менее значимы, чем выбранное, устанавливаются в ноль (или в единицу для дня и месяца).
Допустимые значения для field
следующие:
microseconds |
milliseconds |
second |
minute |
hour |
day |
week |
month |
quarter |
year |
decade |
century |
millennium |
Когда входное значение имеет тип timestamp with time zone
,
обрезка выполняется с учетом определенного часового пояса;
например, обрезка до day
дает значение,
которое является полночью в этом часовом поясе. По умолчанию обрезка выполняется с учетом
текущей настройки TimeZone, но
можно указать дополнительный аргумент time_zone
,
чтобы указать другой часовой пояс. Имя часового пояса можно указать
любым из способов, описанных в Раздел 8.5.3.
Нельзя указывать часовой пояс при обработке ввода типа timestamp without
time zone
или interval
. Они всегда принимаются как есть.
Примеры (предполагая, что локальный часовой пояс - America/New_York
):
SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40'); Результат:2001-02-16 20:00:00
SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40'); Результат:2001-01-01 00:00:00
SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00'); Результат:2001-02-16 00:00:00-05
SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00', 'Australia/Sydney'); Результат:2001-02-16 08:00:00-05
SELECT date_trunc('hour', INTERVAL '3 days 02:47:33'); Результат:3 days 02:00:00
9.9.3. date_bin
#
Функция date_bin
“разбивает” входную метку времени на указанный интервал (шаг stride), выровненный по указанному началу.
date_bin(stride
,source
,origin
)
source
- это выражение значения типа
timestamp
или timestamp with time zone
. (Значения
типа date
автоматически приводятся к типу
timestamp
). stride
- это выражение значения типа
interval
. Возвращаемое значение также имеет тип timestamp
или timestamp with time zone
,
и оно обозначает начало интервала, в который помещается
source
.
Примеры:
SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01'); Результат:2020-02-11 15:30:00
SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01 00:02:30'); Результат:2020-02-11 15:32:30
В случае полных единиц (1 минута, 1 час и т. д.) она дает тот же результат, что и аналогичный вызов функции date_trunc
, но разница в том, что date_bin
может усекать до произвольного интервала.
Интервал stride
должен быть больше нуля и не может содержать единицы измерения месяца или больше.
9.9.4. AT TIME ZONE
#
Оператор AT TIME ZONE
преобразует временную метку без часового пояса в/из временной метки с часовым поясом и значения time with time zone
в различные часовые пояса. Варианты использования приведены в таблице Таблица 9.34.
Таблица 9.34. AT TIME ZONE
Варианты
Оператор Описание Пример(ы) |
---|
Преобразует заданную временную метку без учета часового пояса в временную метку с учетом часового пояса, предполагая, что заданное значение находится в указанном часовом поясе.
|
Преобразует заданную временную метку с часовым поясом в временную метку без часового пояса, так, как она отобразилась бы в этом часовом поясе.
|
Преобразует заданное время с учетом часового пояса в новый часовой пояс. Поскольку дата не указана, используется текущее активное перемещение относительно UTC для указанного целевого часового пояса.
|
В этих выражениях желаемый часовой пояс zone
может быть указан
либо в виде текстового значения (например, 'America/Los_Angeles'
),
либо в виде интервала (например, INTERVAL '-08:00'
).
В случае с текстом, имя часового пояса может быть указано любым из способов,
описанных в Раздел 8.5.3.
В случае с интервалом это полезно только для поясов, имеющих фиксированные смещения от
UTC, поэтому на практике это не очень распространено.
Примеры (при условии, что текущая настройка TimeZone - America/Los_Angeles
):
SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'America/Denver'; Результат:2001-02-16 19:38:40-08
SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'America/Denver'; Результат:2001-02-16 18:38:40
SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 'America/Chicago'; Результат:2001-02-16 05:38:40
Первый пример добавляет временную зону к значению, которое ее не имеет, и отображает значение с использованием текущей настройки TimeZone
. Второй пример сдвигает значение временной метки с временной зоной в указанную временную зону и возвращает значение без временной зоны. Это позволяет хранить и отображать значения, отличные от текущей настройки TimeZone
. Третий пример преобразует время в Токио в время в Чикаго.
Функция
эквивалентна конструкции, соответствующей стандарту SQL,
timezone
(zone
,
timestamp
)
.
timestamp
AT TIME ZONE
zone
9.9.5. Текущая Дата/Время #
Tantor SE-1C предоставляет ряд функций, которые возвращают значения, связанные с текущей датой и временем. Эти функции, соответствующие стандарту SQL, возвращают значения, основанные на времени начала текущей транзакции:
CURRENT_DATE CURRENT_TIME CURRENT_TIMESTAMP CURRENT_TIME(precision
) CURRENT_TIMESTAMP(precision
) LOCALTIME LOCALTIMESTAMP LOCALTIME(precision
) LOCALTIMESTAMP(precision
)
CURRENT_TIME
и
CURRENT_TIMESTAMP
возвращают значения с учетом часового пояса;
LOCALTIME
и
LOCALTIMESTAMP
возвращают значения без учета часового пояса.
CURRENT_TIME
,
CURRENT_TIMESTAMP
,
LOCALTIME
, и
LOCALTIMESTAMP
могут дополнительно принимать
параметр точности, который приводит к округлению
результата до указанного количества десятичных знаков в поле секунд. Без параметра точности
результат предоставляется с полной доступной точностью.
Некоторые примеры:
SELECT CURRENT_TIME; Результат:14:39:53.662522-05
SELECT CURRENT_DATE; Результат:2019-12-23
SELECT CURRENT_TIMESTAMP; Результат:2019-12-23 14:39:53.662522-05
SELECT CURRENT_TIMESTAMP(2); Результат:2019-12-23 14:39:53.66-05
SELECT LOCALTIMESTAMP; Результат:2019-12-23 14:39:53.662522
Так как эти функции возвращают время начала текущей транзакции, их значения не изменяются в течение транзакции. Это считается особенностью: цель состоит в том, чтобы позволить одной транзакции иметь последовательное представление “текущего”" времени, так чтобы несколько изменений в рамках одной транзакции имели одинаковую временную метку.
Примечание
Другие системы баз данных могут обновлять эти значения чаще.
Tantor SE-1C также предоставляет функции, которые возвращают время начала текущего оператора, а также фактическое текущее время в момент вызова функции. Полный список функций времени, не являющихся стандартными для SQL, включает:
transaction_timestamp() statement_timestamp() clock_timestamp() timeofday() now()
transaction_timestamp()
эквивалентна
CURRENT_TIMESTAMP
, но названа так, чтобы ясно отражать
то, что она возвращает.
statement_timestamp()
возвращает время начала текущего
оператора (точнее, время получения последнего командного
сообщения от клиента).
statement_timestamp()
и transaction_timestamp()
возвращают одно и то же значение во время первой команды транзакции, но могут
отличаться во время последующих команд.
clock_timestamp()
возвращает фактическое текущее время, и
поэтому его значение изменяется даже в рамках одной SQL-команды.
timeofday()
- это историческая
функция Tantor SE-1C. Как и
clock_timestamp()
, она возвращает фактическое текущее время,
но в виде отформатированной строки text
, а не значения timestamp
with time zone
.
now()
- это традиционный эквивалент Tantor SE-1C
для transaction_timestamp()
.
Все типы данных даты/времени также принимают специальное литеральное значение now
, чтобы указать текущую дату и время (снова, интерпретируемые как время начала транзакции). Таким образом, следующие три выражения возвращают одинаковый результат:
SELECT CURRENT_TIMESTAMP; SELECT now(); SELECT TIMESTAMP 'now'; -- but see tip below
Подсказка
Не используйте третью форму при указании значения, которое будет вычислено позже, например, в предложении DEFAULT
для столбца таблицы. Система преобразует now
в timestamp
сразу после разбора константы, так что при необходимости значения по умолчанию будет использоваться время создания таблицы! Первые две формы не будут вычислены до использования значения по умолчанию, потому что они являются вызовами функций. Таким образом, они дадут желаемое поведение по умолчанию - использование времени вставки строки. (См. также Раздел 8.5.1.4).
9.9.6. Задержка выполнения #
Следующие функции доступны для отложенного выполнения процесса сервера:
pg_sleep (double precision
) pg_sleep_for (interval
) pg_sleep_until (timestamp with time zone
)
pg_sleep
делает процесс текущей сессии спать до тех пор, пока не пройдет указанное количество секунд. Можно указывать задержки с долей секунды.
pg_sleep_for
- это удобная функция, которая позволяет указывать время сна в виде interval
.
pg_sleep_until
- это удобная функция, когда требуется указать конкретное время пробуждения.
Например:
SELECT pg_sleep(1.5); SELECT pg_sleep_for('5 minutes'); SELECT pg_sleep_until('tomorrow 03:00');
Примечание
Эффективное разрешение интервала сна зависит от платформы; обычное значение составляет 0,01 секунды. Задержка сна будет не меньше указанного значения. Она может быть больше в зависимости от таких факторов, как загрузка сервера. В частности, функция pg_sleep_until
не гарантирует точное пробуждение в указанное время, но она не пробудится раньше.
Предупреждение
Убедитесь, что ваша сессия не удерживает больше блокировок, чем необходимо, при вызове функции pg_sleep
или ее вариантов. В противном случае, другие сессии могут быть вынуждены ждать вашего спящего процесса, что замедлит работу всей системы.