mita2 database life

主にMySQLに関するメモです

MySQL アメリカのサマータイムが恒久化されたらやることになる作業

サマータイムが終わらない?

アメリカでサマータイムを恒久化する動きがあるようです。 どれぐらい現実化する可能性があるのかわかりませんが、仮に、決定された場合、どのような作業が必要になるのか調べておきます。

下院を通過してバイデン大統領が署名すると、2023年の春に夏時間になったらずっとそのまま、秋になっても標準時には戻らなくなります。

news.yahoo.co.jp

Linuxタイムゾーンの管理

日本でも(結局、実現はしませんでしたが)「東京オリンピックの期間はサマータイムを採用しよう」という話があったように、時刻の定義は変遷します。 言い換えると、あるタイムゾーンにおける、「UTCからの時差」がタイミングによって変わるということです。

タイムゾーンにおける時刻の定義の履歴は zoneinfo として定義されています。 この定義があるので、タイムゾーン間の時刻の変換が正しくできるわけですね。

https://www.iana.org/time-zones

zoneinfoCentOS であれば、tzdata パッケージで管理されています。

MySQLタイムゾーンの管理

MySQLタイムゾーンを扱う場合、あらかじめ、mysql_tzinfo_to_sql コマンドで zoneinfo をSQLに変換し、DBにロードしておく必要があります。

$  mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql

タイムゾーンの定義を変更する

フィジーで 2021〜2022 年にかけての夏時間の適用が停止される事態があったようです。 これを使って タイムゾーンの更新のテストしてみます。ちなみに、南太平洋の国なので、12月が夏時間になってます。

この夏時間の変更は、tzdata-2021d取り込まれました。 tzdata-2020a には反映されていません。このデータだと、2021年の時刻も他の年と同じ時刻になってます。

$ rpm -qa | grep tzdata
tzdata-2020a-1.el7.noarch

$ date --date='TZ="Pacific/Fiji" 2020-12-25 14:00:00'
2020年 12月 25日 金曜日 10:00:00 JST
$ date --date='TZ="Pacific/Fiji" 2021-12-25 14:00:00'
2021年 12月 25日 土曜日 10:00:00 JST
$ date --date='TZ="Pacific/Fiji" 2022-12-25 14:00:00'
2022年 12月 25日 日曜日 10:00:00 JST
$ date --date='TZ="Pacific/Fiji" 2023-12-25 14:00:00'
2023年 12月 25日 月曜日 10:00:00 JST

tzdata をアップデートします。

$ sudo yum update tzdata
$ rpm -qa | grep tzdata
tzdata-2022a-1.el7.noarch

新しい tzdata-2022a の定義であれば、2021年だけ夏時間が適用されなくなっていることが確認できました。

$ date --date='TZ="Pacific/Fiji" 2020-12-25 14:00:00'
2020年 12月 25日 金曜日 10:00:00 JST
$ date --date='TZ="Pacific/Fiji" 2021-12-25 14:00:00'
2021年 12月 25日 土曜日 11:00:00 JST # 2021年だけ夏時間が停止されてる
$ date --date='TZ="Pacific/Fiji" 2022-12-25 14:00:00'
2022年 12月 25日 日曜日 10:00:00 JST
[$ date --date='TZ="Pacific/Fiji" 2023-12-25 14:00:00'
2023年 12月 25日 月曜日 10:00:00 JST

これをMySQLにも反映します。タイムゾーンの情報はキャッシュされているようで、DBにロードしたあと再起動が必要でした。

$ mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
$ sudo systemctl restart mysqld
--- 2021
mysql> SELECT CONVERT_TZ('2021-12-25 10:00:00', 'Asia/Tokyo', 'Pacific/Fiji');
+-----------------------------------------------------------------+
| CONVERT_TZ('2021-12-25 10:00:00', 'Asia/Tokyo', 'Pacific/Fiji') |
+-----------------------------------------------------------------+
| 2021-12-25 13:00:00                                             |
+-----------------------------------------------------------------+
1 row in set (0.00 sec)

--- 2022
mysql> SELECT CONVERT_TZ('2022-12-25 10:00:00', 'Asia/Tokyo', 'Pacific/Fiji');
+-----------------------------------------------------------------+
| CONVERT_TZ('2022-12-25 10:00:00', 'Asia/Tokyo', 'Pacific/Fiji') |
+-----------------------------------------------------------------+
| 2022-12-25 14:00:00                                             |
+-----------------------------------------------------------------+
1 row in set (0.00 sec)

まとめ

タイムゾーンの定義が変わったら、tzdata をアップデートして、mysql_tzinfo_to_sql でロードしなおす