2006年1月 1日

Linux と「うるう秒」

今日の日本時間の午前 9時 にうるう秒が入ったそうです。そこで、手元の Debian GNU/Linux sarge で 08:59:60 という時刻を表示させてみました。

 

通常用いられているタイムゾーンの定義ファイル /usr/share/zoneinfo/Asia/Tokyoにはうるう秒の情報は入っていません。うるう秒入りのタイムゾーンの定義ファイルは /usr/share/zoneinfo/right 以下にあります。東京の場合は /usr/share/zoneinfo/right/Asia/Tokyo です。TZ 環境変数を使うと、任意のタイムゾーンでプログラムを実行できます。

それではまず、前回のうるう秒が挿入された 1999年1月 1日午前 9時の様子を見てます。

% TZ=right/Asia/Tokyo ruby -e 'p Time.mktime(1999,1,1,9)'
Fri Jan 01 09:00:00 JST 1999
% TZ=right/Asia/Tokyo ruby -e 'p Time.mktime(1999,1,1,9)-1'
Fri Jan 01 08:59:60 JST 1999

確かに 08:59:60 という時刻が表示されました。しかし、今日 (2006年1月1日) の日付を指定すると 08:59:59 になってしまいました。

% TZ=right/Asia/Tokyo ruby -e 'p Time.mktime(2006,1,1,9)'
Sun Jan 01 09:00:00 JST 2006
% TZ=right/Asia/Tokyo ruby -e 'p Time.mktime(2006,1,1,9)-1'
Sun Jan 01 08:59:59 JST 2006

これは /usr/share/zoneinfo/right/Asia/Tokyo に今回のうるう秒の情報が入っていないためです。glibc 2.3.6 には、今回のうるう秒の情報が入っているので、これを使えば今日の 08:59:60 を見ることができます。

% wget http://ftp.gnu.org/gnu/glibc/glibc-2.3.6.tar.bz2
% tar jxf glibc-2.3.6.tar.bz2
% cd glibc-2.3.6/timezone
% zic -d . -L leapseconds asia
% TZ=`pwd`/Asia/Tokyo ruby -e 'p Time.mktime(2006,1,1,9)-1'
Sun Jan 01 08:59:60 JST 2006

おまけ

ntpd を動かしている Debian GNU/Linux のシステムでは /var/log/message に次のような記録が残っていると思います。カーネル内のうるう秒の処理は kernel/timer.c で行われています (鵜飼さん情報)。

Jan  1 08:59:59 hostname kernel: Clock: inserting leap second 23:59:60 UTC

さらに余談ですが、 JavaScript には月が 0 はじまりという厄介な仕様があります。日は 1はじまり、曜日は 0 はじまり (0 = 日曜 ~ 6 = 土曜) です。

% js
js> d = new Date
Sun Jan 01 2006 23:47:06 GMT+0859 (JDT)
js> d.getMonth()
0
js> d.getDate()
1
js> d.getDay()  # 曜日
0

JavaScript を Unix の端末内で動かす方法については SpiderMonkey で JavaScript のインタラクティブシェルを参照してください。その他の言語の月の始まりについては月のオリジンをどうぞ。