Before MySQL 5.0.74, if the operating system is configured to
return leap seconds from OS time calls or if the MySQL server
uses a time zone definition that has leap seconds, functions
such as NOW() could return a
value having a time part that ends with
:59:60 or :59:61. If such
values are inserted into a table, they would be dumped as is by
mysqldump but considered invalid when
reloaded, leading to backup/restore problems.
As of MySQL 5.0.74, leap second values are returned with a time
part that ends with :59:59. This means that a
function such as NOW() can return
the same value for two or three consecutive seconds during the
leap second. It remains true that literal temporal values having
a time part that ends with :59:60 or
:59:61 are considered invalid.
If it is necessary to search for
TIMESTAMP values one second
before the leap second, anomalous results may be obtained if you
use a comparison with 'YYYY-MM-DD hh:mm:ss'
values. The following example demonstrates this. It changes the
local time zone to UTC so there is no difference between
internal values (which are in UTC) and displayed values (which
have time zone correction applied).
mysql>CREATE TABLE t1 (->a INT,->ts TIMESTAMP DEFAULT NOW(),->PRIMARY KEY (ts)->);Query OK, 0 rows affected (0.01 sec) mysql>-- change to UTCmysql>SET time_zone = '+00:00';Query OK, 0 rows affected (0.00 sec) mysql>-- Simulate NOW() = '2008-12-31 23:59:59'mysql>SET timestamp = 1230767999;Query OK, 0 rows affected (0.00 sec) mysql>INSERT INTO t1 (a) VALUES (1);Query OK, 1 row affected (0.00 sec) mysql>-- Simulate NOW() = '2008-12-31 23:59:60'mysql>SET timestamp = 1230768000;Query OK, 0 rows affected (0.00 sec) mysql>INSERT INTO t1 (a) VALUES (2);Query OK, 1 row affected (0.00 sec) mysql>-- values differ internally but display the samemysql>SELECT a, ts, UNIX_TIMESTAMP(ts) FROM t1;+------+---------------------+--------------------+ | a | ts | UNIX_TIMESTAMP(ts) | +------+---------------------+--------------------+ | 1 | 2008-12-31 23:59:59 | 1230767999 | | 2 | 2008-12-31 23:59:59 | 1230768000 | +------+---------------------+--------------------+ 2 rows in set (0.00 sec) mysql>-- only the non-leap value matchesmysql>SELECT * FROM t1 WHERE ts = '2008-12-31 23:59:59';+------+---------------------+ | a | ts | +------+---------------------+ | 1 | 2008-12-31 23:59:59 | +------+---------------------+ 1 row in set (0.00 sec) mysql>-- the leap value with seconds=60 is invalidmysql>SELECT * FROM t1 WHERE ts = '2008-12-31 23:59:60';Empty set, 2 warnings (0.00 sec)
To work around this, you can use a comparison based on the UTC value actually stored in column, which has the leap second correction applied:
mysql>-- selecting using UNIX_TIMESTAMP value return leap valuemysql>SELECT * FROM t1 WHERE UNIX_TIMESTAMP(ts) = 1230768000;+------+---------------------+ | a | ts | +------+---------------------+ | 2 | 2008-12-31 23:59:59 | +------+---------------------+ 1 row in set (0.00 sec)

User Comments
Add your own comment.