Linuxでサマータイムが切り替わる瞬間について
海外向けのサービスのためにLinuxでサマータイムのある地域のタイムゾーンを設定することもあるかと思いますが、サマータイムに切り替わる瞬間にどうなるのか気になったのでちょっと試してみました。
[条件]
- dateコマンドでPST(太平洋標準時)がサマータイムに入る/戻る瞬間
- 環境:CentOS6.4 Kernel: 2.6.32-358.el6.x86_64
- 実行方法:一時的に時間変更した後、watchコマンドで1秒毎に経過監視
[サマータイムに入る瞬間]
[サマータイムから戻る瞬間]
この通り 2015年のサマータイムにて PST(太平洋標準時)からPDT(太平洋夏時間)にかけてdateコマンドの結果取得が瞬時に切り替わることがわかります。 もちろんdateコマンドの表示フォーマットを変えても同じ結果となります。
phpやrubyといったプログラム言語で時間取得していた場合はどうなるでしょう
<?php date_default_timezone_set('America/Los_Angeles'); echo date('r'); ?>
puts Time.now
どちらも特に何も考えないコードでは同様な結果となるようです。 と、ここまでは当たり前のようですが、もうちょっと踏み込んで見ましょう。
サマータイムに切り替わる日時をコマンドから調べる
Linuxのタイムゾーンの仕組みは「/etc/localtime」「/usr/share/zoneinfo」あたりを調べると分かりますが、特にタイムゾーンのデータ自体である「/usr/share/zoneinfo」配下にある「tz database」と呼ばれるファイルについては以下のコマンドで内容を見る事ができます。
# PST/PDTのタイムゾーンを調べる zdump -v /usr/share/zoneinfo/US/Pacific
[出力結果]
: /usr/share/zoneinfo/US/Pacific Sun Mar 8 09:59:59 2015 UTC = Sun Mar 8 01:59:59 2015 PST isdst=0 gmtoff=-28800 /usr/share/zoneinfo/US/Pacific Sun Mar 8 10:00:00 2015 UTC = Sun Mar 8 03:00:00 2015 PDT isdst=1 gmtoff=-25200 /usr/share/zoneinfo/US/Pacific Sun Nov 1 08:59:59 2015 UTC = Sun Nov 1 01:59:59 2015 PDT isdst=1 gmtoff=-25200 /usr/share/zoneinfo/US/Pacific Sun Nov 1 09:00:00 2015 UTC = Sun Nov 1 01:00:00 2015 PST isdst=0 gmtoff=-28800 :
左から
- zoneinfoファイル名
- UTCでのサマータイム切り替え日時
- PST/PDTでのサマータイム切り替え日時
- 「Is Daylight Saving Time」の略でサマータイム切り替わりのフラグ。つまりisdst=1となっている行がサマータイムの開始
- GMT(グリニッジ標準時)からのオフセット秒
と正確にシステム上のサマータイムの切り替え日時を確認することができます
時刻表現の連続性を保ちたい場合は?
仮にタイムゾーン表現を見ずにHH:MM:SS等の表現のみを記録するシステムだと、切り替わる際に未来に飛んだり、過去に戻ってしまうように見えてしまいます。 保存情報にUnixtimeやタイムゾーンまで含めたデータを保存・読み込んで解析するようにすれば問題ないのですが、他にLinuxには以下のような「GMT+n」というGMTからのオフセットのみの情報から成るタイムゾーンがあるので、同じGMTオフセット時間のものを設定するのも良いでしょう。 こちらは以下のようにそもそもサマータイム情報を保持してないので切り替えが存在しません。
[PST/PDTの代替えにGMT+8を使う]
cp /usr/share/zoneinfo/Etc/GMT+8 /etc/localtime echo ZONE='"GMT+8"' > /etc/sysconfig/clock
zdump -v /usr/share/zoneinfo/Etc/GMT+8 /usr/share/zoneinfo/Etc/GMT+8 -9223372036854775808 = NULL /usr/share/zoneinfo/Etc/GMT+8 -9223372036854689408 = NULL /usr/share/zoneinfo/Etc/GMT+8 9223372036854689407 = NULL /usr/share/zoneinfo/Etc/GMT+8 9223372036854775807 = NULL
[念のためPST/PDTのサマータイム入りする時間をチェックしてみた]