Spec-Zone.ru › SQLite

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

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

1. Обзор

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

  1. date(time-value, modifier, modifier, ...)
  2. time(time-value, modifier, modifier, ...)
  3. datetime(time-value, modifier, modifier, ...)
  4. julianday(time-value, modifier, modifier, ...)
  5. unixepoch(time-value, modifier, modifier, ...)
  6. strftime(format, time-value, modifier, modifier, ...)
  7. timediff(time-value, time-value)

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

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

ISO-8601 Текстовая строка, представляющая одно из значений даты и времени ISO 8601, перечисленных в пунктах 1–10 ниже. Пример: '2025-05-29 14:16:00'
Юлианское число Количество дней, включая дробную часть, прошедших с момента -4713-11-24 12:00:00. Пример: 2460825.09444444
Метка времени Unix Количество секунд, включая дробную часть, прошедших с момента 1970-01-01 00:00:00. Пример: 1748528160

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

Функция date() возвращает дату в виде текста в следующем формате: YYYY-MM-DD.

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

Функция datetime() возвращает дату и время в формате YYYY-MM-DD HH:MM:SS или YYYY-MM-DD HH:MM:SS.SSS, если используется модификатор 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 доли секунды: SS.SSS
%F дата ISO 8601: YYYY-MM-DD
%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: HH:MM
%s секунды с 1970-01-01
%S секунды: 00–59
%T время ISO 8601: HH:MM:SS
%U неделя года (00–53) — неделя 01 начинается в первое воскресенье
%u день недели 1–7, где Monday==1
%V неделя года по ISO 8601
%w день недели 0–6, где Sunday==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() разработан так, чтобы быть понятным человеку. Формат имеет вид:

(+|-)YYYY-MM-DD HH:MM:SS.SSS

Эта строка разницы во времени также является допустимым модификатором для других функций даты и времени. Для значений времени 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. YYYY-MM-DD
  2. YYYY-MM-DD HH:MM
  3. YYYY-MM-DD HH:MM:SS
  4. YYYY-MM-DD HH:MM:SS.SSS
  5. YYYY-MM-DDTHH:MM
  6. YYYY-MM-DDTHH:MM:SS
  7. YYYY-MM-DDTHH:MM:SS.SSS
  8. HH:MM
  9. HH:MM:SS
  10. HH:MM:SS.SSS
  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-й может следовать индикатор часового пояса вида "[+-]HH:MM" или просто "Z". Функции даты и времени используют внутри UTC, или «зулусское» время, поэтому суффикс "Z" ни на что не влияет. Любой ненулевой суффикс "HH:MM" вычитается из указанной даты и времени, чтобы вычислить зулусское время. Например, все следующие значения времени эквивалентны:

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 значащими цифрами, но функции даты и времени принимают любое количество цифр, необходимое для представления юлианского числа.

Стандарт ISO-8601 поддерживает множество альтернативных форматов даты и времени, однако SQLite поддерживает только перечисленные выше.

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

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

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

  1. NNN days
  2. NNN hours
  3. NNN minutes
  4. NNN seconds
  5. NNN months
  6. NNN years
  7. ±HH:MM
  8. ±HH:MM:SS
  9. ±HH:MM:SS.SSS
  10. ±YYYY-MM-DD
  11. ±YYYY-MM-DD HH:MM
  12. ±YYYY-MM-DD HH:MM:SS
  13. ±YYYY-MM-DD HH:MM:SS.SSS
  14. ceiling
  15. floor
  16. start of month
  17. start of year
  18. start of day
  19. weekday 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 он необязателен. Изменения применяются слева направо. Сначала год сдвигается на YYYY, затем месяц на 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".

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

Модификатор "weekday" при необходимости сдвигает дату вперёд к ближайшей дате, для которой номер дня недели равен N. Воскресенье — это 0, понедельник — 1 и так далее. Если дата уже приходится на нужный день недели, модификатор "weekday" не изменяет её.

Модификатор "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. Для текстовых значений времени ISO 8601 модификатор 'auto' ничего не меняет. Модификатор "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()). В этом случае вместо значения времени, обычно передаваемого первым аргументом, подразумевается "now". Например, чтобы кратко получить текущее время в секундах с 1970 года с точностью до миллисекунд, можно выполнить:

SELECT unixepoch('subsec');

4. Примеры

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

SELECT date();

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

SELECT date('now','start of month','+1 month','-1 day');

Вычислить дату и время для метки времени 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','start of year','+9 months','weekday 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 поддерживают только один набор правил перехода на летнее время. Vista поддерживает только два набора. Поэтому на этих платформах исторические расчёты перехода на летнее время будут неверными. Например, в США в 2007 году правила перехода на летнее время изменились. Платформы Windows до Vista применяют новые правила 2007 года также ко всем предыдущим годам. Vista справляется несколько лучше и даёт правильные результаты вплоть до 1986 года, когда правила также изменились.

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

Последнее обновление этой страницы: 2026-01-14 14:54:01Z

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

Spec-Zone.ru

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