コントロールパネル「地域と言語」と日付の書式指定文字列

先日ちょっと嵌ったので、以下備忘録です。
以下のコード、日付の書式指定文字列で「yyyy」を指定すると、四桁で西暦の年数を返却しますよね。

class Program {
    static void Main(string[] args) {
        Console.WriteLine( DateTime.Now.ToString("yyyy") );
    }
}

結果:2014


ところがコントロールパネルから「地域と言語」を起動し「追加の設定」をクリック。


「形式のカスタマイズ」で「日付」タブに遷移し「カレンダーの種類」を「和暦」に変更した場合、書式指定文字列に「yyyy」を指定しても、和暦の年数が返されます。今年(2014年)なら平成26年の「26」を返却します。

class Program {
    static void Main(string[] args) {
        // カレンダーを和暦に変更後
        Console.WriteLine( DateTime.Now.ToString("yyyy") );
    }
}

結果:26

この挙動、初めて知ったのでたいへん焦りました(汗


そこで対処法として、新たに既定の日本語カルチャを生成して、現在のスレッドに結び付けます。CultureInfo のコンストラクタの第二パラメータに false を指定すると、ユーザーが設定したカルチャでなく、既定のカルチャを使用します。これでユーザーが設定したカルチャに引きずられなくなります。

using System;
using System.Globalization;
using System.Threading;

class Program {
    static void Main(string[] args) {
        // カレンダーが和暦に変更されてるので、
        // システムのカルチャではなく既定のカルチャを使用する
        // false を指定しないと、ユーザーが設定したカルチャを使うので注意
        var ci = new CultureInfo("ja-JP", false);
        Thread.CurrentThread.CurrentCulture = ci;

        // GUIアプリケーションなら以下の設定も必要
        // Thread.CurrentThread.CurrentUICulture = ci;

        Console.WriteLine( DateTime.Now.ToString("yyyy") );
    }
}

結果:2014

CurrentThread のカルチャ設定はアプリケーション全体で有効になるので、WPF なら Application.Startup イベント等で設定しておけばいいでしょう。

以上、おそまつさまでした。