(C)裏目小僧
(戻る)
ほんとの2000年問題対策って?
2000年対策と称して、
ってなコードを追加しただけなんてのが結構ありそうだ。(注1)
当然、これでは2050年に破綻する。
言い訳は知っている。
  1. 西暦を4桁にするだけの記憶域が無いのだよ。
  2. 後50年もすればハードが壊れるから、作り直せばいいじゃない。
しかし、こんなコードは知ってて手抜きしてるか、無知の産物! チャンと何年でも使える対策方法はあったのだ。
え? LimitYYを2001年に51にして 2002年に52にしてって? ...ダメダメ もっとスマートな方法があるよ

移動窓方式
座標のように本来は無限に続く、だけど今を基準にその前後だけを記述出来れば良い場合、相対表現と移動窓表現という2つの手法が使える。
たとえば、西暦2桁で年を表現する。その範囲を絶対座標から前後50年とする。

移動窓方式の実際のコード
 2桁xx年をyyyy絶対年±50年に変換する
 
■pascal(delphi)
	
//理屈通りに書くと function YYtoYYYY(xx,yyyy:integer):integer; begin xx := ( xx + 100 - ( yyyy mod 100 ) ) mod 100; if xx>( 100 div 2 ) then xx := xx-100; result := yyyy + xx; end; //3万年先迄使用出来れば十分ならばもっと簡単に function YYtoYYYY(xx,yyyy:integer):integer; begin yyyy := yyyy - (100 div 2); result := yyyy + ( (xx + 32000 - yyyy ) mod 100); end;
■C
/* 理屈通りに移動窓をコーデングすると */ int YYtoYYYY(int xx,int yyyy) { xx=( xx + 100 - (yyyy%100) ) % 100; if( xx > (100 / 2) ) xx -= 100; return yyyy + xx; } /*3万年先迄使用出来れば十分ならば、*/ int YYtoYYYY(int xx,int yyyy) { yyyy -= 100/2; return yyyy+ ( ( xx + 32000 - yyyy ) % 100 ); } もし移動窓をchar(8bitなら -128〜+127)とすれば 非常に簡潔だ。 int yWtoYYYY(char yW,int yyyy) { char y8f = yW - yyyy; return yyyy + y8f; }

え?「この方法だと同じ 50って数字が 当年が2000年なら 1950年で 来年には2050年になるじゃないか」って?
それで問題あるかい? 問題あるなら最初から2桁ってのが間違いなんだよ。
誕生日の記録なら最初から2桁ってのが間違ってるよね? だって100才以上の人って大勢居るんだから
でも、製造日の記録なら、20年も同じ場所に保存される事はないでしょう?
せいぜい数年で、記録として別の場所に移される
そんな記録には年が2桁でも十分使えるし、使えたんじゃない。



え?「この方法だと大小比較出来ない」って?
そんな事はないよ。4桁年に変換してから比較すりゃいいし、差が小さければ移動窓で表現された値をモジュラ数として扱えばいいんだよ

YY年と XX年の差は ((YY-XX+100+50) mod 100)-50とすれば求まる


2のべき乗の移動窓ならもっと簡単だ。mod を and で代用出来る。
char/int のようなサイズ丁度の移動ならもっともっと簡単だ。単に引算して判定すればいいだけだからね。



応用問題
MS/DOSのファイル日付の問題がある。 これは 7bitで 1980年からの日付を表現している。
少し前は、2079年でファイル日付はエラーになった。
さらに、MSDOSなら現在の所、2100年の日付には出来ない。
アプリ側ではこれはどうしようも無い問題として捨てても良いだろう。

しかし、それでも100年動かしたいと言われたら、日付管理を自分でするしかあるまい。
困った事に2000年は閏年だ。つまり100年日付を戻した場合、閏日を処理しなければならない。
パソコンの管理してる曜日との差から調整するような事が必要になるだろう。


本資料参照数 =