Linuxでサマータイムが切り替わる瞬間について

海外向けのサービスのためにLinuxサマータイムのある地域のタイムゾーンを設定することもあるかと思いますが、サマータイムに切り替わる瞬間にどうなるのか気になったのでちょっと試してみました。

[条件]

  • dateコマンドでPST(太平洋標準時)がサマータイムに入る/戻る瞬間
  • 環境:CentOS6.4 Kernel: 2.6.32-358.el6.x86_64
  • 実行方法:一時的に時間変更した後、watchコマンドで1秒毎に経過監視

[サマータイムに入る瞬間]


[サマータイムから戻る瞬間]

この通り 2015年のサマータイムにて PST(太平洋標準時)からPDT(太平洋夏時間)にかけてdateコマンドの結果取得が瞬時に切り替わることがわかります。 もちろんdateコマンドの表示フォーマットを変えても同じ結果となります。

phprubyといったプログラム言語で時間取得していた場合はどうなるでしょう

<?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
:

 

左から

と正確にシステム上のサマータイムの切り替え日時を確認することができます

 

時刻表現の連続性を保ちたい場合は?

仮にタイムゾーン表現を見ずに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

[GMT+nはサマータイム情報がない]

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のサマータイム入りする時間をチェックしてみた]