2000年問題は過ぎたわけですが、これまた、いまだに年度に2桁をわたしてしまうコードが・・・
その場合、こんな危険が潜んでいますよ・・・・ということで・・
以下のC#のコードを実行した結果を予想してみてください。
Console.WriteLine(DateTime.Parse("00/01/01"));
Console.WriteLine(DateTime.Parse("29/01/01"));
Console.WriteLine(DateTime.Parse("30/01/01"));
Console.WriteLine(DateTime.Parse("99/01/01"));
答えはこちら(反転させてねー)
2000/01/01 0:00:00
2029/01/01 0:00:00
1930/01/01 0:00:00
1999/01/01 0:00:00
ほかにあやしいとこがないか、観察したい人は、0~100までループさせてみてくださいませ。
for (int i = 0; i < 100; i++)
{
Console.WriteLine("i=" + i.ToString() + ":"
+ DateTime.Parse(i.ToString() + "/01/01"));
}
いかがでしょうか
DateTime.Parse に対して、2桁の西暦を指定した場合、
00~29までは、2000年代
30~99までは、1900年代
として、扱われます。
理由は、.NET Framework 2.0 から加わった、2 桁表記の年を適切な 4 桁表記に変換する「TwoDigitYearMax」プロパティが、
グレゴリオ暦の場合、2029に設定されているため、このような結果になります。
Calendar.TwoDigitYearMax プロパティ
http://msdn.microsoft.com/ja-jp/library/system.globalization.calendar.twodigityearmax(VS.80).aspx
日付型にはその他にも、「COM 相互運用上の考慮事項」なんてのがあります。
Microsoft Visual Studio 2008/.NET Framework 3.5 .NET Framework クラス ライブラリ
DateTime 構造体http://msdn.microsoft.com/ja-jp/library/system.datetime.aspx以下、大切なことなので、24回引用します(ぉぃ
DateTime 値は、一度、COM アプリケーションに転送し、その後、再びマネージ アプリケーションに戻すことができます。これを "値がラウンドトリップした" と言います。しかし、DateTime 値に時刻しか指定されていないと、期待どおりに値がラウンドトリップしてくれません。
時刻だけ (たとえば、午後 3:00) をラウンドトリップさせた場合、最終的に返る日時は西暦 1899 年 12 月 30 日の午後 3:00 になります。西暦 0001 年 1 月 1 日の午後 3:00 とはなりません。これは、.NET Framework と COM とでは、時刻しか指定しなかった場合に用いられる既定の日付が異なるためです。COM システムでは基準となる日付を西暦 1899 年 12 月 30 日と想定しているのに対し、.NET Framework では西暦 0001 年 1 月 1 日が想定されています。
.NET Framework から COM に時刻しか渡さなかった場合、COM 用の時刻形式に変換するための特殊な処理が実行されます。COM から .NET Framework に時刻だけを渡した場合、特殊な処理は実行されません。特殊な処理を適用すると、1899 年 12 月 30 日以前の日時情報が正しく維持されないためです。逆に言えば、日付を COM からラウンドトリップさせた場合は、.NET Framework と COM 間でその日付が維持されることになります。
.NET Framework と COM における、こうした動作の違いを正しく理解することが大切です。時刻情報だけを指定した DateTime をラウンドトリップさせる場合、最終的に返された DateTime オブジェクトに対し、誤った日付を修正するか無視する処理をアプリケーション側で実装する必要があります。