6.2.2.2 Типы данных DATETIME
, DATE
и TIMESTAMP
Типы DATETIME
, DATE
и TIMESTAMP
являются родственными типами данных. В
данном разделе описаны их свойства, общие черты и различия.
Тип данных DATETIME
используется для величин, содержащих информацию как о
дате, так и о времени. MySQL извлекает и выводит величины DATETIME
в
формате 'YYYY-MM-DD HH:MM:SS'
. Поддерживается диапазон величин от
'1000-01-01 00:00:00'
до '9999-12-31 23:59:59'
. (''поддерживается''
означает, что хотя величины с более ранними временными значениями,
возможно, тоже будут работать, но нет гарантии того, что они будут
правильно храниться и отображаться).
Тип DATE
используется для величин с информацией только о дате, без части,
содержащей время. MySQL извлекает и выводит величины DATE
в формате
'YYYY-MM-DD'
. Поддерживается диапазон величин от '1000-01-01'
до
'9999-12-31'
.
Тип столбца TIMESTAMP
обеспечивает тип представления данных, который можно
использовать для автоматической записи текущих даты и времени при
выполнении операций INSERT
или UPDATE
. При наличии нескольких столбцов
типа TIMESTAMP
только первый из них обновляется автоматически.
Автоматическое обновление первого столбца с типом TIMESTAMP
происходит при
выполнении любого из следующих условий:
-
Столбец не указан явно в команде
INSERT
или LOAD DATA INFILE
.
-
Столбец не указан явно в команде
UPDATE
, и при этом изменяется
величина в некотором другом столбце (следует отметить, что команда
UPDATE
, устанавливающая столбец в то же самое значение, которое было
до выполнения команды, не вызовет обновления столбца TIMESTAMP
,
поскольку в целях повышения производительности MySQL игнорирует
подобные обновления при установке столбца в его текущее значение).
-
Величина в столбце
TIMESTAMP
явно установлена в NULL
.
Для остальных (кроме первого) столбцов типа TIMESTAMP
также можно задать
установку в значение текущих даты и времени. Для этого необходимо просто
установить столбец в NULL
или в NOW()
.
Любой столбец типа TIMESTAMP
(даже первый столбец данного типа) можно
установить в значение, отличное от текущих даты и времени. Это делается
путем явной установки его в желаемое значение. Данное свойство можно
использовать, например, если необходимо установить столбец TIMESTAMP
в
значение текущих даты и времени при создании строки, а при последующем
обновлении этой строки значение столбца не должно изменяться:
-
Пусть MySQL автоматически установит значение столбца с типом
TIMESTAMP
при создании данной строки. Столбец будет установлен в исходное
состояние со значением текущих даты и времени.
-
При выполнении последующих обновлений других столбцов в данной строке
необходимо явно установить столбец
TIMESTAMP
в его текущее значение.
Однако, с другой стороны, для этих целей, возможно, будет проще
использовать столбец DATETIME
. При создании строки его следует
инициализировать функцией NOW()
и оставить в покое при последующих
обновлениях.
Величины типа TIMESTAMP
могут принимать значения от начала 1970
года до
некоторого значения в 2037
году с разрешением в одну секунду. Эти величины
выводятся в виде числовых значений.
Формат данных, в котором MySQL извлекает и показывает величины TIMESTAMP
,
зависит от количества показываемых символов. Это проиллюстрировано в
приведенной ниже таблице. Полный формат TIMESTAMP
составляет 14 десятичных
разрядов, но можно создавать столбцы типа TIMESTAMP
и с более короткой
строкой вывода:
Тип столбца | Формат вывода
|
TIMESTAMP(14) | YYYYMMDDHHMMSS
|
TIMESTAMP(12) | YYMMDDHHMMSS
|
TIMESTAMP(10) | YYMMDDHHMM
|
TIMESTAMP(8) | YYYYMMDD
|
TIMESTAMP(6) | YYMMDD
|
TIMESTAMP(4) | YYMM
|
TIMESTAMP(2) | YY
|
Независимо от размера выводимого значения размер данных, хранящихся в
столбцах типа TIMESTAMP
, всегда один и тот же. Чаще всего используется
формат вывода с 6, 8, 12 или 14 десятичными знаками. При создании таблицы
можно указать произвольный размер выводимых значений, однако если этот
размер задать равным 0 или превышающим 14, то будет использоваться
значение 14. Нечетные значения размеров в интервале от 1 до 13 будут
приведены к ближайшему большему четному числу.
Величины DATETIME
, DATE
и TIMESTAMP
могут быть заданы любым стандартным
набором форматов:
-
Как строка в формате
'YYYY-MM-DD HH:MM:SS'
или в формате 'YY-MM-DD HH:MM:SS'
.
Допускается ``облегченный'' синтаксис - можно использовать
любой знак пунктуации в качестве разделительного между частями
разделов даты или времени. Например, величины '98-12-31 11:30:45'
,
'98.12.31 11+30+45'
, '98/12/31 11*30*45'
и '98@12@31 11^30^45'
являются эквивалентными.
-
Как строка в формате
'YYYY-MM-DD'
или в формате 'YY-MM-DD'
. Здесь
также допустим ``облегченный'' синтаксис. Например, величины
'98-12-31'
, '98.12.31'
, '98/12/31'
и '98@12@31'
являются
эквивалентными.
-
Как строка без разделительных знаков в формате
'YYYYMMDDHHMMSS'
или в
формате 'YYMMDDHHMMSS'
, при условии, что строка понимается как дата.
Например, величины '19970523091528'
и '970523091528'
можно
интерпретировать как '1997-05-23 09:15:28'
, но величина '971122129015'
является недопустимой (значение раздела минут является абсурдным) и
преобразуется в '0000-00-00 00:00:00'
.
-
Как строка без разделительных знаков в формате
'YYYYMMDD'
или в
формате 'YYMMDD'
, при условии, что строка интерпретируется как дата.
Например, величины '19970523'
и '970523'
можно интерпретировать как
'1997-05-23'
, но величина '971332'
является недопустимой (значения
разделов месяца и дня не имеют смысла) и преобразуется в '0000-00-00'
.
-
Как число в формате
YYYYMMDDHHMMSS
или в формате YYMMDDHHMMSS
, при
условии, что число интерпретируется как дата. Например, величины
19830905132800
и 830905132800
интерпретируются как '1983-09-05 13:28:00'
.
-
Как число в формате
YYYYMMDD
или в формате YYMMDD
, при условии, что
число интерпретируется как дата. Например, величины 19830905
и 830905
интерпретируются как '1983-09-05'
.
-
Как результат выполнения функции, возвращающей величину, приемлемую в
контекстах типов данных
DATETIME
, DATE
или TIMESTAMP
(например,
функции NOW()
или CURRENT_DATE
).
Недопустимые значения величин DATETIME
, DATE или T
IMESTAMP преобразуются в
значение ``ноль'' соответствующего типа величин ('0000-00-00 00:00:00'
,
'0000-00-00'
, или 00000000000000
).
Для величин, представленных как строки, содержащие разделительные знаки
между частями даты, нет необходимости указывать два разряда для значений
месяца или дня, меньших, чем 10
. Так, величина '1979-6-9'
эквивалентна
величине '1979-06-09'
. Аналогично, для величин, представленных как строки,
содержащие разделительные знаки внутри обозначения времени, нет
необходимости указывать два разряда для значений часов, минут или секунд,
меньших, чем 10
. Так,
Величины, определенные как числа, должны иметь 6
, 8
, 12
, или 14
десятичных
разрядов. Предполагается, что число, имеющее 8
или 14
разрядов,
представлено в форматах YYYYMMDD
или YYYYMMDDHHMMSS
соответственно, причем
год указан в первых четырех разрядах. Если же длина числа 6
или 12
разрядов, то предполагаются соответственно форматы YYMMDD
или
YYMMDDHHMMSS
, где год указан в первых двух разрядах. Числа, длина которых
не соответствует ни одному из описанных вариантов, интерпретируются как
дополненные спереди нулями до ближайшей вышеуказанной длины.
Величины, представленные строками без разделительных знаков,
интерпретируются с учетом их длины согласно приведенным далее правилам.
Если длина строки равна 8
или 14
символам, то предполагается, что год
задан первыми четырьмя символами. В противном случае предполагается, что
год задан двумя первыми символами. Строка интерпретируется слева направо,
при этом определяются значения для года, месяца, дня, часов, минут и
секунд для всех представленных в строке разделов. Это означает, что строка
с длиной меньше, чем 6
символов, не может быть использована. Например,
если задать строку вида '9903'
, полагая, что это будет означать март 1999
года, то MySQL внесет в таблицу ``нулевую'' дату. Год и месяц в данной
записи равны 99
и 03
соответственно, но раздел, представляющий день,
пропущен (значение равно нулю), поэтому в целом данная величина не
является достоверным значением даты.
При хранении допустимых величин в столбцах типа TIMESTAMP
используется
полная точность, указанная при их задании, независимо от количества
выводимых символов. Это свойство имеет несколько следствий:
-
Необходимо всегда указывать год, месяц и день даже для типов
TIMESTAMP(4)
или TIMESTAMP(2)
. В противном случае задаваемая величина
не будет допустимым значением даты и будет храниться как 0
.
-
При увеличении ширины узкого столбца
TIMESTAMP
путем использования
команды ALTER TABLE
будет выводиться ранее ``скрытая'' информация.
-
И аналогично, при сужении столбца
TIMESTAMP
хранимая информация не
будет потеряна, если не принимать во внимание, что при выводе
информации будет выдаваться меньше.
-
Хотя величины
TIMESTAMP
хранятся с полной точностью, непосредственно
может работать с этим исходным хранимым значением величины только
функция UNIX_TIMESTAMP()
. Остальные функции оперируют форматированными
значениями извлеченной величины. Это означает, что нельзя использовать
такие функции, как HOUR()
или SECOND()
, пока соответствующая часть
величины TIMESTAMP
не будет включена в ее форматированное значение.
Например, раздел HH
столбца TIMESTAMP
не будет выводиться, пока
количество выводимых символов не станет по меньшей мере равным 10
, так
что попытки использовать HOUR()
для более коротких величин TIMESTAMP
приведут к бессмысленным результатам.
Величины одного типа даты можно в ряде случаев присвоить объекту другого
типа даты. Однако при этом возможны некоторое изменение величины или
потеря информации:
-
Если присвоить значение типа
DATE
объекту DATETIME
или TIMESTAMP
, то в
результирующей величине ``временная'' часть будет установлена в
'00:00:00'
, так как величина DATE
не содержит информации о времени.
-
Если присвоить значение типа
DATE
, DATETIME
или TIMESTAMP
объекту
DATE
, то ``временная'' часть в результирующей величине будет удалена,
так как тип DATE
не включает информацию о времени.
-
Несмотря на то что все величины
DATETIME
, DATE
и TIMESTAMP
могут быть
указаны с использованием одного и того же набора форматов, следует
помнить, что указанные типы имеют разные интервалы допустимых
значений. Например, величины типа TIMESTAMP
не могут иметь значения
даты более ранние, чем относящиеся к 1970
году или более поздние, чем
относящиеся к 2037
году. Это означает, что такая дата, как
'1968-01-01'
, будучи разрешенной для величины типа DATETIME
или DATE
,
недопустима для величины типа TIMESTAMP
и будет преобразована в 0
при
присвоении этому объекту.
Задавая величины даты, следует иметь в виду некоторые ``подводные камни'':
-
Упрощенный формат, который допускается для величин, заданных строками,
может ввести в заблуждение. Например, такая величина, как
'10:11:12'
,
благодаря разделителю `:' могла бы оказаться величиной времени, но,
используемая в контексте даты, она будет интерпретирована как год
'2010-11-12'
. В то же время величина '10:45:15'
будет преобразована в
'0000-00-00'
, так как для месяца значение '45'
недопустимо.
-
Сервер MySQL выполняет только первичную проверку истинности даты: дни
00-31
, месяцы 00-12
, года 1000-9999
. Любая дата вне этого диапазона
преобразуется в 0000-00-00
. Следует отметить, что, тем не менее, при
этом не запрещается хранить неверные даты, такие как 2002-04-31
. Это
позволяет веб-приложениям сохранять данные форм без дополнительной
проверки. Чтобы убедиться в достоверности даты, выполняется проверка в
самом приложении.
-
Величины года, представленные двумя разрядами, допускают неоднозначное
толкование, так как неизвестно столетие. MySQL интерпретирует
двухразрядные величины года по следующим правилам:
-
Величины года в интервале
00-69
преобразуются в 2000-2069
.
-
Величины года в интервале
70-99
преобразуются в 1970-1999
.