14.7 Date and Time Functions (original) (raw)

This section describes the functions that can be used to manipulate temporal values. SeeSection 13.2, “Date and Time Data Types”, for a description of the range of values each date and time type has and the valid formats in which values may be specified.

Table 14.11 Date and Time Functions

Name Description
ADDDATE() Add time values (intervals) to a date value
ADDTIME() Add time
CONVERT_TZ() Convert from one time zone to another
CURDATE() Return the current date
CURRENT_DATE(), CURRENT_DATE Synonyms for CURDATE()
CURRENT_TIME(), CURRENT_TIME Synonyms for CURTIME()
CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP Synonyms for NOW()
CURTIME() Return the current time
DATE() Extract the date part of a date or datetime expression
DATE_ADD() Add time values (intervals) to a date value
DATE_FORMAT() Format date as specified
DATE_SUB() Subtract a time value (interval) from a date
DATEDIFF() Subtract two dates
DAY() Synonym for DAYOFMONTH()
DAYNAME() Return the name of the weekday
DAYOFMONTH() Return the day of the month (0-31)
DAYOFWEEK() Return the weekday index of the argument
DAYOFYEAR() Return the day of the year (1-366)
EXTRACT() Extract part of a date
FROM_DAYS() Convert a day number to a date
FROM_UNIXTIME() Format Unix timestamp as a date
GET_FORMAT() Return a date format string
HOUR() Extract the hour
LAST_DAY Return the last day of the month for the argument
LOCALTIME(), LOCALTIME Synonym for NOW()
LOCALTIMESTAMP, LOCALTIMESTAMP() Synonym for NOW()
MAKEDATE() Create a date from the year and day of year
MAKETIME() Create time from hour, minute, second
MICROSECOND() Return the microseconds from argument
MINUTE() Return the minute from the argument
MONTH() Return the month from the date passed
MONTHNAME() Return the name of the month
NOW() Return the current date and time
PERIOD_ADD() Add a period to a year-month
PERIOD_DIFF() Return the number of months between periods
QUARTER() Return the quarter from a date argument
SEC_TO_TIME() Converts seconds to 'hh:mm:ss' format
SECOND() Return the second (0-59)
STR_TO_DATE() Convert a string to a date
SUBDATE() Synonym for DATE_SUB() when invoked with three arguments
SUBTIME() Subtract times
SYSDATE() Return the time at which the function executes
TIME() Extract the time portion of the expression passed
TIME_FORMAT() Format as time
TIME_TO_SEC() Return the argument converted to seconds
TIMEDIFF() Subtract time
TIMESTAMP() With a single argument, this function returns the date or datetime expression; with two arguments, the sum of the arguments
TIMESTAMPADD() Add an interval to a datetime expression
TIMESTAMPDIFF() Return the difference of two datetime expressions, using the units specified
TO_DAYS() Return the date argument converted to days
TO_SECONDS() Return the date or datetime argument converted to seconds since Year 0
UNIX_TIMESTAMP() Return a Unix timestamp
UTC_DATE() Return the current UTC date
UTC_TIME() Return the current UTC time
UTC_TIMESTAMP() Return the current UTC date and time
WEEK() Return the week number
WEEKDAY() Return the weekday index
WEEKOFYEAR() Return the calendar week of the date (1-53)
YEAR() Return the year
YEARWEEK() Return the year and week

Here is an example that uses date functions. The following query selects all rows with a datecol value from within the last 30 days:

mysql> SELECT something FROM tbl_name
    -> WHERE DATE_SUB(CURDATE(),INTERVAL 30 DAY) <= date_col;

The query also selects rows with dates that lie in the future.

Functions that expect date values usually accept datetime values and ignore the time part. Functions that expect time values usually accept datetime values and ignore the date part.

Functions that return the current date or time each are evaluated only once per query at the start of query execution. This means that multiple references to a function such asNOW() within a single query always produce the same result. (For our purposes, a single query also includes a call to a stored program (stored routine, trigger, or event) and all subprograms called by that program.) This principle also applies to CURDATE(),CURTIME(),UTC_DATE(),UTC_TIME(),UTC_TIMESTAMP(), and to any of their synonyms.

The CURRENT_TIMESTAMP(),CURRENT_TIME(),CURRENT_DATE(), andFROM_UNIXTIME() functions return values in the current session time zone, which is available as the session value of the time_zone system variable. In addition,UNIX_TIMESTAMP() assumes that its argument is a datetime value in the session time zone. SeeSection 7.1.15, “MySQL Server Time Zone Support”.

Some date functions can be used with “zero” dates or incomplete dates such as '2001-11-00', whereas others cannot. Functions that extract parts of dates typically work with incomplete dates and thus can return 0 when you might otherwise expect a nonzero value. For example:

mysql> SELECT DAYOFMONTH('2001-11-00'), MONTH('2005-00-00');
        -> 0, 0

Other functions expect complete dates and returnNULL for incomplete dates. These include functions that perform date arithmetic or that map parts of dates to names. For example:

mysql> SELECT DATE_ADD('2006-05-00',INTERVAL 1 DAY);
        -> NULL
mysql> SELECT DAYNAME('2006-05-00');
        -> NULL

Several functions are strict when passed aDATE() function value as their argument and reject incomplete dates with a day part of zero:CONVERT_TZ(),DATE_ADD(),DATE_SUB(),DAYOFYEAR(),TIMESTAMPDIFF(),TO_DAYS(),TO_SECONDS(),WEEK(),WEEKDAY(),WEEKOFYEAR(),YEARWEEK().

Fractional seconds for TIME,DATETIME, and TIMESTAMP values are supported, with up to microsecond precision. Functions that take temporal arguments accept values with fractional seconds. Return values from temporal functions include fractional seconds as appropriate.

mysql> SELECT DATE_ADD('2008-01-02', INTERVAL 31 DAY);  
        -> '2008-02-02'  
mysql> SELECT ADDDATE('2008-01-02', INTERVAL 31 DAY);  
        -> '2008-02-02'  

When invoked with the days form of the second argument, MySQL treats it as an integer number of days to be added to expr.

mysql> SELECT ADDDATE('2008-01-02', 31);  
        -> '2008-02-02'  

This function returns NULL if_date_ or_days_ is NULL.

mysql> SELECT ADDTIME('2007-12-31 23:59:59.999999', '1 1:1:1.000002');  
        -> '2008-01-02 01:01:01.000001'  
mysql> SELECT ADDTIME('01:00:00.999999', '02:00:00.999998');  
        -> '03:00:01.999997'  
mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','GMT','MET');  
        -> '2004-01-01 13:00:00'  
mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00');  
        -> '2004-01-01 22:00:00'  
mysql> SELECT CURDATE();  
        -> '2008-06-13'  
mysql> SELECT CURDATE() + 0;  
        -> 20080613  
mysql> SELECT CURTIME();  
+-----------+  
| CURTIME() |  
+-----------+  
| 19:25:37  |  
+-----------+  
mysql> SELECT CURTIME() + 0;  
+---------------+  
| CURTIME() + 0 |  
+---------------+  
|        192537 |  
+---------------+  
mysql> SELECT CURTIME(3);  
+--------------+  
| CURTIME(3)   |  
+--------------+  
| 19:25:37.840 |  
+--------------+  
mysql> SELECT DATE('2003-12-31 01:02:03');  
        -> '2003-12-31'  
mysql> SELECT DATEDIFF('2007-12-31 23:59:59','2007-12-30');  
        -> 1  
mysql> SELECT DATEDIFF('2010-11-30 23:59:59','2010-12-31');  
        -> -31  

This function returns NULL if_expr1_ or_expr2_ is NULL.

mysql> SELECT DATE_ADD('2018-05-01',INTERVAL 1 DAY);  
        -> '2018-05-02'  
mysql> SELECT DATE_SUB('2018-05-01',INTERVAL 1 YEAR);  
        -> '2017-05-01'  
mysql> SELECT DATE_ADD('2020-12-31 23:59:59',  
    ->                 INTERVAL 1 SECOND);  
        -> '2021-01-01 00:00:00'  
mysql> SELECT DATE_ADD('2018-12-31 23:59:59',  
    ->                 INTERVAL 1 DAY);  
        -> '2019-01-01 23:59:59'  
mysql> SELECT DATE_ADD('2100-12-31 23:59:59',  
    ->                 INTERVAL '1:1' MINUTE_SECOND);  
        -> '2101-01-01 00:01:00'  
mysql> SELECT DATE_SUB('2025-01-01 00:00:00',  
    ->                 INTERVAL '1 1:1:1' DAY_SECOND);  
        -> '2024-12-30 22:58:59'  
mysql> SELECT DATE_ADD('1900-01-01 00:00:00',  
    ->                 INTERVAL '-1 10' DAY_HOUR);  
        -> '1899-12-30 14:00:00'  
mysql> SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);  
        -> '1997-12-02'  
mysql> SELECT DATE_ADD('1992-12-31 23:59:59.000002',  
    ->            INTERVAL '1.999999' SECOND_MICROSECOND);  
        -> '1993-01-01 00:00:01.000001'  

When adding a MONTH interval to aDATE or DATETIME value, and the resulting date includes a day that does not exist in the given month, the day is adjusted to the last day of the month, as shown here:

mysql> SELECT DATE_ADD('2024-03-30', INTERVAL 1 MONTH) AS d1,  
     >        DATE_ADD('2024-03-31', INTERVAL 1 MONTH) AS d2;  
+------------+------------+  
| d1         | d2         |  
+------------+------------+  
| 2024-04-30 | 2024-04-30 |  
+------------+------------+  
1 row in set (0.00 sec)  
mysql> SELECT DATE_FORMAT('2009-10-04 22:23:00', '%W %M %Y');  
        -> 'Sunday October 2009'  
mysql> SELECT DATE_FORMAT('2007-10-04 22:23:00', '%H:%i:%s');  
        -> '22:23:00'  
mysql> SELECT DATE_FORMAT('1900-10-04 22:23:00',  
    ->                 '%D %y %a %d %m %b %j');  
        -> '4th 00 Thu 04 10 Oct 277'  
mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00',  
    ->                 '%H %k %I %r %T %S %w');  
        -> '22 22 10 10:23:00 PM 22:23:00 00 6'  
mysql> SELECT DATE_FORMAT('1999-01-01', '%X %V');  
        -> '1998 52'  
mysql> SELECT DATE_FORMAT('2006-06-00', '%d');  
        -> '00'  
mysql> SELECT DAYNAME('2007-02-03');  
        -> 'Saturday'  
mysql> SELECT DAYOFMONTH('2007-02-03');  
        -> 3  
mysql> SELECT DAYOFWEEK('2007-02-03');  
        -> 7  
mysql> SELECT DAYOFYEAR('2007-02-03');  
        -> 34  
mysql> SELECT EXTRACT(YEAR FROM '2019-07-02');  
        -> 2019  
mysql> SELECT EXTRACT(YEAR_MONTH FROM '2019-07-02 01:02:03');  
        -> 201907  
mysql> SELECT EXTRACT(DAY_MINUTE FROM '2019-07-02 01:02:03');  
        -> 20102  
mysql> SELECT EXTRACT(MICROSECOND  
    ->                FROM '2003-01-02 10:30:00.000123');  
        -> 123  
mysql> SELECT FROM_DAYS(730669);  
        -> '2000-07-03'  

Use FROM_DAYS() with caution on old dates. It is not intended for use with values that precede the advent of the Gregorian calendar (1582). SeeSection 13.2.7, “What Calendar Is Used By MySQL?”.

mysql> SELECT FROM_UNIXTIME(1447430881);  
        -> '2015-11-13 10:08:01'  
mysql> SELECT FROM_UNIXTIME(1447430881) + 0;  
        -> 20151113100801  
mysql> SELECT FROM_UNIXTIME(1447430881,  
    ->                      '%Y %D %M %h:%i:%s %x');  
        -> '2015 13th November 10:08:01 2015'  

Note
If you use UNIX_TIMESTAMP() and FROM_UNIXTIME() to convert between values in a non-UTC time zone and Unix timestamp values, the conversion is lossy because the mapping is not one-to-one in both directions. For details, see the description of theUNIX_TIMESTAMP() function.

mysql> SELECT DATE_FORMAT('2003-10-03',GET_FORMAT(DATE,'EUR'));  
        -> '03.10.2003'  
mysql> SELECT STR_TO_DATE('10.31.2003',GET_FORMAT(DATE,'USA'));  
        -> '2003-10-31'  
mysql> SELECT HOUR('10:05:03');  
        -> 10  
mysql> SELECT HOUR('272:59:59');  
        -> 272  
mysql> SELECT LAST_DAY('2003-02-05');  
        -> '2003-02-28'  
mysql> SELECT LAST_DAY('2004-02-05');  
        -> '2004-02-29'  
mysql> SELECT LAST_DAY('2004-01-01 01:01:01');  
        -> '2004-01-31'  
mysql> SELECT LAST_DAY('2003-03-32');  
        -> NULL  
mysql> SELECT MAKEDATE(2011,31), MAKEDATE(2011,32);  
        -> '2011-01-31', '2011-02-01'  
mysql> SELECT MAKEDATE(2011,365), MAKEDATE(2014,365);  
        -> '2011-12-31', '2014-12-31'  
mysql> SELECT MAKEDATE(2011,0);  
        -> NULL  
mysql> SELECT MAKETIME(12,15,30);  
        -> '12:15:30'  
mysql> SELECT MICROSECOND('12:00:00.123456');  
        -> 123456  
mysql> SELECT MICROSECOND('2019-12-31 23:59:59.000010');  
        -> 10  
mysql> SELECT MINUTE('2008-02-03 10:05:03');  
        -> 5  
mysql> SELECT MONTH('2008-02-03');  
        -> 2  
mysql> SELECT MONTHNAME('2008-02-03');  
        -> 'February'  
mysql> SELECT NOW();  
        -> '2007-12-15 23:50:26'  
mysql> SELECT NOW() + 0;  
        -> 20071215235026.000000  

NOW() returns a constant time that indicates the time at which the statement began to execute. (Within a stored function or trigger,NOW() returns the time at which the function or triggering statement began to execute.) This differs from the behavior forSYSDATE(), which returns the exact time at which it executes.

mysql> SELECT NOW(), SLEEP(2), NOW();  
+---------------------+----------+---------------------+  
| NOW()               | SLEEP(2) | NOW()               |  
+---------------------+----------+---------------------+  
| 2006-04-12 13:47:36 |        0 | 2006-04-12 13:47:36 |  
+---------------------+----------+---------------------+  
mysql> SELECT SYSDATE(), SLEEP(2), SYSDATE();  
+---------------------+----------+---------------------+  
| SYSDATE()           | SLEEP(2) | SYSDATE()           |  
+---------------------+----------+---------------------+  
| 2006-04-12 13:47:44 |        0 | 2006-04-12 13:47:46 |  
+---------------------+----------+---------------------+  

In addition, the SET TIMESTAMP statement affects the value returned byNOW() but not bySYSDATE(). This means that timestamp settings in the binary log have no effect on invocations of SYSDATE(). Setting the timestamp to a nonzero value causes each subsequent invocation of NOW() to return that value. Setting the timestamp to zero cancels this effect so that NOW() once again returns the current date and time.
See the description forSYSDATE() for additional information about the differences between the two functions.

mysql> SELECT PERIOD_ADD(200801,2);  
        -> 200803  
mysql> SELECT PERIOD_DIFF(200802,200703);  
        -> 11  
mysql> SELECT QUARTER('2008-04-01');  
        -> 2  
mysql> SELECT SECOND('10:05:03');  
        -> 3  
mysql> SELECT SEC_TO_TIME(2378);  
        -> '00:39:38'  
mysql> SELECT SEC_TO_TIME(2378) + 0;  
        -> 3938  
mysql> SELECT STR_TO_DATE('01,5,2013','%d,%m,%Y');  
        -> '2013-05-01'  
mysql> SELECT STR_TO_DATE('May 1, 2013','%M %d,%Y');  
        -> '2013-05-01'  

Scanning starts at the beginning of_str_ and fails if_format_ is found not to match. Extra characters at the end of str are ignored.

mysql> SELECT STR_TO_DATE('a09:30:17','a%h:%i:%s');  
        -> '09:30:17'  
mysql> SELECT STR_TO_DATE('a09:30:17','%h:%i:%s');  
        -> NULL  
mysql> SELECT STR_TO_DATE('09:30:17a','%h:%i:%s');  
        -> '09:30:17'  

Unspecified date or time parts have a value of 0, so incompletely specified values in_str_ produce a result with some or all parts set to 0:

mysql> SELECT STR_TO_DATE('abc','abc');  
        -> '0000-00-00'  
mysql> SELECT STR_TO_DATE('9','%m');  
        -> '0000-09-00'  
mysql> SELECT STR_TO_DATE('9','%s');  
        -> '00:00:09'  

Range checking on the parts of date values is as described inSection 13.2.2, “The DATE, DATETIME, and TIMESTAMP Types”. This means, for example, that“zero” dates or dates with part values of 0 are permitted unless the SQL mode is set to disallow such values.

mysql> SELECT STR_TO_DATE('00/00/0000', '%m/%d/%Y');  
        -> '0000-00-00'  
mysql> SELECT STR_TO_DATE('04/31/2004', '%m/%d/%Y');  
        -> '2004-04-31'  

If the NO_ZERO_DATE SQL mode is enabled, zero dates are disallowed. In that case,STR_TO_DATE() returnsNULL and generates a warning:

mysql> SET sql_mode = '';  
mysql> SELECT STR_TO_DATE('00/00/0000', '%m/%d/%Y');  
+---------------------------------------+  
| STR_TO_DATE('00/00/0000', '%m/%d/%Y') |  
+---------------------------------------+  
| 0000-00-00                            |  
+---------------------------------------+  
mysql> SET sql_mode = 'NO_ZERO_DATE';  
mysql> SELECT STR_TO_DATE('00/00/0000', '%m/%d/%Y');  
+---------------------------------------+  
| STR_TO_DATE('00/00/0000', '%m/%d/%Y') |  
+---------------------------------------+  
| NULL                                  |  
+---------------------------------------+  
mysql> SHOW WARNINGS\G  
*************************** 1. row ***************************  
  Level: Warning  
   Code: 1411  
Message: Incorrect datetime value: '00/00/0000' for function str_to_date  

Prior to MySQL 8.0.35, it was possible to pass an invalid date string such as '2021-11-31' to this function. In MySQL 8.0.35 and later,STR_TO_DATE() performs complete range checking and raises an error if the date after conversion would be invalid.
Note
You cannot use format "%X%V" to convert a year-week string to a date because the combination of a year and week does not uniquely identify a year and month if the week crosses a month boundary. To convert a year-week to a date, you should also specify the weekday:

mysql> SELECT STR_TO_DATE('200442 Monday', '%X%V %W');  
        -> '2004-10-18'  

You should also be aware that, for dates and the date portions of datetime values, STR_TO_DATE() checks (only) the individual year, month, and day of month values for validity. More precisely, this means that the year is checked to be sure that it is in the range 0-9999 inclusive, the month is checked to ensure that it is in the range 1-12 inclusive, and the day of month is checked to make sure that it is in the range 1-31 inclusive, but the server does not check the values in combination. For example, SELECT STR_TO_DATE('23-2-31', '%Y-%m-%d') returns2023-02-31. Enabling or disabling theALLOW_INVALID_DATES server SQL mode has no effect on this behavior. SeeSection 13.2.2, “The DATE, DATETIME, and TIMESTAMP Types”, for more information.

mysql> SELECT DATE_SUB('2008-01-02', INTERVAL 31 DAY);  
        -> '2007-12-02'  
mysql> SELECT SUBDATE('2008-01-02', INTERVAL 31 DAY);  
        -> '2007-12-02'  

The second form enables the use of an integer value for_days_. In such cases, it is interpreted as the number of days to be subtracted from the date or datetime expression expr.

mysql> SELECT SUBDATE('2008-01-02 12:00:00', 31);  
        -> '2007-12-02 12:00:00'  

This function returns NULL if any of its arguments are NULL.

mysql> SELECT SUBTIME('2007-12-31 23:59:59.999999','1 1:1:1.000002');  
        -> '2007-12-30 22:58:58.999997'  
mysql> SELECT SUBTIME('01:00:00.999999', '02:00:00.999998');  
        -> '-00:59:59.999999'  

This function returns NULL if_expr1_ or_expr2_ is NULL.

mysql> SELECT NOW(), SLEEP(2), NOW();  
+---------------------+----------+---------------------+  
| NOW()               | SLEEP(2) | NOW()               |  
+---------------------+----------+---------------------+  
| 2006-04-12 13:47:36 |        0 | 2006-04-12 13:47:36 |  
+---------------------+----------+---------------------+  
mysql> SELECT SYSDATE(), SLEEP(2), SYSDATE();  
+---------------------+----------+---------------------+  
| SYSDATE()           | SLEEP(2) | SYSDATE()           |  
+---------------------+----------+---------------------+  
| 2006-04-12 13:47:44 |        0 | 2006-04-12 13:47:46 |  
+---------------------+----------+---------------------+  

In addition, the SET TIMESTAMP statement affects the value returned byNOW() but not bySYSDATE(). This means that timestamp settings in the binary log have no effect on invocations of SYSDATE().
Because SYSDATE() can return different values even within the same statement, and is not affected by SET TIMESTAMP, it is nondeterministic and therefore unsafe for replication if statement-based binary logging is used. If that is a problem, you can use row-based logging.
Alternatively, you can use the--sysdate-is-now option to cause SYSDATE() to be an alias for NOW(). This works if the option is used on both the replication source server and the replica.
The nondeterministic nature ofSYSDATE() also means that indexes cannot be used for evaluating expressions that refer to it.

mysql> SELECT TIME('2003-12-31 01:02:03');  
        -> '01:02:03'  
mysql> SELECT TIME('2003-12-31 01:02:03.000123');  
        -> '01:02:03.000123'  
mysql> SELECT TIMEDIFF('2000-01-01 00:00:00',  
    ->                 '2000-01-01 00:00:00.000001');  
        -> '-00:00:00.000001'  
mysql> SELECT TIMEDIFF('2008-12-31 23:59:59.000001',  
    ->                 '2008-12-30 01:01:01.000002');  
        -> '46:58:57.999999'  
mysql> SELECT TIMESTAMP('2003-12-31');  
        -> '2003-12-31 00:00:00'  
mysql> SELECT TIMESTAMP('2003-12-31 12:00:00','12:00:00');  
        -> '2004-01-01 00:00:00'  
mysql> SELECT TIMESTAMPADD(MINUTE, 1, '2003-01-02');  
        -> '2003-01-02 00:01:00'  
mysql> SELECT TIMESTAMPADD(WEEK,1,'2003-01-02');  
        -> '2003-01-09'  

When adding a MONTH interval to aDATE or DATETIME value, and the resulting date includes a day that does not exist in the given month, the day is adjusted to the last day of the month, as shown here:

mysql> SELECT TIMESTAMPADD(MONTH, 1, DATE '2024-03-30') AS t1,  
     >        TIMESTAMPADD(MONTH, 1, DATE '2024-03-31') AS t2;  
+------------+------------+  
| t1         | t2         |  
+------------+------------+  
| 2024-04-30 | 2024-04-30 |  
+------------+------------+  
1 row in set (0.00 sec)  
mysql> SELECT TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01');  
        -> 3  
mysql> SELECT TIMESTAMPDIFF(YEAR,'2002-05-01','2001-01-01');  
        -> -1  
mysql> SELECT TIMESTAMPDIFF(MINUTE,'2003-02-01','2003-05-01 12:05:55');  
        -> 128885  

Note
The order of the date or datetime arguments for this function is the opposite of that used with theTIMESTAMP() function when invoked with 2 arguments.

mysql> SELECT TIME_FORMAT('100:00:00', '%H %k %h %I %l');  
        -> '100 100 04 04 4'  
mysql> SELECT TIME_TO_SEC('22:23:00');  
        -> 80580  
mysql> SELECT TIME_TO_SEC('00:39:38');  
        -> 2378  
mysql> SELECT TO_DAYS(950501);  
        -> 728779  
mysql> SELECT TO_DAYS('2007-10-07');  
        -> 733321  

TO_DAYS() is not intended for use with values that precede the advent of the Gregorian calendar (1582), because it does not take into account the days that were lost when the calendar was changed. For dates before 1582 (and possibly a later year in other locales), results from this function are not reliable. SeeSection 13.2.7, “What Calendar Is Used By MySQL?”, for details.
Remember that MySQL converts two-digit year values in dates to four-digit form using the rules inSection 13.2, “Date and Time Data Types”. For example,'2008-10-07' and'08-10-07' are seen as identical dates:

mysql> SELECT TO_DAYS('2008-10-07'), TO_DAYS('08-10-07');  
        -> 733687, 733687  

In MySQL, the zero date is defined as'0000-00-00', even though this date is itself considered invalid. This means that, for'0000-00-00' and'0000-01-01',TO_DAYS() returns the values shown here:

mysql> SELECT TO_DAYS('0000-00-00');  
+-----------------------+  
| to_days('0000-00-00') |  
+-----------------------+  
|                  NULL |  
+-----------------------+  
1 row in set, 1 warning (0.00 sec)  
mysql> SHOW WARNINGS;  
+---------+------+----------------------------------------+  
| Level   | Code | Message                                |  
+---------+------+----------------------------------------+  
| Warning | 1292 | Incorrect datetime value: '0000-00-00' |  
+---------+------+----------------------------------------+  
1 row in set (0.00 sec)  
mysql> SELECT TO_DAYS('0000-01-01');  
+-----------------------+  
| to_days('0000-01-01') |  
+-----------------------+  
|                     1 |  
+-----------------------+  
1 row in set (0.00 sec)  

This is true whether or not theALLOW_INVALID_DATES SQL server mode is enabled.

mysql> SELECT TO_SECONDS(950501);  
        -> 62966505600  
mysql> SELECT TO_SECONDS('2009-11-29');  
        -> 63426672000  
mysql> SELECT TO_SECONDS('2009-11-29 13:43:32');  
        -> 63426721412  
mysql> SELECT TO_SECONDS( NOW() );  
        -> 63426721458  

Like TO_DAYS(),TO_SECONDS() is not intended for use with values that precede the advent of the Gregorian calendar (1582), because it does not take into account the days that were lost when the calendar was changed. For dates before 1582 (and possibly a later year in other locales), results from this function are not reliable. SeeSection 13.2.7, “What Calendar Is Used By MySQL?”, for details.
Like TO_DAYS(),TO_SECONDS(), converts two-digit year values in dates to four-digit form using the rules inSection 13.2, “Date and Time Data Types”.
In MySQL, the zero date is defined as'0000-00-00', even though this date is itself considered invalid. This means that, for'0000-00-00' and'0000-01-01',TO_SECONDS() returns the values shown here:

mysql> SELECT TO_SECONDS('0000-00-00');  
+--------------------------+  
| TO_SECONDS('0000-00-00') |  
+--------------------------+  
|                     NULL |  
+--------------------------+  
1 row in set, 1 warning (0.00 sec)  
mysql> SHOW WARNINGS;  
+---------+------+----------------------------------------+  
| Level   | Code | Message                                |  
+---------+------+----------------------------------------+  
| Warning | 1292 | Incorrect datetime value: '0000-00-00' |  
+---------+------+----------------------------------------+  
1 row in set (0.00 sec)  
mysql> SELECT TO_SECONDS('0000-01-01');  
+--------------------------+  
| TO_SECONDS('0000-01-01') |  
+--------------------------+  
|                    86400 |  
+--------------------------+  
1 row in set (0.00 sec)  

This is true whether or not theALLOW_INVALID_DATES SQL server mode is enabled.

mysql> SELECT UNIX_TIMESTAMP();  
        -> 1447431666  
mysql> SELECT UNIX_TIMESTAMP('2015-11-13 10:20:19');  
        -> 1447431619  
mysql> SELECT UNIX_TIMESTAMP('2015-11-13 10:20:19.012');  
        -> 1447431619.012  

If you use UNIX_TIMESTAMP() andFROM_UNIXTIME() to convert between values in a non-UTC time zone and Unix timestamp values, the conversion is lossy because the mapping is not one-to-one in both directions. For example, due to conventions for local time zone changes such as Daylight Saving Time (DST), it is possible forUNIX_TIMESTAMP() to map two values that are distinct in a non-UTC time zone to the same Unix timestamp value.FROM_UNIXTIME() maps that value back to only one of the original values. Here is an example, using values that are distinct in the MET time zone:

mysql> SET time_zone = 'MET';  
mysql> SELECT UNIX_TIMESTAMP('2005-03-27 03:00:00');  
+---------------------------------------+  
| UNIX_TIMESTAMP('2005-03-27 03:00:00') |  
+---------------------------------------+  
|                            1111885200 |  
+---------------------------------------+  
mysql> SELECT UNIX_TIMESTAMP('2005-03-27 02:00:00');  
+---------------------------------------+  
| UNIX_TIMESTAMP('2005-03-27 02:00:00') |  
+---------------------------------------+  
|                            1111885200 |  
+---------------------------------------+  
mysql> SELECT FROM_UNIXTIME(1111885200);  
+---------------------------+  
| FROM_UNIXTIME(1111885200) |  
+---------------------------+  
| 2005-03-27 03:00:00       |  
+---------------------------+  

If you want to subtractUNIX_TIMESTAMP() columns, you might want to cast them to signed integers. SeeSection 14.10, “Cast Functions and Operators”.

mysql> SELECT UTC_DATE(), UTC_DATE() + 0;  
        -> '2003-08-14', 20030814  
mysql> SELECT UTC_TIME(), UTC_TIME() + 0;  
        -> '18:07:53', 180753.000000  
mysql> SELECT UTC_TIMESTAMP(), UTC_TIMESTAMP() + 0;  
        -> '2003-08-14 18:08:04', 20030814180804.000000  
mysql> SELECT WEEK('2008-02-20');  
        -> 7  
mysql> SELECT WEEK('2008-02-20',0);  
        -> 7  
mysql> SELECT WEEK('2008-02-20',1);  
        -> 8  
mysql> SELECT WEEK('2008-12-31',1);  
        -> 53  

If a date falls in the last week of the previous year, MySQL returns 0 if you do not use2, 3,6, or 7 as the optional_mode_ argument:

mysql> SELECT YEAR('2000-01-01'), WEEK('2000-01-01',0);  
        -> 2000, 0  

One might argue that WEEK() should return 52 because the given date actually occurs in the 52nd week of 1999.WEEK() returns0 instead so that the return value is“the week number in the given year.” This makes use of the WEEK() function reliable when combined with other functions that extract a date part from a date.
If you prefer a result evaluated with respect to the year that contains the first day of the week for the given date, use0, 2,5, or 7 as the optional_mode_ argument.

mysql> SELECT WEEK('2000-01-01',2);  
        -> 52  

Alternatively, use theYEARWEEK() function:

mysql> SELECT YEARWEEK('2000-01-01');  
        -> 199952  
mysql> SELECT MID(YEARWEEK('2000-01-01'),5,2);  
        -> '52'  
mysql> SELECT WEEKDAY('2008-02-03 22:23:00');  
        -> 6  
mysql> SELECT WEEKDAY('2007-11-06');  
        -> 1  
mysql> SELECT WEEKOFYEAR('2008-02-20');  
        -> 8  
mysql> SELECT YEAR('1987-01-01');  
        -> 1987  
mysql> SELECT YEARWEEK('1987-01-01');  
        -> 198652  

The week number is different from what theWEEK() function would return (0) for optional arguments0 or 1, asWEEK() then returns the week in the context of the given year.