元号改正? 新しい元号の情報が増えるだけじゃん?
ここ最近エンジニア界隈を賑わせている改元問題ですが、
1. レジストリに新しい元号の情報が追加される
2. Unicode文字に新しい元号記号が追加される
環境自体の変更はこの程度だろうと思っていた、そんな時期が私にもありました。
はじめに
私は現在データエントリー用のAP開発に携わっています。
紙に書かれた情報をデータ化する際に、タイプミスなどのヒューマンエラーは付き物です。
そのため、不正な入力が行われていないかチェックする機能が備わっています。
その機能の一つが「日付の実在チェック」であり、
- 2016/2/29 : 実在するのでOK
- 2018/2/29 : 実在しないのでNG
- 昭和60年4月1日 : 実在するのでOK
- 昭和99年4月1日 : 実在しないのでNG
このような挙動となるよう実装されています。
西暦、和暦両方に対応しており、和暦で記述された場合は内部処理で西暦に変換しています。
西暦変換部だけを抜き出して記述すると、次のようになります。
string strDate = "昭和60年4月1日";
CultureInfo ci = CultureInfo.CreateSpecificCulture("ja-JP");
DateTime dt = DateTime.Parse(strDate, ci, DateTimeStyles.None);
Console.WriteLine(dt.ToString("yyyy/MM/dd"));
// 1985/04/01
「昭和99年4月1日」などの実在しない和暦の日付を西暦に変換すると「DateTime.Parse」処理で例外が発生するため、例外発生時は一律チェック結果をNGとして処理しています。
try
{
string strDate = "昭和99年4月1日";
CultureInfo ci = CultureInfo.CreateSpecificCulture("ja-JP");
DateTime dt = DateTime.Parse(strDate, ci, DateTimeStyles.None);
// 例外発生
Console.WriteLine(dt.ToString("yyyy/MM/dd"));
:
}
catch
{
// 例外発生時はチェックNG
}
問題となる挙動
上記の処理を実行した時、突然西暦変換が成功するようになりました。
string strDate = "昭和99年4月1日";
CultureInfo ci = CultureInfo.CreateSpecificCulture("ja-JP");
DateTime dt = DateTime.Parse(strDate, ci, DateTimeStyles.None);
Console.WriteLine(dt.ToString("yyyy/MM/dd"));
// 2024/04/01
この不具合によって例外処理が想定通りに行われず、チェック機能が正しく動作しなくなってしまいました。
(下記の対処法が分かるまでは、AP改修が入ると思って本気で焦りました…)
原因と対処法
最近の.NET Frameworkのアップデートにより、和暦日付の文字列から日付オブジェクトへの変換仕様が変わったことが原因のようです。
昭和だけでなく、「大正50年」「平成80年」なども例外が発生することなく日付オブジェクトへ変換できます。
(元号がギリギリのタイミングで公開されることから、当面の間「平成32年」のような表記を許容する、という国の方針を踏まえた改修と思われます)
アップデート自体はWindows10を対象に、米国時間7/10(火)にリリースされています。
他バージョンについては名言されていませんが、順次リリースされているものと思われます。
(ちなみに、自分のPCはWindows7 Enterprise 64bitです)
また対処方法についてですが、
- .NET Framework 4.6以降ではAP構成ファイル(*.exe.config)の編集
- .NET Framework 4.5.2以前ではレジストリの変更
を行うことで従来の挙動に戻すことができるようです。
詳しくはこちらの記事をご覧ください。
おわりに
システムを新元号に対応させるだけでなく、従来の元号に対して正しく処理が行えるかも併せて確認する必要があると感じました。
しかし、元号周知が改元の1ヶ月前って本当なんなんですかね。得してる人いるんですかね。
対応に追われるエンジニアの皆様、お互い頑張ってまいりましょう。