sh1’s diary

プログラミング、読んだ本、資格試験、ゲームとか私を記録するところ

新しい元号はどのように追加されて C# ではどんな影響があるか

この記事は、C# その2 Advent Calendar 2018 の5日目の記事です。

平成は 2019 年の4月末までありますが、この年の瀬のタイミングで整理しておきたく存じます。(追記:新しい元号は「令和」でしたね)
ちなみに、平成が終わるタイミングは、今上天皇 125代の退位により終了する予定らしいです。2019年(平成31年)04月30日 までが平成で 05月01日 から新元号になる予定です。

Handling a new era in the Japanese calendar in .NET - .NETBlog 」の記事が Microsoft のブログで公開されました。とてもよいまとめになっているので、ここをチェックするのが一番正確かも。

2019年04月04日の追記

元号の一覧を表示するプログラム

改めて書いてみた。元号の ID を取得して、それに対応するテキストを取得します。
元号の取得形式は「平成」のような形と「平」のような省略形があるようです。
それぞれ、下記のコードで一覧を取得することが可能です。

public IEnumerable<string> GetEraNames()
{
    var cultureInfo = new CultureInfo("ja-JP", true);
    cultureInfo.DateTimeFormat.Calendar = new JapaneseCalendar();

    var eras = cultureInfo.DateTimeFormat.Calendar.Eras;
    var eraNames = new List<string>();

    foreach (var era in eras)
    {
        eraNames.Add(cultureInfo.DateTimeFormat.GetEraName(era));
    }

    return eraNames;
}

public IEnumerable<string> GetAbbreviatedEraNames()
{
    var cultureInfo = new CultureInfo("ja-JP", true);
    cultureInfo.DateTimeFormat.Calendar = new JapaneseCalendar();

    var eras = cultureInfo.DateTimeFormat.Calendar.Eras;
    var eraNames = new List<string>();

    foreach (var era in eras)
    {
        eraNames.Add(cultureInfo.DateTimeFormat.GetAbbreviatedEraName(era));
    }

    return eraNames;
}

こんな感じの結果が出力されます。(新元号は下記のテストより「??」と表示されています)

f:id:shikaku_sh:20181203154744p:plain:w200

元号がどのように対応するのか

Microsoft日本の元号の変更について の記事に詳しいです。

まず、新元号は、Windows OS は 108.17 しか対応しないみたいですね。 XP や Vista や環境では駄目です。ここは注意が必要です。

移行のシナリオとしては、新しい元号レジストリの決まったキーに書き込まれます。それが以下のレジストリです。

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras

新しい元号をテストする方法も「新元号プレースホルダーのレジストリを個別に削除、追加する方法について」の記事で用意されています。えらい。

「add_new_jpera_placeholder」を実行して、レジストリエディタの内容を確認してみる。(実行の際は、注意のポップアップが表示されます)

f:id:shikaku_sh:20190403092418p:plainf:id:shikaku_sh:20181203155034p:plain
レジストリの編集

こんな感じに追加されました。
Windows OS 環境では、 C# のプログラムにおいて元号の情報は、このレジストリを参照しています。なので、この情報が「キモ」になるわけです。

新しい元号を確認してみる

レジストリに追加したキーがどのように動作するのか確認するサンプルのコードです。

static void Main(string[] args)
{
    while (true)
    {
        Console.Write("元号を調べる年月日を入力してください。(入力例 2019-05-01):");
        var inputText = Console.ReadLine();

        if (inputText == "exit") break;

        DateTimeOffset datetime;
        if (DateTimeOffset.TryParseExact(inputText, "yyyy-MM-dd", null, DateTimeStyles.AssumeLocal, out datetime))
        {
            var eraName = program.GetEra(datetime);
            Console.WriteLine($"{inputText} の元号は {eraName} です。");
        }
        else
        {
            Console.WriteLine($"{inputText} は、正しい年月日として認識できませんでした。");
        }

        Console.WriteLine("");
    }
    
}

public string GetEra(DateTimeOffset datetime)
{
    var cultureInfo = new CultureInfo("ja-JP", true);
    cultureInfo.DateTimeFormat.Calendar = new JapaneseCalendar();

    return datetime.ToString("gg", cultureInfo);
}

実行してみる。次のように 2019-05-01 から次の元号予定の「??」が出力できています。(「delete_new_jpera」を実行すると「??」は表示されなくなります。2019-05-01も「平成」に戻ってしまいます)

f:id:shikaku_sh:20181203160008p:plain
元号の確認

逆にいえば、対応しない OS も「add_new_jpera_placeholder」を正しいテキストに書き換えてあげれば、無理やり対応しそうな気がします。

まとめ

  • 新しい元号は「HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras」のレジストリーに追加される
  • C#レジストリーの情報を参照して元号変換している
  • 対応するクライアント OS は Windows 10, 8.1, 7 の3つだけ
  • 対応しないクライアント OS は、おそらく永遠の平成が続く

サンプル

「EraNameSample」というサンプルをあげています。

参考

Effective C# 6.0/7.0

Effective C# 6.0/7.0

プログラミングC# 第7版

プログラミングC# 第7版