電子機器の時刻

↑

■○○年問題

近年「2000年問題」に代表される、電子機器の時刻記録の「桁あふれ」によるシステムのトラブルがしばしば問題にされます。当初システムを作った時に、漠然とこの桁あふれが起きる頃までにはもっといいシステムに移行しているだろう、といった考えで作成されたものが実際には、システムが更新されても時刻仕様だけ古いものを踏襲してきてしまったために、この手の問題が起きています。

電子システム上に日付や時刻を記録する場合、基本的に2進法で記録する場合と10進法で記録する場合がありますが、いづれも桁数を決めて記録しているので、いつかはその桁数をあふれてしまう場合があります。特に1980年代頃まではメモリも記録媒体もひじょうに高価であったため、当時の設計者はいかに小さな容量で多くのデータを記録するかということに腐心しており、数十年先の桁あふれにまで考慮する余裕は無かったのです。

この手の問題が最初に日本でクローズアップされたのは1989年の昭和天皇崩御の時でした。それまで日付を昭和○年という形で持っていたシステムも国内にはかなりあったので、天皇が交替し元号が改まって慌てることになりました。次はなんといっても2000年問題ですが、この時は事前に多くのシステムで問題が起きないか充分な検討が行われ、2000年になる時には多くのSEが万一の時に備えて待機していたこともあり、実際には大きなトラブルはほとんど起きませんでした。

天皇交替や2000年問題などは社会的にも大きな動きになりましたが、目立たない所でも小さな問題は起きていました。1999年8月21日には現在ではカーナビでおなじみの測位衛星GPSの内部時間の桁数があふれて0に戻るというのがあり、一部のGPS機器で実際に誤動作が起きました。GPSの時刻は次は2019年4月7日にも0に戻りますが、さすがに次はトラブルはないでしょう。この手の電子機器の内部時刻の問題は今日のように生活のあらゆる場所に電子機器が使われている今、気を付けてないと大変なことになる可能性もあります。

■一般的な10進記録システム

 1980年代頃まではメモリやハードディスクが高価であったこともあり、年月日を記録する場合、年を10進数2桁で記録する流儀が主流でした(月・日・時・分・秒は各々2桁)。その場合、多くのシステムでは単純に西暦の下2桁を記録していますが、ソフトメーカーで工夫を凝らした場合もあり、たとえば1980年を起点にして、1990年なら10, 2010年なら30 などと記録する方式を採ったりしたシステムもあります。このようなシステムは2000年には問題が起きませんが、2080年になると問題を生じます。起点としては1970年、1990年などというのもありました。古いシステムでは1930年起点というのもあるそうです。

   だいたい1990年頃以降に設計されたシステムでは年は4桁取られているものが多いものと思われ、こういうシステムは9998年までは安全に使用できます(9999は削除データの印など特別な値として利用されている場合がある)。

■一般的な2進記録システム

 10進数でデータを記録しているのはCOBOLで書かれた事務処理系のシステムに多いですが、FORTRANで書かれた技術計算系のシステムでは2進数でデータを記録したものが多かったです。この場合、月・日・時・分・秒は全て1ビット(0-255または -128〜127)で記録できますが、年を1ビットで記録したものと2ビットで記録した場合があります。2ビットで記録した場合は符号付きにしても32767年まで記録できるので実用上問題ありませんが、1ビットで例えば西暦下2桁を記録したようなシステムでは2000年問題を引き起こす可能性がありました。

2000年問題の時にひとつ問題だったのは、その問題を引き起こしそうなプログラムの多くがCOBOLやFORTRANで書かれたものであったのに、当時既にそれらの言語はあまり使われなくなっており、COBOLやFORTRANの修正ができるプログラマが少なかったという問題もありました。そのため大手のソフトハウスがOBに声を掛けて一時的に現場に復帰してもらうようなケースもあったようです。

■GPSの内部時刻

 GPSの内部時刻は1980年のUTC(時刻体系のページ参照)をベースにした原子時計による時刻で、閏秒の補正は直接行わず差分の形で保持されています。ここでこの時計の「週」の積算が10bitで持たれているため、1980年1月6日(日)を起点として1024週ごとにゼロに戻ります。これが1999年8月21日に初めて起きたのですが、次は2019年4月7日にも起きます。

■MSDOSのFAT

 MSDOSのファイル管理システムであるFAT、およびその拡張形式であるWindows95/98/MeのVFATは更新日時を 年(7bit)月(4bit)日(5bit)時(5bit)分(6bit)秒(5bit)の合計32bitで持っています。秒が0-59のはずなのに5bitしかないのは実は偶数にまるめて記録しているためです。年は7bitで0-127年が記録できますが、FATの起点は1980年なので127は2107年に相当します。つまりFAT/VFATは2107年の年末まで正常に動作します。

■MacのHFS

 Macintoshのファイル管理システムであるHFS(および後継のHFS+)はファイルの時刻を1904年1月1日起点のLongInt(32bit)の秒数で持っています。1904年1月1日0時0分0秒の2**32=4294967296秒後は2040年2月6日6時28分16秒になるので、それをすぎると問題が生じることになります。

■WindowsのNTFS

 WindowsNT, WindowsXP以降で使用されているファイル管理システムNTFSではファイルの時刻を1601年1月1日起点の64bitの経過時間で持っています。時間の単位は0.1μ秒です。1601年1月1日0時0分0秒の2**64=1844674407370.9551616秒後は60056年5月28日5時36分10.9551616秒になります。実用上問題無いと考えられます。どちらかというと起点を-10000年くらいにしておいて欲しかった所です。

■Unix系の経過時刻

 Unix系のOSでは1970年1月1日からの経過秒数で時刻を管理しているものが多くあります。Perlのtime関数やJavaScriptのgetTime関数などもこの値を返します(JavaScriptのgetTimeはミリ秒単位)。問題はこの数値をきちんと格納できないサイズの変数で処理しようとした場合です。

 ・2001年9月9日1時46分40秒にこの数字が十進数で9桁から10桁に変わりました。2chなどではこの数字を掲示板のidに使用しているため、この前後での掲示板の並べ替えがうまく行きません。  ・2038年1月19日3時14分8秒に2進数で31ビットから32ビットになるので符号付きIntegerで処理しているプログラムが誤動作します。    WWWプログラミングでよく使用されているPerlのtime関数は1970年1月1日からの経過秒数を返します。


(C)copyright ffortune.net 1995-2016 produced by ffortune and Lumi.
お問い合わせはこちらから