うるう秒という物の存在をご存じでしょうか?例えば1999年1月1日 0時0分0秒(GMT)
前後の1秒ごとの協定世界時での時刻の変化を見てみましょう。
Thu Dec 31 23:59:58 GMT 1998 Thu Dec 31 23:59:59 GMT 1998 Thu Dec 31 23:59:60 GMT 1998 ←ここに注目 Fri Jan 01 00:00:00 GMT 1999 Fri Jan 01 00:00:01 GMT 1999 Fri Jan 01 00:00:02 GMT 1999たぶん、普通のコンピュータのシステム時計は、
Thu Dec 31 23:59:58 GMT 1998 Thu Dec 31 23:59:59 GMT 1998 Fri Jan 01 00:00:00 GMT 1999 Fri Jan 01 00:00:01 GMT 1999 Fri Jan 01 00:00:02 GMT 1999 Fri Jan 01 00:00:03 GMT 1999という感じで時を刻んでいることでしょう。
それでは、試してみましょう。
その前に、これからやることを実行すると、何らかの問題が発生する
可能性があります。ディスクを破壊したりとか、そういう種類の障害は
原理上発生しないはずですが、時刻の関わるもの、 cron とか syslog
関係とか、そういうもので何か起こるかもしれません。できれば、テスト用
マシンを用意して十分検証した方が良いでしょう。
私の環境では、幸い障害は発生していません(今のところ....)。
用意する物
Linux のインストールされているマシン。
調べていないのでよく分かりませんが、glibc-2.1 以降でないとうるう秒の
処理に対応していないようです。glibc-2.1 を標準で採用している
ディストリビューションを使用するのがよいでしょう。私は Plamo Linux 2.0
で実験しました。
timezone data
ftp://elsie.nci.nih.gov/pub/ から取得してください。
2003年4月25日現在、
ftp://elsie.nci.nih.gov/pub/tzdata2003a.tar.gz が最新の様です。
これらのアーカイブ内にあるうるう秒挿入日時のデータ leapseconds については、
うるう秒の挿入が決定される度に更新されますので、定期的に新しいものを取得
して、以下の作業をやり直す必要があります。
zoneinfo の作成。
今回は、/usr/share/zoneinfo 以下全てをうるう秒対応に変更するのではなく
うるう秒対応の Asia/Tokyo の zoneinfo だけを作成する事にしますので、
上記 glibc のソースまたは tzdata2000d.tar.gz から
asia leapsecondsというファイルだけを持ってきて下さい。 適当なディレクトリを作成して asia, leapseconds をコピーして
zic -d . -L leapseconds asiaを実行すれば、カレントディレクトリの Asia 以下に、アジア各地のうるう秒に対応した zoneinfo が作成されます。 このファイルを /etc/localtime にすれば終わりです。
ln -s /usr/share/zoneinfo/Asia/Tokyo-leaps /usr/share/zoneinfo/localtime ln -s /usr/share/zoneinfo/localtime /etc/localtimeという風にリンクを張りました。 /usr/share/zoneinfo/Asia/Tokyo にリンクを 張り直せば元の状態に戻ります。後は、適当なプログラムを書いて実験してみてください。 たとえば、次のようなプログラムを実行すれば、
#includeうるう秒に対応していれば、#include int main() { time_t t = 915148819; int i; for( i = 0; i < 5; i++ ){ printf( "%11.1d: %s", t, ctime(&t) ); t++; } exit(0); } 915148819: Fri Jan 1 08:59:58 1999 915148820: Fri Jan 1 08:59:59 1999 915148821: Fri Jan 1 08:59:60 1999 915148822: Fri Jan 1 09:00:00 1999 915148823: Fri Jan 1 09:00:01 1999という結果になるでしょうし、対応していないシステムでは、915148819: Fri Jan 1 09:00:19 1999 915148820: Fri Jan 1 09:00:20 1999 915148821: Fri Jan 1 09:00:21 1999 915148822: Fri Jan 1 09:00:22 1999 915148823: Fri Jan 1 09:00:23 1999となることでしょう(実行しているマシンのlocaltime が日本標準時に設定されている 場合です)。 ruby がインストールされていれば、#!/usr/local/bin/ruby # t = Time::gm( 1998, 12, 31, 23, 59, 58 ) for i in 1 .. 5 printf( "%11.1d: %s\n",t.to_i, t.to_s ) t += 1 endというプログラムなんかは如何でしょうか? 上記 ruby のプログラムでは、時刻の表示が GMT になっていますが t.to_s を t.localtime.to_s に変更すれば、local time 表示になります。何か問題は起こるのか?
たぶん起こると思います。例えば、毎時 0分0秒に何かするというつもりでt = time(NULL); if( ( t % (60*60)) == 0 ){ .......というような書き方をされると困ったことになりますよね? 1972 年頃は 毎時 0分0秒だったの が、現在(2000年)では、希望よりも 22 秒早く実行されてしまいます。新規に作成する物に ついては、プログラムの作成者が気をつけていれば良いだけの話ですが、今使っている プログラムはどうなっているでしょうか? なんか 2000年問題の時の事を思い出しますね。ところで次のうるう秒はいつでしょうか?それは、誰にもわかりませんが、 2003年7月1日にうるう秒が無い事は決定しているようです。 うるう秒の実施に付いての情報を早めに知りたい方は、 独立行政法人通信総合研究所 日本標準時グループ のページの「日本標準時グループからのお知らせ」をまめにチェックすると 良いでしょう。
このページに関する、ご意見、感想、苦情はこちらまで 松本 徳真 / matsu@netfort.gr.jp