Spec-Zone.ru › SQLite

Функции даты и времени

Содержание
1. Обзор
2. Значения времени
3. Модификаторы
4. Примеры
5. Ограничения и ошибки

1. Обзор

SQLite поддерживает семь скалярных функций даты и времени следующим образом:

  1. date(значение-времени, модификатор, модификатор, ...)
  2. time(значение-времени, модификатор, модификатор, ...)
  3. datetime(значение-времени, модификатор, модификатор, ...)
  4. julianday(значение-времени, модификатор, модификатор, ...)
  5. unixepoch(значение-времени, модификатор, модификатор, ...)
  6. strftime(формат, значение-времени, модификатор, модификатор, ...)
  7. timediff(значение-времени, значение-времени)

Первые шесть функций даты и времени принимают необязательное значение-времени в качестве аргумента, за которым следуют ноль или более модификаторов. Функция strftime() также принимает строку формата в качестве своего первого аргумента. Функция timediff() принимает ровно два аргумента, которые оба являются значениями-времени.

SQLite не имеет специального типа данных дата/время. Вместо этого значения даты и времени могут храниться в любом из следующих форматов:

ISO-8601 Строка текста, являющаяся значением даты/времени ISO 8601. Пример: '2025-05-29 14:16:00'
Номер дня Джулиана Количество дней, включая дробные дни, с 24:00 по Гринвичу 24 ноября 4713 г. до н. э. Пример: 2460825.09444444
Маркер времени Unix Количество секунд, включая дробные секунды, с момента 1970-01-01 00:00:00. Пример: 1748528160

Эти три формата вместе известны как значения-времени. Все функции даты и времени принимают значения-времени в виде текста ISO-8601 или в виде номера дня Джулиана. Их также можно настроить на прием маркеров времени Unix, добавив необязательные аргументы-модификаторы 'auto' или 'unixepoch'. Поскольку функция timediff() не принимает модификаторы, она может использовать только значения-времени в формате ISO-8601 и номера дня Джулиана.

Функция date() возвращает дату в текстовом формате: ГГГГ-ММ-ДД.

Функция time() возвращает время в формате ЧЧ:ММ:СС или ЧЧ:ММ:СС.СССС, если используется модификатор subsec.

Функция datetime() возвращает дату и время в формате ГГГГ-ММ-ДД ЧЧ:ММ:СС или ГГГГ-ММ-ДД ЧЧ:ММ:СС.СССС, если используется модификатор subsec.

Функция julianday() возвращает номер дня Джулиана — дробное число дней с полудня в Гринвиче 24 ноября 4714 г. до н. э. (пролептический григорианский календарь).

Функция unixepoch() возвращает маркер времени Unix — количество секунд с момента 1970-01-01 00:00:00 UTC. Функция unixepoch() обычно возвращает целое число секунд, но с необязательным модификатором subsec она вернёт дробное число секунд.

Функция strftime() возвращает отформатированную дату в соответствии со строкой формата, указанной в качестве первого аргумента. Строка формата поддерживает наиболее распространённые замены, встречающиеся в функции strftime() стандартной библиотеки C, а также две новые замены, %f и %J. Ниже приведён полный список допустимых замен strftime() на версии 3.46.0 (2024-05-23). Более ранние версии SQLite могут не поддерживать все замены. Если встречена неопределённая или неподдерживаемая замена, результат — NULL.

%d день месяца: 01-31
%e день месяца без ведущего нуля: 1-31
%f дробные секунды: СС.SSS
%F дата в формате ISO 8601: ГГГГ-ММ-ДД
%G год ISO 8601, соответствующий %V
%g двузначный год ISO 8601, соответствующий %V
%H час: 00-24
%I час 12-часовых часов: 01-12
%j день года: 001-366
%J номер дня Джулиана (дробный)
%k час без ведущего нуля: 0-24
%l %I без ведущего нуля: 1-12
%m месяц: 01-12
%M минута: 00-59
%p "AM" или "PM" в зависимости от часа
%P "am" или "pm" в зависимости от часа
%R время в формате ISO 8601: ЧЧ:ММ
%s секунды с 1970-01-01
%S секунды: 00-59
%T время в формате ISO 8601: ЧЧ:ММ:СС
%U неделя года (00-53) — неделя 01 начинается с первой воскресенья
%u день недели 1-7, где понедельник==1
%V неделя года ISO 8601
%w день недели 0-6, где воскресенье==0
%W неделя года (00-53) — неделя 01 начинается с первого понедельника
%Y год: 0000-9999
%% %

Другие функции даты и времени могут быть выражены через strftime():

  
Function


Equivalent strftime() 


 date(...) 

 strftime('%F', ...) 


 time(...) 

 strftime('%T', ...) 


 datetime(...) 

 strftime('%F %T', ...) 


 julianday(...) 

 CAST(strftime('%J', ...) as REAL) 


 unixepoch(...) 

 CAST(strftime('%s', ...) as INT) 

 

Функции date(), time() и datetime() возвращают текст, поэтому их аналоги strftime() точные. Однако функции julianday() и unixepoch() возвращают числовые значения. Их аналоги strftime() возвращают строку, представляющую текстовое представление соответствующего числа.

Основные причины предоставления функций, отличных от strftime(), заключаются в удобстве и эффективности. Функции julianday() и unixepoch() возвращают действительные и целочисленные значения соответственно и не несут затраты на преобразование формата или неточности, возникающие при использовании спецификаторов формата '%J' или '%s' с функцией strftime().

Функция timediff(A,B) возвращает строку, описывающую величину времени, которую необходимо добавить к B, чтобы достичь времени A. Формат результата timediff() предназначен для удобного чтения человеком. Формат:

(+|-)ГГГГ-ММ-ДД ЧЧ:ММ:СС.СССС

Эта строка разницы во времени также является допустимым модификатором для других функций даты/времени. Для значений-времени A и B выполняется следующая инвариантность:

datetime(A) = datetime(B, timediff(A,B))

Длительность месяцев и лет различна. Февраль короче марта. Високосные годы длиннее обычных. Результат timediff() учитывает все это. Функция timediff() предназначена для предоставления дружественного для человека описания временного интервала. Если вам нужно узнать количество дней или секунд между двумя датами A и B, вы всегда можете сделать одно из следующих:

SELECT julianday(B) - julianday(A);
SELECT unixepoch(B) - unixepoch(A);

Функция timediff(A,B) может возвращать одинаковый результат даже для значений A и B, охватывающих разное количество дней — в зависимости от даты начала. Например, оба следующих вызова timediff() возвращают один и тот же результат ("-0000-01-00 00:00:00.000"), хотя первый временной интервал составляет 28 дней, а второй — 31 день:

SELECT timediff('2023-02-15','2023-03-15');
SELECT timediff('2023-03-15','2023-04-15');

Резюме: если вам нужен временной интервал, удобный для чтения человеком, используйте timediff(). Если вам нужна точная разница во времени (в днях или секундах), используйте разницу между двумя вызовами julianday() или unixepoch().

2. Значения времени

Значение времени может быть в любом из следующих форматов, показанных ниже. Значение обычно является строкой, хотя в случае формата 12 оно может быть целым или вещественным числом.

  1. ГГГГ-ММ-ДД
  2. ГГГГ-ММ-ДД ЧЧ:ММ
  3. ГГГГ-ММ-ДД ЧЧ:ММ:СС
  4. ГГГГ-ММ-ДД ЧЧ:ММ:СС.СССС
  5. ГГГГ-ММ-ДДTЧЧ:ММ
  6. ГГГГ-ММ-ДДTЧЧ:ММ:СС
  7. ГГГГ-ММ-ДДTЧЧ:ММ:СС.СССС
  8. ЧЧ:ММ
  9. ЧЧ:ММ:СС
  10. ЧЧ:ММ:СС.СССС
  11. now
  12. DDDDDDDDDD

В форматах 5-7 символ "T" является буквальным символом, разделяющим дату и время, как требуется ISO-8601. Форматы 8-10, указывающие только время, предполагают дату 2000-01-01. Формат 11, строка 'now', преобразуется в текущую дату и время, полученные из метода xCurrentTime объекта sqlite3_vfs, используемого в данный момент. Аргумент 'now' для функций даты и времени всегда возвращает точно такое же значение для нескольких вызовов в рамках одного вызова sqlite3_step(). Используется всемирное координированное время (UTC). Формат 12 — номер дня Джулиана, выраженный как целое или вещественное число. Формат 12 также может интерпретироваться как маркер времени Unix, если за ним немедленно следует модификатор 'auto' или 'unixepoch'.

Форматы 2-10 могут быть дополнительно снабжены индикатором часового пояса в виде "[+-]ЧЧ:ММ" или только "Z". Функции даты и времени используют UTC или "zulu" время внутренне, и поэтому суффикс "Z" является бесполезным. Любой суффикс "ЧЧ:ММ", отличный от нуля, вычитается из указанной даты и времени для вычисления zulu-времени. Например, все следующие значения-времени эквивалентны:

2013-10-07 08:23:19.120
2013-10-07T08:23:19.120Z
2013-10-07 04:23:19.120-04:00
2456572.84952685

В форматах 4, 7 и 10 значение дробных секунд SS.SSS может содержать одну или несколько цифр после десятичной точки. В примерах показаны ровно три цифры, потому что только первые три цифры значимы для результата, но строка ввода может содержать меньше или больше трех цифр, и функции даты/времени все равно будут работать правильно. Аналогично, формат 12 показан с 10 значимыми цифрами, но функции даты/времени действительно примут столько или столько цифр, сколько необходимо для представления числа Джулианского дня.

Во всех функциях, кроме timediff(), значение времени (и все модификаторы) могут быть опушены, в этом случае предполагается значение времени 'сейчас'.

3. Модификаторы

Для всех функций даты/времени, кроме timediff(), аргумент значения времени может быть последован нулем или более модификаторами, которые изменяют дату и/или время. Каждый модификатор представляет собой преобразование, которое применяется к значению времени слева от него. Модификаторы применяются слева направо; порядок важен. Доступные модификаторы следующие.

  1. NNN дней
  2. NNN часов
  3. NNN минут
  4. NNN секунд
  5. NNN месяцев
  6. NNN лет
  7. ±HH:MM
  8. ±HH:MM:SS
  9. ±HH:MM:SS.SSS
  10. ±GGGG-MM-DD
  11. ±GGGG-MM-DD HH:MM
  12. ±GGGG-MM-DD HH:MM:SS
  13. ±GGGG-MM-DD HH:MM:SS.SSS
  14. ceiling
  15. floor
  16. начало месяца
  17. начало года
  18. начало дня
  19. день недели N
  20. unixepoch
  21. julianday
  22. auto
  23. localtime
  24. utc
  25. subsec
  26. subsecond

Первые тринадцать модификаторов (с 1 по 13) добавляют указанное количество времени к дате и времени, указанным аргументами слева от них. Символ 's' в конце названий модификаторов с 1 по 6 является необязательным. Значение NNN может быть любым числом с плавающей точкой, с необязательным префиксом '+' или '-'.

Модификаторы сдвига времени (с 7 по 13) перемещают значение времени на указанное количество лет, месяцев, дней, часов, минут и/или секунд. Инициализирующий знак '+' или '-' требуется для форматов с 10 по 13, но является необязательным для форматов 7, 8 и 9. Изменения применяются слева направо. Сначала год сдвигается на GGGG, затем месяц на MM, а затем день на DD и так далее. Функция timediff(A,B) возвращает сдвиг времени в формате 13, который сдвигает значение времени B в A.

Из-за того, что длина месяца или года меняется от месяца к месяцу, могут возникнуть неоднозначности при сдвиге даты на месяцы и/или годы. Например, какова дата через год после 2024-02-29? Это 2025-02-28 или 2025-03-01? Или какова дата, которая является на два месяца позже 2023-12-31? Это 2024-02-29 или 2024-03-02? Нет единого мнения о том, как разрешить эту неоднозначность, поэтому модификаторы «ceiling» и «floor» (14 и 15) доступны, чтобы программист мог принять решение. Если модификатор после сдвига времени — «ceiling», то любая неоднозначность в дате разрешается выбором более поздней даты. Модификатор «floor» разрешает неоднозначности, выбирая последний день предыдущего месяца. По умолчанию используется поведение «ceiling».

Модификаторы «начало» (с 16 по 18) сдвигают дату назад к началу соответствующего месяца, года или дня.

Модификатор «день недели» сдвигает дату вперед, если необходимо, к следующей дате, где день недели равен N. Воскресенье — 0, понедельник — 1 и так далее. Если дата уже соответствует нужному дню недели, модификатор «день недели» оставляет дату неизменной.

Модификатор «unixepoch» (20) работает только в том случае, если он следует непосредственно за значением времени в формате DDDDDDDDDD. Этот модификатор заставляет интерпретировать DDDDDDDDDD не как число Джулианского дня, как обычно, а как время Unix — количество секунд с 1970 года. Если модификатор «unixepoch» не следует за значением времени в формате DDDDDDDDDD, выражающим количество секунд с 1970 года, или если другие модификаторы отделяют модификатор «unixepoch» от предыдущего значения DDDDDDDDDD, то поведение не определено.

Модификатор «julianday» должен сразу следовать за начальным значением времени, которое должно быть в формате DDDDDDDDD. Любое другое использование модификатора «julianday» является ошибкой и приводит к возвращению значения NULL. Модификатор «julianday» принудительно интерпретирует число значения времени как число Джулианского дня. Поскольку это поведение по умолчанию, модификатор «julianday» почти не является операцией. Единственное различие заключается в том, что добавление «julianday» принудительно применяет формат времени DDDDDDDDD, и возвращается NULL, если используется любой другой формат значения времени.

Модификатор «auto» должен сразу следовать за начальным значением времени. Если значение времени является числовым (формат DDDDDDDDDD), то модификатор «auto» заставляет значение времени интерпретироваться либо как число Джулианского дня, либо как отметка времени Unix, в зависимости от его величины. Если значение находится в диапазоне от 0,0 до 5373484,499999, то оно интерпретируется как число Джулианского дня (соответствующее датам от -4713-11-24 12:00:00 до 9999-12-31 23:59:59 включительно). Для числовых значений, лежащих вне диапазона допустимых чисел Джулианского дня, но внутри диапазона от -210866760000 до 253402300799, модификатор «auto» заставляет значение интерпретироваться как отметка времени Unix. Другие числовые значения находятся вне диапазона и приводят к возврату значения NULL. Модификатор «auto» не имеет эффекта для текстовых значений времени ISO 8601. Модификатор «auto» разработан для работы со значениями времени даже в тех случаях, когда неизвестно, какой формат значения времени хранится в файле базы данных, или в тех случаях, когда один и тот же столбец хранит значения времени в разных форматах в разных строках. Модификатор «auto» автоматически выбирает соответствующий формат. Однако есть некоторая неоднозначность. Отметки времени Unix для первых 63 дней 1970 года будут интерпретироваться как числа Джулианского дня. Модификатор «auto» очень полезен, когда гарантируется, что набор данных не содержит дат в этом диапазоне, но следует избегать его для приложений, которые могут использовать даты в начале 1970 года.

Модификатор «localtime» предполагает, что значение времени слева от него находится в универсальном координированном времени (UTC) и корректирует это значение времени так, чтобы оно было в местном времени. Если «localtime» следует за временем, которое не является UTC, то поведение не определено. Модификатор «utc» — противоположность «localtime». «utc» предполагает, что значение времени слева находится в местном часовом поясе и корректирует это значение времени, чтобы оно находилось в UTC. Если время слева не находится в местном часовом поясе, то результат «utc» не определен.

Модификатор «subsecond» (который может быть сокращен до «subsec») увеличивает разрешение вывода для datetime(), time() и unixepoch(), а также для формата строки «%s» в strftime(). Модификатор «subsecond» не влияет на другие функции даты/времени. Текущая реализация увеличивает разрешение с секунд до миллисекунд, но в будущих версиях SQLite это разрешение может быть увеличено. При использовании «subsec» с datetime() или time(), поле секунд в конце следует за десятичной точкой и одной или несколькими цифрами, показывающими дробные секунды. При использовании «subsec» с unixepoch(), результат — число с плавающей точкой, которое представляет количество секунд и дробных секунд с 1970-01-01. Модификаторы «subsecond» и «subsec» обладают особым свойством, что они могут встречаться в качестве первого аргумента функций даты/времени (или в качестве первого аргумента после строки формата для strftime()). В этом случае значение времени, которое обычно находится в первом аргументе, понимается как «сейчас». Например, короткий способ получить текущее время в секундах с 1970 года с точностью до миллисекунды — сказать:

SELECT unixepoch('subsec');

4. Примеры

Вычислить текущую дату.

SELECT date();

Вычислить последнее число текущего месяца.

SELECT date('now','начало месяца','+1 месяц','-1 день');

Вычислить дату и время, учитывая отметку времени Unix 1092941466.

SELECT datetime(1092941466, 'unixepoch');
SELECT datetime(1092941466, 'auto'); -- Не работает для начала 1970 года!

Вычислить дату и время, учитывая отметку времени Unix 1092941466, и скорректировать для вашего местного часового пояса.

SELECT datetime(1092941466, 'unixepoch', 'localtime');

Вычислить текущую отметку времени Unix.

SELECT unixepoch();
SELECT strftime('%s');

Вычислить количество дней с момента подписания Декларации независимости США.

SELECT julianday('now') - julianday('1776-07-04');

Вычислить количество секунд с определенного момента в 2004 году:

SELECT unixepoch() - unixepoch('2004-01-01 02:34:56');

Вычислить дату первого вторника октября текущего года.

SELECT date('now','начало года','+9 месяцев','день недели 2');

Вычислить время с момента начала эпохи Unix в секундах с миллисекундной точностью:

SELECT (julianday('now') - 2440587.5)*86400.0;
SELECT unixepoch('now','subsec');

Вычислить, сколько лет исполнилось бы Аврааму Линкольну, если бы он был жив сегодня:

SELECT timediff('now','1809-02-12');

5. Ограничения и ошибки

Вычисление местного времени в значительной степени зависит от воли политиков и поэтому сложно получить правильное значение для всех локалей. В этой реализации используется стандартная функция библиотеки C localtime_r() для помощи в вычислении местного времени. Функция C localtime_r() обычно работает только для годов с 1970 по 2037 год. Для дат за пределами этого диапазона SQLite пытается отобразить год на эквивалентный год в этом диапазоне, выполнить вычисление, а затем отобразить год обратно.

Эти функции работают только для дат от 0000-01-01 00:00:00 до 9999-12-31 23:59:59 (числа Джулианского дня с 1721059,5 по 5373484,5). Для дат за пределами этого диапазона результаты работы этих функций не определены.

Неплатформенные платформы Windows, кроме Vista, поддерживают только один набор правил DST. Vista поддерживает только два. Следовательно, на этих платформах исторические вычисления DST будут неправильными. Например, в США в 2007 году правила DST изменились. Неплатформенные платформы Windows применяют новые правила DST 2007 года ко всем предыдущим годам. Vista немного лучше справляется с получением правильных результатов до 1986 года, когда также были изменены правила.

Все внутренние вычисления предполагают использование системы григорианского календаря. Они также предполагают, что каждый день длится ровно 86400 секунд; никакие високосные секунды не учитываются.

Эта страница в последний раз была изменена 24 октября 2024 года в 10:55:33 UTC

SQLite is in the Public Domain.
https://sqlite.org/lang_datefunc.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API