日付からEpochを求める

Epochとは FreeBSDのman 3 time で見てみると

1970/1/1 00:00:00 (UTC)からの経過秒数

と定義されているようです。

UTCには閏秒があったりして厄介です。また初期実装エンジニアの勘違い(!?)もあって上記のように実装されていないシステムが一般的で、閏秒はなかったこととして計算するのが主流のようです。いうなれば原子時(TAI)ベースといったところでしょうか?これについては語ると長くなりますので割愛します。詳細はここみてください。

今回は現在の日付からepochを求めるお話です。

ローカルタイムからepochを求めるには mktime()という関数を使えばよろしい。これはマニュアルに書いてあります。日本の場合はこれで終了です。

問題はサマータイムのある地域の場合です。業務で必要なので調べてみました。

簡単のためロンドンについて書きます。

ロンドンでは3月の最終日曜日の深夜1時から 10月の最終日曜日の1時までがサマータイムとなります。(どちらもGMT)

入るときは1時間だけ時間が飛びます。つまり00:59:59の次が02:00:00となります。その間の時刻は存在しません。

戻るときは1時間だけ時間が巻き戻ります。01:59:59の次が01:00:00になります。

厄介なのは後者です。前者は mktimeライブラリがよろしくやってくれますが、後者は時刻だけからでは、サマータイム終了前なのか後なのか判断できないので、わかりません。

これはプログラマが責任を持って渡してやらなければなりません。それが struct tmのtm_isdstメンバです。

tm_isdstを正にするとサマータイム内、0にするとサマータイム外として判断します。負の値を設定するとよろしくやってくれるようで、中間の30分の前後でわけてくれるようです。

なお、JSTで実行する場合はサマータイムが存在しないので、tm_isdstを正にしておくと、常にエラー(-1)になります。年月日、時分秒だけ代入しておいて変換しても一向に-1しかmktimeが返さないので、ちゃんと0とか-1を代入してからmktimeを実行しましょう。

コメント一覧

実は、tm_isdstの意味を勘違いしているライブラリの実装や、アプリケーションが結構あるんですよ。サマータイムが存在しない地域の人が間違うのも無理ないですが…
nao