Search the MySQL manual:
Subscribe to the monthly
MySQL Newsletter!

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 происходит при выполнении любого из следующих условий:

Для остальных (кроме первого) столбцов типа TIMESTAMP также можно задать установку в значение текущих даты и времени. Для этого необходимо просто установить столбец в NULL или в NOW().

Любой столбец типа 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 могут быть заданы любым стандартным набором форматов:

Недопустимые значения величин DATETIME, DATE или TIMESTAMP преобразуются в значение ``ноль'' соответствующего типа величин ('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 используется полная точность, указанная при их задании, независимо от количества выводимых символов. Это свойство имеет несколько следствий:

Величины одного типа даты можно в ряде случаев присвоить объекту другого типа даты. Однако при этом возможны некоторое изменение величины или потеря информации:

Задавая величины даты, следует иметь в виду некоторые ``подводные камни'':

User Comments

Posted by Fredrik Johansson on May 17 2002 6:24am[Delete] [Edit]

Usually I don't want to make the timestamp string
in php and then query it to the db as many people
seem to do, then its better to do a "insert into
db values(now(),'otherstuff');" for a perfect fitting

Posted by Timo Salmi on March 17 2003 4:22am[Delete] [Edit]

Be careful when adding indexes to TIMESTAMP columns. The UNIX_TIMESTAMP(timestamp) must be at least 0 to make queries work. This example is for Finland (UTC+2)

mysql> CREATE TABLE test (ts TIMESTAMP);

mysql> INSERT INTO test SET ts=NOW();
mysql> INSERT INTO test SET ts=NOW();

mysql> SELECT * FROM test WHERE ts>=19700101000000;

+----------------+
| ts |
+----------------+
| 20030317135755 |
| 20030317135755 |
+----------------+
2 rows in set (0.01 sec)

mysql> ALTER TABLE test ADD INDEX ts_index (ts);

mysql> SELECT * FROM test WHERE ts>=19700101000000;
Empty set (0.00 sec)

mysql> SELECT * FROM test WHERE ts>=19700101020000;
+----------------+
| ts |
+----------------+
| 20030317135755 |
| 20030317135755 |
+----------------+
2 rows in set (0.01 sec)

This is because:

mysql> SELECT UNIX_TIMESTAMP(19700101000000),FROM_UNIXTIME(0)+0;
+--------------------------------+--------------------+
| UNIX_TIMESTAMP(19700101000000) | FROM_UNIXTIME(0)+0 |
+--------------------------------+--------------------+
| -7200 | 19700101020000 |
+--------------------------------+--------------------+
1 row in set (0.00 sec)

However, with or without index this will work:

mysql> SELECT * FROM test WHERE ts>=FROM_UNIXTIME(0);
+----------------+
| ts |
+----------------+
| 20030317135755 |
| 20030317135755 |
+----------------+
2 rows in set (0.01 sec)

Posted by [name withheld] on May 7 2003 7:45am[Delete] [Edit]

A quick tip: if you have two timestamps or datetimes, you can calculate the interval in seconds like this

select (unix_timestamp(updated) - unix_timetamp(created) as diff

Posted by markus diersbock on November 4 2003 3:01am[Delete] [Edit]

When using timestamps, grab the date and time from the mySQL functions (ei. now()) rather than passing them as args from the calling app like your webpage. The main reason for this is that your webserver and DB might be on different servers and may even be in different timezones.

Posted by buzzy on January 15 2004 8:29am[Delete] [Edit]

Should there be some discussion of permissible default values here?

Posted by Dalit Dalidad on January 18 2004 3:07pm[Delete] [Edit]

Yeah how about the default options on the datetime field ?

Posted by [name withheld] on March 4 2004 10:29am[Delete] [Edit]

Yep, it would be nice to have what MS SQL Server has, the "macro" defaults.

Example: an give column can have it's default value of now() or date_format(now(), '%Y') or whatever... even though now() is the most needed ( getDate() in MS SQL ).

-Marcus
www.free-lancers.biz
http://www.free-lancers.biz (mysql powered, as usual)

Posted by Nathan Hall on March 14 2004 4:55pm[Delete] [Edit]

Concerning the finite timespan on the TIMESTAMP type:

I always liked the formatting of the TIMESTAMP however the year 2037 will be here in a few years then once again the rush to correct bugs will come about again like y2k. I perfer to create my own time_stamp function when working with mysql & php. By using a varchar(14) I can create a text representation of the numeric TIMESTAMP type. This text version allows for dates upto the year 9999. (By then we will have moved on to better technologies for data manipulation :) ) The DATETIME type allows for this functionality however the formating is not what I have desired. Anyway, if anything...food for thought!

Nathan Hall
8networks, Inc.
nate( at )8networks.com

Add your own comment.