Spec-Zone.ru › MySQL 8.4

11.1.3 Литералы дат и времени

  • Стандартные SQL и ODBC литералы дат и времени

  • Строчные и числовые литералы в контексте дат и времени

Значения дат и времени могут быть представлены в нескольких форматах, таких как строковые значения в кавычках или числа, в зависимости от конкретного типа значения и других факторов. Например, в контекстах, где MySQL ожидает дату, он интерпретирует любое из '2015-07-21', '20150721' и 20150721 как дату.

В этом разделе описаны допустимые форматы литералов дат и времени. Более подробную информацию о типах временных данных, таких как диапазон допустимых значений, см. в Разделе 13.2 «Типы данных дат и времени».

Стандартные SQL и ODBC литералы дат и времени

Стандарт SQL требует, чтобы временные литералы были заданы с использованием ключевого слова типа и строки. Пробел между ключевым словом и строкой является необязательным.

DATE 'str'
TIME 'str'
TIMESTAMP 'str'

MySQL распознает, но, в отличие от стандартного SQL, не требует ключевого слова типа. Приложения, которые должны соответствовать стандарту, должны включать ключевое слово типа для временных литералов.

MySQL также распознает синтаксис ODBC, соответствующий стандартному синтаксису SQL:

{ d 'str' }
{ t 'str' }
{ ts 'str' }

MySQL использует ключевые слова типа и конструкции ODBC для получения значений DATE, TIME и DATETIME соответственно, включая хвостовую дробную часть секунды, если она указана. Синтаксис TIMESTAMP генерирует значение DATETIME в MySQL, так как DATETIME имеет диапазон, который более точно соответствует типу стандартного SQL TIMESTAMP, у которого диапазон годов от 0001 до 9999. (Диапазон лет MySQL TIMESTAMP составляет от 1970 до 2038.)

Строки и числовые литералы в контексте дат и времени

MySQL распознает значения DATE в следующих форматах:

  • В виде строки в формате 'YYYY-MM-DD' или 'YY-MM-DD'. Разрешен, но устаревший, «расслабленный» синтаксис: в качестве разделителя между частями даты можно использовать любой знак препинания. Например, '2012-12-31', '2012/12/31', '2012^12^31' и '2012@12@31' эквивалентны. Использование любого символа, кроме тире (-), в качестве разделителя вызывает предупреждение, как показано здесь:

    mysql> SELECT DATE'2012@12@31';
    +------------------+
    | DATE'2012@12@31' |
    +------------------+
    | 2012-12-31       |
    +------------------+
    1 row in set, 1 warning (0.00 sec)
    
    mysql> SHOW WARNINGS\G
    *************************** 1. row ***************************
      Level: Warning
       Code: 4095
    Message: Delimiter '@' in position 4 in datetime value '2012@12@31' at row 1 is
    deprecated. Prefer the standard '-'.
    1 row in set (0.00 sec)
    
  • В виде строки без разделителей в формате 'YYYYMMDD' или 'YYMMDD', при условии, что строка имеет корректный формат даты. Например, '20070523' и '070523' интерпретируются как '2007-05-23', но '071332' некорректны (имеют бессмысленные части месяца и дня) и преобразуются в '0000-00-00'.

  • В виде числа в формате YYYYMMDD или YYMMDD, при условии, что число имеет корректный формат даты. Например, 19830905 и 830905 интерпретируются как '1983-09-05'.

MySQL распознает значения DATETIME и TIMESTAMP в следующих форматах:

  • В виде строки в формате 'YYYY-MM-DD hh:mm:ss' или 'YY-MM-DD hh:mm:ss'. MySQL также допускает «расслабленный» синтаксис, хотя он устарел: в качестве разделителя между частями даты или времени можно использовать любой знак препинания. Например, '2012-12-31 11:30:45', '2012^12^31 11+30+45', '2012/12/31 11*30*45' и '2012@12@31 11^30^45' эквивалентны. Использование любых символов, кроме тире (-) для части даты и двоеточия (:) для части времени, вызывает предупреждение, как показано здесь:

    mysql> SELECT TIMESTAMP'2012^12^31 11*30*45';
    +--------------------------------+
    | TIMESTAMP'2012^12^31 11*30*45' |
    +--------------------------------+
    | 2012-12-31 11:30:45            |
    +--------------------------------+
    1 row in set, 1 warning (0.00 sec)
    
    mysql> SHOW WARNINGS\G
    *************************** 1. row ***************************
      Level: Warning
       Code: 4095
    Message: Delimiter '^' in position 4 in datetime value '2012^12^31 11*30*45' at
    row 1 is deprecated. Prefer the standard '-'.
    1 row in set (0.00 sec)
    

    Единственным разделителем, распознаваемым между частью даты/времени и частью дробной секунды, является десятичная точка.

    Части даты и времени могут быть разделены T вместо пробела. Например, '2012-12-31 11:30:45' и '2012-12-31T11:30:45' эквивалентны.

    Раньше MySQL поддерживал произвольное количество начальных и конечных пробелов в значениях даты и времени, а также между частями даты и времени в значениях DATETIME и TIMESTAMP. В MySQL 8.4 это поведение устарело, и наличие лишних пробелов вызывает предупреждение, как показано здесь:

    mysql> SELECT TIMESTAMP'2012-12-31   11-30-45';
    +----------------------------------+
    | TIMESTAMP'2012-12-31   11-30-45' |
    +----------------------------------+
    | 2012-12-31 11:30:45              |
    +----------------------------------+
    1 row in set, 1 warning (0.00 sec)
    
    mysql> SHOW WARNINGS\G
    *************************** 1. row ***************************
      Level: Warning
       Code: 4096
    Message: Delimiter ' ' in position 11 in datetime value '2012-12-31   11-30-45'
    at row 1 is superfluous and is deprecated. Please remove.
    1 row in set (0.00 sec)
    

    Предупреждение также выводится, если используются пробелы, отличные от пробела, например так:

    mysql> SELECT TIMESTAMP'2021-06-06
        '> 11:15:25';
    +--------------------------------+
    | TIMESTAMP'2021-06-06
     11:15:25'                       |
    +--------------------------------+
    | 2021-06-06 11:15:25            |
    +--------------------------------+
    1 row in set, 1 warning (0.00 sec)
    
    mysql> SHOW WARNINGS\G
    *************************** 1. row ***************************
      Level: Warning
       Code: 4095
    Message: Delimiter '\n' in position 10 in datetime value '2021-06-06
    11:15:25' at row 1 is deprecated. Prefer the standard ' '.
    1 row in set (0.00 sec)
    

    Поднимается только одно такое предупреждение на временное значение, даже если могут существовать несколько проблем с разделителями, пробелами или обоими одновременно, как показано в следующем ряду операторов:

    mysql> SELECT TIMESTAMP'2012!-12-31  11:30:45';
    +----------------------------------+
    | TIMESTAMP'2012!-12-31  11:30:45' |
    +----------------------------------+
    | 2012-12-31 11:30:45              |
    +----------------------------------+
    1 row in set, 1 warning (0.00 sec)
    
    mysql> SHOW WARNINGS\G
    *************************** 1. row ***************************
      Level: Warning
       Code: 4095
    Message: Delimiter '!' in position 4 in datetime value '2012!-12-31  11:30:45'
    at row 1 is deprecated. Prefer the standard '-'.
    1 row in set (0.00 sec)
    
    mysql> SELECT TIMESTAMP'2012-12-31  11:30:45';
    +---------------------------------+
    | TIMESTAMP'2012-12-31  11:30:45' |
    +---------------------------------+
    | 2012-12-31 11:30:45             |
    +---------------------------------+
    1 row in set, 1 warning (0.00 sec)
    
    mysql> SHOW WARNINGS\G
    *************************** 1. row ***************************
      Level: Warning
       Code: 4096
    Message: Delimiter ' ' in position 11 in datetime value '2012-12-31  11:30:45'
    at row 1 is superfluous and is deprecated. Please remove.
    1 row in set (0.00 sec)
    
    mysql> SELECT TIMESTAMP'2012-12-31 11:30:45';
    +--------------------------------+
    | TIMESTAMP'2012-12-31 11:30:45' |
    +--------------------------------+
    | 2012-12-31 11:30:45            |
    +--------------------------------+
    1 row in set (0.00 sec)
    
  • В виде строки без разделителей в формате 'YYYYMMDDhhmmss' или 'YYMMDDhhmmss', при условии, что строка имеет корректный формат даты. Например, '20070523091528' и '070523091528' интерпретируются как '2007-05-23 09:15:28', но '071122129015' некорректны (имеют бессмысленную часть минуты) и становятся '0000-00-00 00:00:00'.

  • В виде числа в формате YYYYMMDDhhmmss или YYMMDDhhmmss, при условии, что число имеет корректный формат даты. Например, 19830905132800 и 830905132800 интерпретируются как '1983-09-05 13:28:00'.

Значение DATETIME или TIMESTAMP может содержать конечную дробную часть секунды с точностью до микросекунд (6 цифр). Дробная часть всегда должна быть разделена от остальной части времени десятичной точкой; другие разделители дробной части секунды не распознаются. Подробности о поддержке дробных секунд в MySQL см. в разделе 13.2.6, «Дробные секунды во временных значениях».

Даты, содержащие двузначные значения года, неоднозначны, так как век неизвестен. MySQL интерпретирует двузначные значения года по следующим правилам:

  • Значения года в диапазоне 70-99 становятся 1970-1999.

  • Значения года в диапазоне 00-69 становятся 2000-2069.

См. также раздел 13.2.9, «Двузначные годы в датах».

Для значений, заданных в виде строк, включающих разделители частей даты, не нужно указывать две цифры для значений месяца или дня, меньших 10. '2015-6-9' эквивалентно '2015-06-09'. Аналогично, для значений, заданных в виде строк, включающих разделители частей времени, не нужно указывать две цифры для значений часа, минуты или секунды, меньших 10. '2015-10-30 1:2:3' эквивалентно '2015-10-30 01:02:03'.

Значения, заданные в виде чисел, должны иметь длину 6, 8, 12 или 14 цифр. Если число имеет длину 8 или 14 цифр, предполагается, что оно находится в формате YYYYMMDD или YYYYMMDDhhmmss, и год задается первыми 4 цифрами. Если число имеет длину 6 или 12 цифр, предполагается, что оно находится в формате YYMMDD или YYMMDDhhmmss, и год задаётся первыми 2 цифрами. Числа, не соответствующие этим длинам, интерпретируются как дополненные ведущими нулями до ближайшей длины.

Значения, заданные в виде строк без разделителей, интерпретируются в зависимости от их длины. Для строки длиной 8 или 14 символов год предполагается заданным первыми 4 символами. В противном случае год предполагается заданным первыми 2 символами. Строка интерпретируется слева направо для определения значений года, месяца, дня, часа, минуты и секунды, в зависимости от наличия соответствующих частей в строке. Это означает, что вы не должны использовать строки с длиной менее 6 символов. Например, если вы укажете '9903', предполагая, что это март 1999 года, MySQL преобразует его в значение даты «ноль». Это происходит потому, что значения года и месяца равны 99 и 03, но часть дня отсутствует. Однако вы можете явно указать значение нуль для представления отсутствующих частей месяца или дня. Например, чтобы вставить значение '1999-03-00', используйте '990300'.

MySQL распознает значения TIME в следующих форматах:

  • В виде строки в формате 'D hh:mm:ss'. Вы также можете использовать один из следующих «расслабленных» синтаксисов: 'hh:mm:ss', 'hh:mm', 'D hh:mm', 'D hh' или 'ss'. Здесь D представляет дни и может принимать значения от 0 до 34.

  • В виде строки без разделителей в формате 'hhmmss', при условии, что она имеет корректный формат времени. Например, '101112' понимается как '10:11:12', но '109712' некорректна (имеет бессмысленную часть минут) и становится '00:00:00'.

  • В виде числа в формате hhmmss, при условии, что оно имеет корректный формат времени. Например, 101112 понимается как '10:11:12'. Также понимаются следующие альтернативные форматы: ss, mmss или hhmmss.

Дробная часть секунды распознается в форматах времени 'D hh:mm:ss.fraction', 'hh:mm:ss.fraction', 'hhmmss.fraction' и hhmmss.fraction, где fraction - дробная часть с точностью до микросекунд (6 цифр). Дробная часть всегда должна быть разделена от остальной части времени десятичной точкой; другие разделители дробной части секунды не распознаются. Подробности о поддержке дробных секунд в MySQL см. в разделе 13.2.6, «Дробные секунды во временных значениях».

Для значений TIME, заданных в виде строк, включающих разделители частей времени, не нужно указывать две цифры для значений часа, минуты или секунды, меньших 10. '8:3:2' эквивалентно '08:03:02'.

При вставке значений TIMESTAMP и DATETIME в таблицу можно указать смещение часового пояса. Смещение добавляется к части времени литерала datetime без промежуточных пробелов и использует тот же формат, что и для установки системной переменной time_zone, за исключением следующих пунктов:

  • Для значений часов меньше 10 требуется ведущий ноль.

  • Значение '-00:00' отклоняется.

  • Имена часовых поясов, такие как 'EET' и 'Asia/Shanghai', использовать нельзя; 'SYSTEM' также нельзя использовать в этом контексте.

Вставляемое значение не должно содержать ноль для части месяца, части дня или обеих частей. Это выполняется независимо от настройки серверного режима SQL.

В этом примере показано вставка значений datetime с часовыми смещениями в столбцы TIMESTAMP и DATETIME с использованием различных настроек time_zone, а затем их извлечение:

mysql> CREATE TABLE ts (
    ->     id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ->     col TIMESTAMP NOT NULL
    -> ) AUTO_INCREMENT = 1;

mysql> CREATE TABLE dt (
    ->     id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ->     col DATETIME NOT NULL
    -> ) AUTO_INCREMENT = 1;

mysql> SET @@time_zone = 'SYSTEM';

mysql> INSERT INTO ts (col) VALUES ('2020-01-01 10:10:10'),
    ->     ('2020-01-01 10:10:10+05:30'), ('2020-01-01 10:10:10-08:00');

mysql> SET @@time_zone = '+00:00';

mysql> INSERT INTO ts (col) VALUES ('2020-01-01 10:10:10'),
    ->     ('2020-01-01 10:10:10+05:30'), ('2020-01-01 10:10:10-08:00');

mysql> SET @@time_zone = 'SYSTEM';

mysql> INSERT INTO dt (col) VALUES ('2020-01-01 10:10:10'),
    ->     ('2020-01-01 10:10:10+05:30'), ('2020-01-01 10:10:10-08:00');

mysql> SET @@time_zone = '+00:00';

mysql> INSERT INTO dt (col) VALUES ('2020-01-01 10:10:10'),
    ->     ('2020-01-01 10:10:10+05:30'), ('2020-01-01 10:10:10-08:00');

mysql> SET @@time_zone = 'SYSTEM';

mysql> SELECT @@system_time_zone;
+--------------------+
| @@system_time_zone |
+--------------------+
| EST                |
+--------------------+

mysql> SELECT col, UNIX_TIMESTAMP(col) FROM dt ORDER BY id;
+---------------------+---------------------+
| col                 | UNIX_TIMESTAMP(col) |
+---------------------+---------------------+
| 2020-01-01 10:10:10 |          1577891410 |
| 2019-12-31 23:40:10 |          1577853610 |
| 2020-01-01 13:10:10 |          1577902210 |
| 2020-01-01 10:10:10 |          1577891410 |
| 2020-01-01 04:40:10 |          1577871610 |
| 2020-01-01 18:10:10 |          1577920210 |
+---------------------+---------------------+

mysql> SELECT col, UNIX_TIMESTAMP(col) FROM ts ORDER BY id;
+---------------------+---------------------+
| col                 | UNIX_TIMESTAMP(col) |
+---------------------+---------------------+
| 2020-01-01 10:10:10 |          1577891410 |
| 2019-12-31 23:40:10 |          1577853610 |
| 2020-01-01 13:10:10 |          1577902210 |
| 2020-01-01 05:10:10 |          1577873410 |
| 2019-12-31 23:40:10 |          1577853610 |
| 2020-01-01 13:10:10 |          1577902210 |
+---------------------+---------------------+

Смещение не отображается при выборке значения datetime, даже если оно использовалось при его вставке.

Диапазон поддерживаемых значений смещения составляет от -13:59 до +14:00 включительно.

Литералы datetime, включающие часовые смещения, принимаются в качестве значений параметров подготовленными операторами.

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-8.4-en/date-and-time-literals.html

Spec-Zone.ru

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