以下、MySQL5.6で遭遇した。
MySQLのUNIX_TIMESTAMPは DATETIME文字列などを引数にとり、UNIXタイムスタンプ(1970-01-01 00:00:00 UTCを起点とした経過秒数)を返す関数だ。
mysql> SET SESSION time_zone = 'UTC';
mysql> select UNIX_TIMESTAMP('1970-01-01 00:00:00');
+---------------------------------------+
| UNIX_TIMESTAMP('1970-01-01 00:00:00') |
+---------------------------------------+
| 0 |
+---------------------------------------+
1 row in set (0.00 sec)
ただし、2038年1月19日3時14分7秒(UTC)以降を渡すと0になってしまう。 これはドキュメントにも書いてある通り範囲外だから。
mysql> select UNIX_TIMESTAMP('2038-01-19-03-14-07');
+---------------------------------------+
| UNIX_TIMESTAMP('2038-01-19-03-14-07') |
+---------------------------------------+
| 2147483647 |
+---------------------------------------+
1 row in set (0.04 sec)
mysql> select UNIX_TIMESTAMP('2038-01-19-03-14-08');
+---------------------------------------+
| UNIX_TIMESTAMP('2038-01-19-03-14-08') |
+---------------------------------------+
| 0 |
+---------------------------------------+
1 row in set (0.00 sec)
では、この境目は何かというと、32ビットで表せる符号付数値の最大値だ。
> 2 ** 31
=> 2147483648
これはMySQLに限らず、2038年問題と呼ばれているもので、
DATETIME型は'9999-12-31’までサポートしているのでこれ以降も表すことはできるが、UNIX_TIMESTAMP
しても正しい値は得られなくなる。