DATETIME, DATE, and TIMESTAMP Types
TIME Type
YEAR Type
DATETIME, DATE, and TIMESTAMP Types
The DATETIME, DATE, and TIMESTAMP types are related.
This section describes their characteristics, how they are similar, and how
they differ.
The DATETIME type is used when you need values that contain both date
and time information.  MySQL retrieves and displays DATETIME
values in 'YYYY-MM-DD HH:MM:SS' format.  The supported range is
'1000-01-01 00:00:00' to '9999-12-31 23:59:59'.  (``Supported''
means that although earlier values might work, there is no guarantee that
they will.)
The DATE type is used when you need only a date value, without a time
part.  MySQL retrieves and displays DATE values in
'YYYY-MM-DD' format.  The supported range is '1000-01-01' to
'9999-12-31'.
The TIMESTAMP column type provides a type that you can use to
automatically mark INSERT or UPDATE operations with the current
date and time.  If you have multiple TIMESTAMP columns, only the first
one is updated automatically.
Automatic updating of the first TIMESTAMP column occurs under any of
the following conditions:
INSERT or
LOAD DATA INFILE statement.
UPDATE statement and some
other column changes value.  (Note that an UPDATE that sets a column
to the value it already has will not cause the TIMESTAMP column to be
updated, because if you set a column to its current value, MySQL
ignores the update for efficiency.)
TIMESTAMP column to NULL.
TIMESTAMP columns other than the first may also be set to the current
date and time.  Just set the column to NULL or to NOW().
You can set any TIMESTAMP column to a value different from the current
date and time by setting it explicitly to the desired value.  This is true
even for the first TIMESTAMP column.  You can use this property if,
for example, you want a TIMESTAMP to be set to the current date and
time when you create a row, but not to be changed whenever the row is updated
later:
TIMESTAMP column explicitly to its current value.
On the other hand, you may find it just as easy to use a DATETIME
column that you initialise to NOW() when the row is created and
leave alone for subsequent updates.
TIMESTAMP values may range from the beginning of 1970 to sometime in
the year 2037, with a resolution of one second.  Values are displayed as
numbers.
The format in which MySQL retrieves and displays TIMESTAMP
values depends on the display size, as illustrated by the following table.  The
`full' TIMESTAMP format is 14 digits, but TIMESTAMP columns may
be created with shorter display sizes:
| Column type | Display format | 
TIMESTAMP(14)  |  YYYYMMDDHHMMSS
 | 
TIMESTAMP(12)  |  YYMMDDHHMMSS
 | 
TIMESTAMP(10)  |  YYMMDDHHMM
 | 
TIMESTAMP(8)  |  YYYYMMDD
 | 
TIMESTAMP(6)  |  YYMMDD
 | 
TIMESTAMP(4)  |  YYMM
 | 
TIMESTAMP(2)  |  YY
 | 
All TIMESTAMP columns have the same storage size, regardless of
display size.  The most common display sizes are 6, 8, 12, and 14.  You can
specify an arbitrary display size at table creation time, but values of 0 or
greater than 14 are coerced to 14.  Odd-valued sizes in the range from 1 to
13 are coerced to the next higher even number.
Note: From version 4.1, TIMESTAMP is returned as a string with
the format 'YYYY-MM-DD HH:MM:SS' and different timestamp lengths are
no longer supported.
You can specify DATETIME, DATE, and TIMESTAMP values using
any of a common set of formats:
'YYYY-MM-DD HH:MM:SS' or 'YY-MM-DD
HH:MM:SS' format.  A ``relaxed'' syntax is allowed--any punctuation
character may be used as the delimiter between date parts or time parts.
For example, '98-12-31 11:30:45', '98.12.31 11+30+45',
'98/12/31 11*30*45', and '98@12@31 11^30^45' are
equivalent.
'YYYY-MM-DD' or 'YY-MM-DD' format.
A ``relaxed'' syntax is allowed here, too.  For example, '98-12-31',
'98.12.31', '98/12/31', and '98@12@31' are
equivalent.
'YYYYMMDDHHMMSS' or
'YYMMDDHHMMSS' format, provided that the string makes sense as a
date.  For example, '19970523091528' and '970523091528' are
interpreted as '1997-05-23 09:15:28', but '971122129015' is
illegal (it has a nonsensical minute part) and becomes '0000-00-00
00:00:00'.
'YYYYMMDD' or 'YYMMDD'
format, provided that the string makes sense as a date.  For example,
'19970523' and '970523' are interpreted as
'1997-05-23', but '971332' is illegal (it has nonsensical month
and day parts) and becomes '0000-00-00'.
YYYYMMDDHHMMSS or YYMMDDHHMMSS
format, provided that the number makes sense as a date.  For example,
19830905132800 and 830905132800 are interpreted as
'1983-09-05 13:28:00'.
YYYYMMDD or YYMMDD
format, provided that the number makes sense as a date.  For example,
19830905 and 830905 are interpreted as '1983-09-05'.
DATETIME, DATE, or TIMESTAMP context, such as
NOW() or CURRENT_DATE.
Illegal DATETIME, DATE, or TIMESTAMP values are converted
to the ``zero'' value of the appropriate type ('0000-00-00 00:00:00',
'0000-00-00', or 00000000000000).
For values specified as strings that include date part delimiters, it is not
necessary to specify two digits for month or day values that are less than
10.  '1979-6-9' is the same as '1979-06-09'.  Similarly,
for values specified as strings that include time part delimiters, it is not
necessary to specify two digits for hour, minute, or second values that are
less than 10.  '1979-10-30 1:2:3' is the same as
'1979-10-30 01:02:03'.
Values specified as numbers should be 6, 8, 12, or 14 digits long.  If the
number is 8 or 14 digits long, it is assumed to be in YYYYMMDD or
YYYYMMDDHHMMSS format and that the year is given by the first 4
digits.  If the number is 6 or 12 digits long, it is assumed to be in
YYMMDD or YYMMDDHHMMSS format and that the year is given by the
first 2 digits.  Numbers that are not one of these lengths are interpreted
as though padded with leading zeros to the closest length.
Values specified as non-delimited strings are interpreted using their length
as given.  If the string is 8 or 14 characters long, the year is assumed to
be given by the first 4 characters.  Otherwise, the year is assumed to be
given by the first 2 characters.  The string is interpreted from left to
right to find year, month, day, hour, minute, and second values, for as many
parts as are present in the string.  This means you should not use strings
that have fewer than 6 characters.  For example, if you specify '9903',
thinking that will represent March, 1999, you will find that MySQL
inserts a ``zero'' date into your table.  This is because the year and month
values are 99 and 03, but the day part is missing (zero), so
the value is not a legal date.
TIMESTAMP columns store legal values using the full precision with
which the value was specified, regardless of the display size.  This has
several implications:
TIMESTAMP(4) or TIMESTAMP(2).  Otherwise, the value will not
be a legal date and 0 will be stored.
ALTER TABLE to widen a narrow TIMESTAMP column,
information will be displayed that previously was ``hidden''.
TIMESTAMP column does not cause information to
be lost, except in the sense that less information is shown when the values
are displayed.
TIMESTAMP values are stored to full precision, the only
function that operates directly on the underlying stored value is
UNIX_TIMESTAMP().  Other functions operate on the formatted retrieved
value.  This means you cannot use functions such as HOUR() or
SECOND() unless the relevant part of the TIMESTAMP value is
included in the formatted value.  For example, the HH part of a
TIMESTAMP column is not displayed unless the display size is at least
10, so trying to use HOUR() on shorter TIMESTAMP values
produces a meaningless result.
You can to some extent assign values of one date type to an object of a different date type. However, there may be some alteration of the value or loss of information:
DATE value to a DATETIME or TIMESTAMP
object, the time part of the resulting value is set to '00:00:00',
because the DATE value contains no time information.
DATETIME or TIMESTAMP value to a DATE
object, the time part of the resulting value is deleted, because the
DATE type stores no time information.
DATETIME, DATE, and TIMESTAMP
values all can be specified using the same set of formats, the types do not
all have the same range of values.  For example, TIMESTAMP values
cannot be earlier than 1970 or later than 2037.  This means
that a date such as '1968-01-01', while legal as a DATETIME or
DATE value, is not a valid TIMESTAMP value and will be
converted to 0 if assigned to such an object.
Be aware of certain pitfalls when specifying date values:
'10:11:12' might look like a time value
because of the `:' delimiter, but if used in a date context will be
interpreted as the year '2010-11-12'.  The value '10:45:15'
will be converted to '0000-00-00' because '45' is not a legal
month.
00-31, months 00-12, years 1000-9999.
Any date not within this range will revert to 0000-00-00.
Please note that this still allows you to store invalid dates such as
2002-04-31. It allows web applications to store data from a form
without further checking. To ensure a date is valid, perform a check in
your application.
00-69 are converted to 2000-2069.
70-99 are converted to 1970-1999.
| Posted by djresonance on Friday May 17 2002, @6:24am | [Delete] [Edit] | 
To get a MySQL compatible DATETIME string with 
php, use the following: 
$datetime = date("Y-m-d H:i:s");
| Posted by Fredrik Johansson on Friday 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 Ellert van Koperen on Friday May 17 2002, @6:24am | [Delete] [Edit] | 
A way to display a Timestamp as a normal date-
time, assuming that datetime is the Timestamp 
field:
select DATE_FORMAT(datetime, \'%Y-%m-%d %T\') 
from some_table
| Posted by Jacqui Caren on Wednesday December 18 2002, @5:28pm | [Delete] [Edit] | 
A first reading of this page makes me seriously
worried about the implied lack of design.
Knowning just how dangerous bad date parsing can 
be the ability to 
<UL>
<LI>convert 2002122 to 02002122
<LI>tale a HH::MM::SS string and parse as date
>br><I>(ignore seperators values)</I>
</UL>
can only be deacribed as dangerous.
It would be far more advisable to have a stricter
date format parser and allow date and time formats
to be set system wide (default), per databasse and 
then per session.
I am a critic of the brain dead SQLServer but even 
this has broken but better (less dangerous) date 
parsing rules that this.
| Posted by Andrius Juozapaitis on Monday November 18 2002, @4:22pm | [Delete] [Edit] | 
2 pitfalls I've encountered with mysql timestamps:
1) timestamp in mysql differs from the unix-
timestamp in php. 
2) this automatic-update-one-but-not-the-other 
column sounds, and actually is, scary. and it's not 
intuitive too - I was figthing with all types of weird 
behaviour until I found this manual here ;-). my 
suggestion - use datetime with now() instead. 
| Posted by PJ Kix on Thursday December 5 2002, @4:09am | [Delete] [Edit] | 
if you need to use an UPDATE query but don't want 
your timestamp columns to be automagically 
updated as well just be sure to set them to 
themselves in the SQL statement like so ...
UPDATE `table` SET `views` = `views`+1 , 
`timestamp` = `timestamp` WHERE `row_id` 
= "242"
that way the the updates will take place but the 
timestamps will not update themselves. 
Hope it helps someone.
-=PJK=-
| Posted by Sanie Mohd on Tuesday February 18 2003, @1:12am | [Delete] [Edit] | 
I would prefer if the value for this types of fields (date, datetime,timestamp,etc) is invalid, do not insert it at all, prompt the ERROR instead, like any other type. Because it at least will prompt user that there is an error occured. If not, user will assuming the entry is valid. I've a occasion (since I'm new in this MySQL) related to this where I'm assuming the entry is exactly valid. Friends of mine also who start to working with MySQL facing the same problem.
| Posted by [name withheld] on Sunday February 23 2003, @4:21pm | [Delete] [Edit] | 
I realy wish timezone would be stored with the time values!
| Posted by Timo Salmi on Monday 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 Roland Moriz on Friday March 28 2003, @6:18am | [Delete] [Edit] | 
A "Datetime" Solution for Perl:
use POSIX qw(strftime);
$datetime = strftime "%Y-%m-%d %H:%M:%S", localtime;
| Posted by Mal McKee on Monday April 14 2003, @1:22am | [Delete] [Edit] | 
Hmm I'm just after readin that this is nor the place to post questions.  So I shall convert my query to the form of a suggestion...
I would suggest that, to convert local server time to your timezone, that you add the relevant number of hours to the query.  For example, my server is located eight hours behind (although its nine during British Summer Time!).  So add this difference somehow to your relevant table.  It would probably be in the form of seconds.. so 8 hoursn would amount to 28,800 seconds.
Now .. if only I knew where I should put this adjustment...  anyone got any ideas..? ;)
| Posted by Joao Avelino on Monday May 5 2003, @9:16am | [Delete] [Edit] | 
Hi.
I have a variable wich calls an atomic clock to get the precise date and time. I am able to "separate" the values and create 3 variables (vbscript asp), one for the year, one for the month and one for the day. I want to put it all together in a way that I can use it in a sql string and compare it with a Date field in my db.
First problem: Joining this 3 variables in a way that mysql string will recognize it as a date so I can make correct queries.
Second problem: If I can solve first problem, adding a integer number to the field "Date" with a value 2003-05-05 will turn it into 2003-05-10? Like (2003-05-05)+5=2003-05-10?
Third problem: If there's no problem with Second Problem, if I add 5 days (using date field+5) to day 2003-05-28, assuming that the month has 31 days, will I get 2003-06-02?
I know this is not the place to ask questions, but I wasn´t able to find an answer yet. I have a urgent situation. I'm making a online newspaper, and it's very hard to find documentation. I did find it at msdn, but it didn't cover pratical ways to use and get dates and that's of crucial importance to have a fully automated online newspaper (timings for articles and pub, expiration dates, etc). Sorry again, but i'm kind of desperate.
Thank you.
| Posted by Bob Johnson on Monday May 5 2003, @9:46am | [Delete] [Edit] | 
RE: to Joao Avelino
1) I don't know the exact VBScript syntax, but couldn't you say something to the effect of:
DIM date = year + "-" + month + "-" + day
DIM sql = "SELECT date FROM database WHERE date = \'" + date + "\';"
Then run the query with Connection.executeQuery(sql);
2) MySql supports date calculations (See section 3.3.4.5)
UPDATE db SET
date = DATE_ADD(date, INTERVAL 5 DAY)
WHERE your conditions;
3) MySql wraps the end of the month as well as the end of the year and Leap years correctly.
Hope this helps in time.
| Posted by jeppe on Wednesday 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 Adam Laiacano on Thursday May 15 2003, @9:43am | [Delete] [Edit] | 
Hello,
I'm trying to query fields that have been added within the last given amount of days.  I have the query part all set, I just need to create a date that's the given number of days before the current one.  For example, today is 2003-05-15, and I need to create or calculate the date 20 days ago as being 2003-04-25.  Any help is appreciated.
-Adam
| Posted by jane leung on Monday July 21 2003, @1:27am | [Delete] [Edit] | 
To Adam Laiacano: 
You can try 
select date_sub('2003-05-15', interval 20 day)
Hope this help!
jane