AOTAKA's web Copyright(c)AOTAKA 1995-2003 - www.aotaka.jp 更新:1999-10-04

西暦2000年問題(Y2K)

西暦1999年まで30日を切った平成10年12月08日、(社)日本電子工業振興協会(JEIDA)は1999年問題に対する緊急アピールを行った。これは西暦2000年問題に目を奪われがちな我々に対する警鐘であった。ここで時間崩壊とも呼ばれるコンピューター内部で起こっているカタストロフィーを再考してみよう。

1998/12/12 初版
1998/12/20 ちょっとウソが書いてあったので修正
1999/01/20 UTC(協定世界時)って何という疑問に答える
1999/02/05 「西暦2000年問題はもう始まっている」「なぜ人は西暦を2桁でプログラムするのか?」を付け加え、時間変数の表記間違いを修正(最近Cから離れているもので・・・(苦笑))
1999/10/04 8/22に起こった「GPSのロールオーバー」の結果を追加


西暦2000年問題は何故起こるのか

 コンピューター(ここでは組込用マイクロプロセッサーなども含む)や、その前身が我々の生活において実用的・大規模に使用されるようになったのは1920年頃からであると思う。
  当初は国勢調査や弾道計算という非一般的目的であったコンピューターも、やがて様々な使用法が開発され一般に普及し現在に至っているのはご存じの通り。
  現在のコンピューターは大小の差こそあれ、たいていは時計機能を有し、さらにはその時計機能を用いて事務処理上の時間管理からファイルの作成日時管理までデータの処理・管理に極めて密接に作用しているのが現状である。しかもその時計は実用上・歴史的な問題から「キリストが生まれたとされる年」を起点とするいい加減な歴(いわゆる西暦)を標準にするようになっている。

 しかし西暦を使用する上において習慣的に本来はコンピューターとは相容れない風習が存在していた。それが西暦の2桁表示である。人間は西暦を4桁で表記しようが2桁で表記しようが自分たちが生きている間に流れる時間はせいぜい2世紀がよいところだし、ある程度の教育を受けた者であれば2桁で表記された年号を簡単な推測から4桁に翻訳することは簡単である。
  しかし、コンピューターやその上のデータは人間のような曖昧さに対応できるほど柔軟ではない。(曖昧さをプログラミングできれば別だが、普通そんなことはしないだろうし、出来たら天才だ。)

 コンピューターが初めて実用的な目的を持って運用された当初から現在に至るまで西暦の頭には「19」の文字が必ず記されていた。しかし、1999年の次からはそこが「20」に置き換わる。不幸なことかコンピューターは1980年代の前後あたりから急速な発展を遂げ、今や生産・物流・航空・陸運・海運・軍事・情報・通信・金融・・・様々な文明活動になくてはならない物となっているが、コンピューターは西暦の頭が「19」ということを前提に設計さえすれば今までは問題なかった。つまり「20」になったときは想定されておらず、その動作は不定(とうぜん動作に異常を来す可能性が高い)な事が多い。

これが何を意味するのか、それはまさに不定である。


西暦2000年には何が起こるのか

 まあ先ほどから「不定」だと言っている通り、具体的には何が「どう」どのような規模で発生するのかは分からないのだが、現在想定されるシステム的問題については大体以下のようになっている。

(1)「'00=1900」

 この問題は日数計算などで問題となる。例えば西暦4桁で計算する場合と下2桁で計算する場合には以下のような違いが発生する。

2000/1/1 1999/12/31 1日
'00/1/1 '99/12/31 -36524日

これは2000年を1900年として計算してしまうという問題である。結果的に正しく日時計算を行うことが出来なくなり、時間の前後関係を取り違えたり、正しい日数計算が出来なくなる不都合が出る。

 我々に身近な具体的事例としては、クレジットカードの2000年問題があげられる。たとえば現在使用されているクレジットカードには「有効期限 01/99」等と書かれているが、これは'99年01月末日まで有効のカードという意味である。今ではさすがに「01/00」等というカードが登場しているが2000年以降が有効期限となるカードは一時期、発行不可能な状態になったことがあった。これはクレジットカードが年を2桁で処理していることに起因し、例えば1995年に有効期限5年間のカードを処理しようとすれば「'00?1900年迄有効なのだから有効期限外だよ」とエラーを返されてしまうのである。(この時は結局1999年12月迄有効のカードを仮発行することで対応した) 昨今、国内では手動でクレジットの決済を行うという酔狂な店舗も少なくなっているので、当然処理は機械がやることになるが、この機械やシステムは2000年に対応できなかったのである。

(2)「想定範囲外・99や00に特殊な意味を持たせている場合」

 もともと西暦2000年頃まで使用されることを想定していなかったプログラムの中には、データ的に99や00を特殊な数字として処理するプログラムがある。この場合は'99年や'00年をその特殊な処理(例えば工期の記録で”工期終了日未定”とかという扱いをするプログラムは存在する)として扱う物もある。いわゆる例外処理と呼ばれる処理をするためのキーが99や00になっているプログラムだ。

 さてこの場合には何が起こるのか。工事の期間を管理するソフトがあったとして99年1月1日を工事の終了日として入力してみよう。もし問題があるならば「99年の入力があったということは”終了日未定”だな」とプログラムが勝手な判断をしてしまう。また、そういうプログラムなら開始時期に99年なんて入力しようものなら「入力範囲外です」と言われて入力すら出来ないだろう。つまりこの例では1999年の元日以降は使えないプログラムになってしまうのである。

 ちなみにこのケースでは、西暦1999年中に起こる(1999年内の特定条件がトリガーキーとなる)場合を西暦1999年問題、西暦2000年になってから起こる(2000年内の特定条件がトリガーキーとなる)場合を西暦2000年問題と言う事があるが基本的に同じ原因である。

 なお、99とは言ったがいわゆる「1999年問題」が99年元日以降に発生するとは限らない。'99年4月9日(99年の99日目)、'99年9月9日(9999と9が並ぶ)なども危ないと言われている。また、「うちは2000年を跨ぐ計算がないから大丈夫です」なんて言っていると足をすくわれかねないので一応は注意するべきである。

身近で便利な(?)例外処理

  Windows98の時計を1980年1月1日(の早い時間)にしてファイルを作成してみよう。(Windowsの前身である)MS-DOS内部では1980年が0年なので1月1日はまさに紀元である。しかも日本時間の8:59までは世界標準時では、まだ1979年12月31日である。このためにWindows標準のエクスプローラーなどでは日付表示をわざと出さなかったりする。これも例外処理の一つといえよう。逆にこれを利用し更新日不明のデータをこの日付にしておけば便利かもしれない。あまり実用的な意味はないけどね。
(Windows98で確認、将来的に同じ処理が行われるかはもちろん不明だ)

(3)西暦2000年は閏年か

 常識人ならこの答えは分かるだろう。ちなみに答えは「閏年は西暦が4で割り切れる年にあり、100で割り切れる年は帳消しにするが、400で割り切れる年にはやっぱり挿入するので、2月29日は有る」だ。

 ところがプログラマーの中にはグレゴリオ暦の規則を正しく理解しない大馬鹿者もいるので、そいつらが2月には29日が無いと仮定してプログラムをしちゃった場合には、2000年2月29日をまたぐ日数計算や3月1日以降の曜日計算に支障を来す結果となる。

もっとも、大馬鹿野郎は「4年に一回閏年」しか知らないわけだから2100年まで大丈夫かもしれない(笑)

 

 以上の問題は、実際には確実な検証作業というのが不可能なので、2000年になって運用してみるまで分からないと言った不安を残す。

 またハードウエア自身の問題は、相手がただのソフトウエアの場合とは違い、「組み込みチップ」などといわれる何年も前に作られたハードウエアを2000年対応の設計に変更する事は不可能で簡単にリプレースすることはかなわない。今はハードウエアの方が真に重要視すべき問題なのかもしれない。

 

グレゴリオは永遠か?5時間48分42秒の歪みへの挑戦

  我々が現在使用している暦法はグレゴリオ暦、その前はユリウス暦だった。(日本に限れば明治まで太陰暦を使用していた) それぞれ1年365日として計算する太陽暦の一種である。ユリウスは「4年に一度…」で約1600年を耐え抜き、グレゴリオはそれに「100年…、400年…」を付け加え、約1600年間の歪みを精算するために十数日間をおろ抜いた。これらは365日5時間48分42秒で太陽を公転する地球と、1年365日で計算する暦を一致させるための処置である。

  では次に人類の暦と実際の地球の動きがずれてしまい、補正が必要となるのは何時のことか? 私は1982年にこの問題を考え、プログラムには西暦1601年〜昭和474年(西暦2399年)以外を受け付けない処理を施したものである。9歳当時の事なので割といい加減な処理であるのが今となっては恥ずかしいが(笑)

  しかし最近聞いた話によれば、ここ数千年ほどで見れば補正を加えたりグレゴリオ暦に替わる暦を採用しなくても全然大丈夫らしい。なるほど、論理的に考えればその通りだ。

  400年間の日数 1年間の日数 146096.86… 365.24215…
1年365日 146000 ÷400= 365 -5:48:42 4年
ユリウス暦 146100 ÷400= 365.25 0:11:18 127年
グレゴリオ暦 146097 ÷400= 365.2425 0:00:30 2880年

 

西暦2000年問題はもう始まっている

 西暦2000年問題とはデータの処理上の問題である。つまりはデータに依存するのであって時間依存ではない。これが何を意味するのか、理解できない人間もまだまだ多い。

 1999年10月よりアメリカでは2000年会計年が、日本でも2000年3月までを対象とした平成11年度が4月より始まる。現在発行されているクレジットカードでは既に有効期限は2002年や2004年である。しかも日本では4月からは各企業とも西暦2000年3月までを一区切りとした事業を始めるだろう。そうすれば2000年以降の決済などがデータ上に現れてくることになるのである。データ上は既に西暦2000年問題が始まっているのである。

 

ところでMicrosoftは?「Year 2k Ready?」

  世界でもっとも影響力の大きいソフトウエア会社といえばMicrosoft・・・。あなたのMicrosoft製品は2000年に対応していますか?何時どのように対応されるのですか?本当に対応されるのですか?実はMicrosoftは対応する気がないのではないですか?一般の人々にも分かるように告知はされるのですか?

   今でも西暦2000年2月29日を越えられないNOS(Network OS)をパッケージ販売しているMicrosoftの公式見解は日本国政府ほど曖昧で暢気(のんき)だ。(1999年2月現在)

 

なぜ人は西暦を2桁でプログラムするのか?

 さて西暦2000年問題がクローズアップされた原因は何であろうか。(2)の例外処理や(3)の閏年のミスなどだけを見れば取るに足らないバグ(プログラム上のミス)であったはずだ。問題を大きくしたのは全世界の多くのプログラムや機器が西暦を2桁で管理していたことに他ならない。JIS(日本工業規格)でもISO(国際標準規格)でも西暦を2桁で表すことは規定されている。

 なぜ、10年以上も前から問題にされているY2Kを今の今まで放って置いたのだろうか。

 それはデータの量を1バイトでも削減することがプログラマーとしての基本と認識されてきたからといえないだろうか。1980年代以前は「1ビットいくら」の時代であった。銀行のメインシステムでさえハードディスクが1GBにも遠く届かない時代、プログラマーは1バイトを削ることを至上命題とされ、システムが何十年も受け継がれていくことを想定していなかった、または経費の問題からあえて無視していた。

 そして、1999年にまで至る結果となった。1999年時点でシステムは開発されたときと同じように問題なく動いている。来年以降も動き続けるために、人類が日本の国家予算と同じ桁の支出を強いられることになるだろうという事を除けば。

  必要なbit数 特徴
MS-DOS
ファイル
7bits
1980〜2107
4
0〜15
5
0〜31
5
0〜31
6
0〜63
5
2秒
単位
32 2秒単位とすることでデータフォーマットの無駄を克服し32bitsで100年を表す。フォーマット的には不正な時間データも許容するが、データの解析を行う必要がない点が1980年頃には重要な要素だったのだろう。
UNIX
time_t
1970年よりの経過秒数
1970〜2038年、1秒単位
31 31bitsで68年を表せる、経過秒数なので1970〜2038年の間の経過秒数は計算が楽。ただしデータを実際の時間として扱うには必ず変換が必要となるので(当時としては)処理能力の大きい電算機向けの発想だろう。
例1 14
0〜16383
4
0〜15
5
0〜31
5
0〜31
6
0〜63
6
0〜63
40 もし今、決めろと言われればこのようなフォーマットも考えられる。だいたい40bitsもあれば当面困ることはないだろう。たった8bitsの差でここまで楽になるのだから不思議な物である。

※例3は、0(1)〜52(53)週で1年の各週を区分けする方式で、工場の製品管理ではもっともポピュラーに使用される。
例2 14
0〜16383
9
経過日数
17
経過秒数
40
例3 14
0〜16383
6
3
5
0〜31
6
0〜63
6
0〜63
40
例4 西暦1970年よりの経過秒数
1970〜36811年、1秒単位
40

 

西暦2000年問題以外にある問題

 さて西暦1999年問題は上で触れたので、それ以外の問題について考えてみよう。

 まず、GPSの問題。 ぐろーばる・ぽじしょにんぐ・しすてむ、まあ日本語にすれば全地球測位システムだが、近年はカーナビゲーションシステムに応用され、非常に素晴らしい物となっている。このシステムは、複数個の衛星から発信された「時刻、衛星の位置情報、その電波を実際に受信した時間差」から計算により自分の居る位置をはじき出すのだが、この衛星が発信している日時情報(第何週目の何日目で日を表す)は西暦1999年8月22日に1023週目から0週目に戻る。これがTHE GPS WEEK 1024 ROLLOVER。

 さてロールオーバーしちゃったらどうすんのか? そりゃ1024週ごとに起こるロールオーバーはGPS測位機のファームウエア設計時に考慮されており、ロールオーバー後も正常に機能するように設計するのが正しい。が、世の中、失敗してからじゃないと気がつかない事はかなり多い。1999年8月22日はGPSにとって初めてのロールオーバー。失敗しちゃったメーカーがあんのよ。その影響とはGPSをよく知っている人の話では

などが考えられるそうだ。

 次にUNIX。さてUNIXとは何でしょう? 一般庶民が触れることは実際にはないにせよ、毎日の生活に必要なシステムUNIX。たとえば今をときめくインターネットを支えるサーバーコンピューターを動かしているのは主にUNIX。またUNIXを作るために作られたC言語でプログラムした場合も、基本思想はある意味においてUNIXと同じと言える。

 さて、この一番縁遠いようで身近なシステムUNIXが何をしてくれるか。それは変数time_tの桁あふれ、つまり2038年以降の日時をまともに計算してくれなくなる。具体的には変数time_tはsigned longという数値構造を持っており、2進数で

00000000 00000000 00000000 00000000b 〜
01111111 11111111 11111111 11111111b (最後のbは2進数ですという意味)が正の数。

簡単には32桁のうち最初の1桁が0だと正の数、1だと負の数(マイナス)を表します。これを念頭に

01111111 11111111 11111111 11111111b +1とするとどうなるか? 答えは

10000000 00000000 00000000 00000000b

となりこれは「-214783647」を表す。(こういうのを2の補数表現という)

 さて、2038年のある秒に+1秒したら1970年の約68年前になっちゃった? これではまともに計算ができる訳ないよねぇ(笑)

 

西暦2000年問題とは無縁の世界

 さて、私たちの身近な物で電波時計というものがある。これは民生用として広く売られている時計で、茨城県猿島郡三和町から発信される標準電波(JG2AS:周波数40kHzで時刻情報を流している試験局)を受信して時間を補正する機能を有する時計である。さてこの電波は2000年になったらどうなるのであろう。きっと4桁で情報を送っているのだろうって? いやいや、単純に年の情報がないだけなのである(笑)

 このように「年」情報を持たないシステムや元々カレンダー機能を必要としないシステム、時刻情報のみが必要なシステムなどでは2000年以降も問題なく動作するのである。また、エレベーターなどで採用されている経過時間カウンターでも2000年問題とは無縁である。(ただしより高度なメンテナンスを行うために日時情報を使用する物も中にはあると思われる)

(日本ではエレベーターは法定時間を超えても無メンテナンスの場合に使用を中止する義務があるため、経過時間をカウントするエレベーターもある。もちろん使用中に経過時間がオーバーしようが、客を降ろしてから使用中止になるように設計されているので、2000年問題が発生しようが閉じこめられる事は無い。Y2Kによる停電になったら元も子もないので乗らないことに越したことはないが…。)

 

各システムにおけるカタストロフィーな日々

ダメになる日時 システム 原因
1999-01-01
04-09
09-09
アプリケーション 99という年の数字に特殊な意味(永遠・未定など)を持たせているプログラムが正しい処理を行えなくなる。
1999-08-22
00:00:00
(UTC)
GPSを使用した機器 GPS(全地球測位システム)は1980-01-06から1024週間目(2の10乗)に当たるこの日、時計のカウンターが0週間目に戻ってしまう「週のロールオーバー」を運用開始より初めて起こす。このために1980年と勘違いした機器が異常を来し、使い物にならなくなってしまう可能性がある。

平成10年12月16日付けの朝日新聞ではパイオニア製カーナビゲーションシステムのうち1996年までに製造された物についてはICの交換が必要だそうだ。
※ロールオーバー後になって、当初は「対応」とされた松下製品にも欠陥が発覚した。
2000-01-01 全てのシステムに及ぶ 西暦を下2桁で管理している機器が1900年と2000年を区別することが出来なくなる問題。生産・物流・航空・陸運・海運・軍事・情報・通信・金融・・・様々な分野の全ての文明システムが機能不全に陥る危険性を孕む20世紀最後の大問題。
2000-02-29 アプリケーション 閏年を正しく理解していないプログラマーによる物は、この日以降異常を来す危険性がある。
2000-03-31 アプリケーション 決算期末処理などのために1年に一度しか起動しないプログラムが起動する日。バグがあれば2000年に入って初めて起動したこの日に、2000年問題の洗礼を受けることとなる。米国などは8月31日になる。
2000-08-31 アプリケーション 同上。
2038-01-19
03:14:08
(UTC)
UNIX・C言語など 1970-01-01 00:00(UTC)からの経過秒数が2の31乗(2,147,483,648=2039-1-19 03:14:07UTC)を越え、C言語の時間変数time_tが桁あふれを起こす。
  私がこの問題に気がついたときにTurboCで検証を行ったがやはりおかしくなった。 この問題はtime_tがsigned longと定義されているためにこの日に発生する。将来的には変数time_tを廃止し新たなる関数を定義する物と思われるが旧来のプログラムはダメだろう。
2079-01-01 Excel95 Microsoft Excel 95 はこの日を境に使用不可に・・・数万円もする割には馬鹿なのね。
2080-01-01 MS-DOS・WIndows95 初期のMS-DOSではこれ以降は仕様上不定となる。Windows95では一部機能が異常になるようだ。もっとも2080年にはWindows直系のシステム自体が存在しないだろうから、ファイルデータの更新日情報さえどうにかすれば問題ないだろう。
2100-01-01 MS-DOS・Windows98 後期のMS-DOSではこれ以降は仕様上不定となる。Windows98では時計管理が不能に。(2099-12-31を過ぎても12-31に戻ってしまう) PC/AT互換機の限界とも言える。
2108-01-01 MS-DOS MS-DOSアプリケーションの一部ではここまで対応する物もあるようだ。もっともOSが正式にサポートしているわけではないので理論上の最大延命期間。

※日本時間=UTC(協定世界時)+9時間


[ index ]