CultureInfo クラス

この記事では、この API のリファレンス ドキュメントを補足して解説します。

CultureInfo クラスは、言語、サブ言語、国や地域、カレンダー、特定のカルチャに関連付けられている規則など、カルチャ固有の情報を提供します。 このクラスでは、DateTimeFormatInfoNumberFormatInfoCompareInfoTextInfo オブジェクトのカルチャ固有のインスタンスへのアクセスも提供されます。 これらのオブジェクトには、大文字と小文字の区別、日付と数値の書式設定、文字列の比較など、カルチャ固有の操作に必要な情報が含まれています。 CultureInfo クラスは、StringDateTimeDateTimeOffset、数値型など、カルチャ固有のデータを書式設定、解析、または操作するクラスによって直接または間接に使われます。

カルチャ名と識別子

CultureInfo クラスは、RFC 4646 に基づくカルチャごとに一意の名前を指定します。 名前は、ISO 639 の言語に関連付けられた 2 文字または 3 文字の小文字のカルチャ コードと、ISO 3166 の国または地域に関連付けられた 2 文字の大文字のサブカルチャ コードの組み合わせです。 さらに、Windows 10 以降で実行されているアプリでは、有効な BCP-47 言語タグに対応するカルチャ名がサポートされます。

Note

カルチャ名をクラス コンストラクターまたは CreateSpecificCultureCultureInfoなどのメソッドに渡すとき、大文字と小文字は区別されません。

RFC 4646 に基づくカルチャ名は languagecode2-country/regioncode2 という形式であり、languagecode2 は 2 文字の言語コード、country/regioncode2 は 2 文字のサブカルチャ コードです。 たとえば、日本語 (日本) は ja-JP、英語 (米国) は en-US です。 2 文字の言語コードを使用できない場合は、ISO 639-3 で定義されている 3 文字のコードが使われます。

一部のカルチャ名では、ISO 15924 スクリプトも指定されます。 たとえば、Cyrl はキリル スクリプトを指定し、Latn はラテン スクリプトを指定します。 スクリプトを含むカルチャ名では、languagecode2-scripttag-country/regioncode2 というパターンが使われます。 この種のカルチャ名の例としては、ウズベク語 (キリル文字、ウズベキスタン) の uz-Cyrl-UZ があります。 Windows Vista より前の Windows オペレーティング システムでは、スクリプトを含むカルチャ名には languagecode2-country/regioncode2-scripttag というパターンが使われます (例: ウズベク語 (キリル文字、ウズベキスタン) に対する uz-UZ-Cyrl)。

ニュートラル カルチャは、2 文字の小文字の言語コードだけで指定されます。 たとえば、fr はフランス語のニュートラル カルチャを指定し、de はドイツ語のニュートラル カルチャを指定します。

Note

この規則に従わないカルチャ名が 2 つあります。 zh-Hans という名前の中国語 (簡体字) と、zh-Hant という名前の中国語 (繁体字) のカルチャはニュートラル カルチャです。 これらのカルチャ名は現在の標準を表しており、古い名前である zh-CHSzh-CHT を使う理由がない限り、これらを使う必要があります。

カルチャ識別子は標準の国際数値省略形であり、インストールされているカルチャの 1 つを一意に識別するために必要なコンポーネントが含まれます。 アプリケーションでは、定義済みのカルチャ識別子を使うことも、カスタム識別子を定義することもできます。

System.Globalization 名前空間内のこのクラスと他のクラスでは、定義済みの特定のカルチャ名と識別子が使われます。 Windows システムの詳細なカルチャ情報については、Windows でサポートされている言語と地域の名前の一覧の「言語タグ」列をご覧ください。 カルチャ名は、BCP 47 によって定義されている標準に準拠します。

カルチャ名と識別子は、特定のコンピューターで見つかるカルチャのサブセットのみを表します。 Windows のバージョンまたはサービス パックにより、使用できるカルチャが変わる可能性があります。 アプリケーションでは、CultureAndRegionInfoBuilder クラスを使ってカスタム カルチャを追加できます。 ユーザーは、Microsoft Locale Builder ツールを使って、独自のカスタム カルチャを追加できます。 Microsoft Locale Builder は、CultureAndRegionInfoBuilder クラスを使ってマネージド コードで記述されています。

複数の異なる名前が、カルチャに密接に関連付けられています。特に重要なのは、次のクラス メンバーに関連付けられている名前です。

インバリアント、ニュートラル、および特定のカルチャ

一般に、カルチャは、インバリアント カルチャ、ニュートラル カルチャ、特定のカルチャの 3 つのセットにグループ化されます。

インバリアント カルチャはカルチャに依存しません。 アプリケーションでは、空の文字列 ("") を使用する名前またはその識別子によって、インバリアント カルチャを指定します。 InvariantCulture は、インバリアント カルチャのインスタンスを定義します。 これは英語に関連付けられていますが、どの国や地域にも関連付けられていません。 これは、カルチャを必要とする Globalization 名前空間のほぼすべてのメソッドで使われます。

ニュートラル カルチャは、言語に関連付けられていますが、国や地域には関連付けられていないカルチャです。 特定のカルチャは、言語と国または地域に関連付けられているカルチャです。 たとえば、fr はフランス後カルチャのニュートラル名で、fr-FR は特定のフランス語 (フランス) カルチャの名前です。 中国語 (簡体字) と中国語 (繁体字) もニュートラル カルチャと見なされることに注意してください。

含まれるデータが任意になるため、ニュートラル カルチャ用に CompareInfo クラスのインスタンスを作成することはお勧めしません。 データの表示と並べ替えを行うには、言語と地域の両方を指定します。 さらに、ニュートラル カルチャ用に作成された CompareInfo オブジェクトの Name プロパティは、国のみを返し、地域は含まれません。

定義されたカルチャには階層があり、階層内では、特定のカルチャの親はニュートラル カルチャで、ニュートラル カルチャの親はインバリアント カルチャです。 Parent プロパティには、特定のカルチャに関連付けられたニュートラル カルチャが含まれます。 カスタム カルチャでは、このパターンに従って Parent プロパティを定義する必要があります。

特定のカルチャのリソースをオペレーティング システムで利用できない場合は、関連付けられたニュートラル カルチャのリソースが使われます。 ニュートラル カルチャのリソースを利用できない場合は、メイン アセンブリに埋め込まれているリソースが使われます。 リソースのフォールバック プロセスについて詳しくは、リソースのパッケージ化と展開に関する記事をご覧ください。

Windows API でのロケールの一覧は、.NET でサポートされるカルチャの一覧と少し異なります。 たとえば、P/Invoke メカニズムを介した Windows との相互運用性が必要な場合、アプリケーションではオペレーティング システム用に定義された特定のカルチャを使う必要があります。 特定のカルチャを使うと、LCID と同じロケール識別子によって識別される、同等の Windows ロケールとの一貫性が確実に実現されます。

DateTimeFormatInfo または NumberFormatInfo は、インバリアント カルチャまたは特定のカルチャに対してのみ作成でき、ニュートラル カルチャに対しては作成できません。

DateTimeFormatInfo.CalendarTaiwanCalendar であるのに、Thread.CurrentCulturezh-TW に設定されていない場合、DateTimeFormatInfo.NativeCalendarNameDateTimeFormatInfo.GetEraNameDateTimeFormatInfo.GetAbbreviatedEraName は空の文字列 ("") を返します。

カスタム カルチャ

Windows では、カスタム ロケールを作成できます。 詳しくは、「カスタム ロケール」をご覧ください。

CultureInfo とカルチャ データ

.NET のカルチャ データは、実装、プラットフォーム、バージョンに応じて、さまざまなソースの 1 つから取得されます。

  • Unix プラットフォームまたは Windows 10 以降のバージョンで実行されているすべてのバージョンの .NET (Core) では、カルチャ データは International Components for Unicode (ICU) ライブラリによって提供されます。 ICU ライブラリの特定のバージョンは、個々のオペレーティング システムによって異なります。
  • Windows 9 以前のバージョンで実行されているすべてのバージョンの .NET (Core) では、カルチャ データは Windows オペレーティング システムによって提供されます。
  • .NET Framework 4 以降のバージョンでは、カルチャ データは Windows オペレーティング システムによって提供されます。

このため、.NET の特定の実装、プラットフォーム、またはバージョンで利用できるカルチャが、.NET の別の実装、プラットフォーム、またはバージョンでは利用できないことがあります。

一部の CultureInfo オブジェクトは、基になるプラットフォームによって異なります。 特に、zh-CN つまり中国語 (簡体字、中国) と zh-TW つまり中国語 (繁体字、台湾) は、Windows システムではカルチャとして利用できますが、Unix システムでは別名のカルチャです。 "zh-CN" は "zh-Hans-CN" カルチャの別名であり、"zh-TW" は "zh-Hant-TW" カルチャの別名です。 別名のカルチャは、GetCultures メソッドの呼び出しから返されず、Parent カルチャなどのプロパティの値が、Windows の対応するプロパティとは異なる場合があります。 zh-CNzh-TW カルチャの場合、このような違いには次のものが含まれます。

  • Windows システムでは、"zh-CN" カルチャの親カルチャは "zh-Hans" で、"zh-TW" カルチャの親カルチャは "zh-Hant" です。 これらのカルチャの親カルチャはどちらも "zh" です。 Unix システムでは、両方のカルチャの親は "zh" です。 つまり、"zh-CN" または "zh-TW" カルチャに対してカルチャ固有のリソースを提供せず、ニュートラル カルチャ "zh-Hans" または "zh-Hant" に対してリソースを提供した場合、アプリケーションは Windows ではニュートラル カルチャのリソースを読み込みますが、Unix では読み込みません。 Unix システムでは、スレッドの CurrentUICulture を "zh-Hans" または "zh-Hant" に明示的に設定する必要があります。

  • Windows システムでは、"zh-CN" カルチャを表すインスタンスで CultureInfo.Equals を呼び出し、それを "zh-Hans-CN" インスタンスに渡すと、true が返されます。 Unix システムでは、このメソッドの呼び出しからは false が返されます。 この動作は、"zh-TW" の CultureInfo のインスタンスで Equals を呼び出してそれを "zh-Hant-Tw" インスタンスに渡す場合にも当てはまります。

動的カルチャ データ

インバリアント カルチャ以外のカルチャ データは動的です。 これは、定義済みのカルチャに対しても当てはまります。 たとえば、国や地域で新しい通貨の採用、単語のスペルの変更、または優先カレンダーの変更が行われると、それに合わせてカルチャの定義が変更されます。 カスタム カルチャは予告なしに変更される可能性があり、特定のカルチャはカスタム置換カルチャによってオーバーライドされる場合があります。 また、以下で説明するように、個々のユーザーはカルチャの優先設定をオーバーライドできます。 アプリケーションでは、常に、実行時にカルチャ データを取得する必要があります。

注意

データを保存するとき、アプリケーションでは、インバリアント カルチャ、バイナリ形式、または特定のカルチャに依存しない形式を使う必要があります。 インバリアント カルチャ以外の特定のカルチャに関連付けられている現在の値に従って保存されたデータは、そのカルチャが変更された場合、読み取れなくなったり、意味が変わったりする可能性があります。

現在のカルチャと現在の UI カルチャ

.NET アプリケーション内のすべてのスレッドには、現在のカルチャと現在の UI カルチャがあります。 現在のカルチャによって、日付、時刻、数値、通貨値の書式設定規則、テキストの並べ替え順序、大文字と小文字の表記規則、文字列の比較方法が決まります。 現在の UI カルチャは、実行時にカルチャ固有のリソースを取得するために使われます。

Note

現在のカルチャと現在の UI カルチャがスレッドごとにどのように決定されるかについては、「カルチャとスレッド」セクションをご覧ください。 新しいアプリケーション ドメインで実行されるスレッド、およびアプリケーション ドメインの境界をまたがるスレッドで、現在のカルチャと現在の UI カルチャがどのように決定されるかについては、「カルチャとアプリケーション ドメイン」セクションをご覧ください。 タスク ベースの非同期操作を実行するスレッドで、現在のカルチャと現在の UI カルチャがどのように決定されるかについては、「カルチャとタスク ベースの非同期操作」セクションをご覧ください。

現在のカルチャについて詳しくは、CultureInfo.CurrentCulture プロパティを参照してください。 現在の UI カルチャについて詳しくは、CultureInfo.CurrentUICulture プロパティのトピックを参照してください。

現在のカルチャと現在の UI カルチャを取得する

現在のカルチャを表す CultureInfo オブジェクトは、2 つの方法のいずれかで取得できます。

次の例では、両方のプロパティの値を取得し、比較して等しいことを示し、現在のカルチャの名前を表示します。

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

public class CurrentCultureEx
{
    public static void Main()
    {
        CultureInfo culture1 = CultureInfo.CurrentCulture;
        CultureInfo culture2 = Thread.CurrentThread.CurrentCulture;
        Console.WriteLine("The current culture is {0}", culture1.Name);
        Console.WriteLine("The two CultureInfo objects are equal: {0}",
                          culture1 == culture2);
    }
}
// The example displays output like the following:
//     The current culture is en-US
//     The two CultureInfo objects are equal: True

現在の UI カルチャを表す CultureInfo オブジェクトは、2 つの方法のいずれかで取得できます。

次の例では、両方のプロパティの値を取得し、比較して等しいことを示し、現在の UI カルチャの名前を表示します。

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

public class CurrentUIEx
{
    public static void Main()
    {
        CultureInfo uiCulture1 = CultureInfo.CurrentUICulture;
        CultureInfo uiCulture2 = Thread.CurrentThread.CurrentUICulture;
        Console.WriteLine("The current UI culture is {0}", uiCulture1.Name);
        Console.WriteLine("The two CultureInfo objects are equal: {0}",
                          uiCulture1 == uiCulture2);
    }
}
// The example displays output like the following:
//     The current UI culture is en-US
//     The two CultureInfo objects are equal: True

現在のカルチャと現在の UI カルチャを設定する

スレッドのカルチャと UI カルチャを変更するには、次のようにします。

  1. CultureInfo クラスのコンストラクターを呼び出して、カルチャの名前を渡すことにより、そのカルチャを表す CultureInfo オブジェクトをインスタンス化します。 新しいカルチャが現在の Windows カルチャと同じ場合、CultureInfo(String) コンストラクターはユーザーのオーバーライドを反映する CultureInfo オブジェクトをインスタンス化します。 CultureInfo(String, Boolean) コンストラクターを使うと、新しいカルチャが現在の Windows カルチャと同じ場合に、新しくインスタンス化される CultureInfo オブジェクトがユーザーのオーバーライドを反映するかどうかを指定できます。

  2. .NET Core と .NET Framework 4.6 以降のバージョンでは、CultureInfo オブジェクトを CultureInfo.CurrentCulture または CultureInfo.CurrentUICulture プロパティに割り当てます。

次の例では、現在のカルチャを取得します。 フランス語 (フランス) カルチャ以外の場合は、現在のカルチャをフランス語 (フランス) に変更します。 そうでない場合は、現在のカルチャをフランス語 (ルクセンブルク) に変更します。

using System;
using System.Globalization;

public class ChangeEx1
{
    public static void Main()
    {
        CultureInfo current = CultureInfo.CurrentCulture;
        Console.WriteLine("The current culture is {0}", current.Name);
        CultureInfo newCulture;
        if (current.Name.Equals("fr-FR"))
            newCulture = new CultureInfo("fr-LU");
        else
            newCulture = new CultureInfo("fr-FR");

        CultureInfo.CurrentCulture = newCulture;
        Console.WriteLine("The current culture is now {0}",
                          CultureInfo.CurrentCulture.Name);
    }
}
// The example displays output like the following:
//     The current culture is en-US
//     The current culture is now fr-FR

次の例では、現在のカルチャを取得します。 スロベニア (スロベニア) カルチャ以外の場合は、現在のカルチャをスロベニア (スロベニア) に変更します。 そうでない場合は、現在のカルチャをクロアチア語 (クロアチア) に変更します。

using System;
using System.Globalization;

public class ChangeUICultureEx
{
    public static void Main()
    {
        CultureInfo current = CultureInfo.CurrentUICulture;
        Console.WriteLine("The current UI culture is {0}", current.Name);
        CultureInfo newUICulture;
        if (current.Name.Equals("sl-SI"))
            newUICulture = new CultureInfo("hr-HR");
        else
            newUICulture = new CultureInfo("sl-SI");

        CultureInfo.CurrentUICulture = newUICulture;
        Console.WriteLine("The current UI culture is now {0}",
                          CultureInfo.CurrentUICulture.Name);
    }
}
// The example displays output like the following:
//     The current UI culture is en-US
//     The current UI culture is now sl-SI

すべてのカルチャを取得する

GetCultures メソッドを呼び出すと、ローカル コンピューターで利用できる特定のカテゴリのカルチャまたはすべてのカルチャの配列を取得できます。 たとえば、カスタム カルチャ、特定のカルチャ、またはニュートラル カルチャを単独で、または組み合わせて取得できます。

次の例では、GetCultures メソッドを 2 回呼び出して、最初は System.Globalization.CultureTypes 列挙メンバーを使ってすべてのカスタム カルチャを取得し、次に System.Globalization.CultureTypes 列挙メンバーを使ってすべての置換カルチャを取得しています。

using System;
using System.Globalization;

public class GetCulturesEx
{
    public static void Main()
    {
        // Get all custom cultures.
        CultureInfo[] custom = CultureInfo.GetCultures(CultureTypes.UserCustomCulture);
        if (custom.Length == 0)
        {
            Console.WriteLine("There are no user-defined custom cultures.");
        }
        else
        {
            Console.WriteLine("Custom cultures:");
            foreach (var culture in custom)
                Console.WriteLine("   {0} -- {1}", culture.Name, culture.DisplayName);
        }
        Console.WriteLine();

        // Get all replacement cultures.
        CultureInfo[] replacements = CultureInfo.GetCultures(CultureTypes.ReplacementCultures);
        if (replacements.Length == 0)
        {
            Console.WriteLine("There are no replacement cultures.");
        }
        else
        {
            Console.WriteLine("Replacement cultures:");
            foreach (var culture in replacements)
                Console.WriteLine("   {0} -- {1}", culture.Name, culture.DisplayName);
        }
        Console.WriteLine();
    }
}
// The example displays output like the following:
//     Custom cultures:
//        x-en-US-sample -- English (United States)
//        fj-FJ -- Boumaa Fijian (Viti)
//
//     There are no replacement cultures.

カルチャとスレッド

新しいアプリケーション スレッドが開始されるときは、現在のスレッド カルチャではなく、現在のシステム カルチャによって、現在のカルチャと現在の UI カルチャが定義されます。 この違いを次の例に示します。 この場合、アプリケーション スレッドの現在のカルチャと現在の UI カルチャは、フランス語 (フランス) カルチャ (fr-FR) に設定されます。 現在のカルチャが既に fr-FR である場合、この例では英語 (米国) カルチャ (en-US) に設定されます。 通貨の値として 3 つの乱数が表示されてから、新しいスレッドが作成され、続いてさらに 3 つの乱数が通貨の値として表示されます。 しかし、例からの出力でわかるように、新しいスレッドで表示される通貨値には、メイン アプリケーション スレッドからの出力とは異なり、フランス語 (フランス) カルチャの書式設定規則が反映されていません。

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

public class DefaultThreadEx
{
    static Random rnd = new Random();

    public static void Main()
    {
        if (Thread.CurrentThread.CurrentCulture.Name != "fr-FR")
        {
            // If current culture is not fr-FR, set culture to fr-FR.
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("fr-FR");
            Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("fr-FR");
        }
        else
        {
            // Set culture to en-US.
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
            Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("en-US");
        }
        ThreadProc();

        Thread worker = new Thread(ThreadProc);
        worker.Name = "WorkerThread";
        worker.Start();
    }

    private static void DisplayThreadInfo()
    {
        Console.WriteLine("\nCurrent Thread Name: '{0}'",
                          Thread.CurrentThread.Name);
        Console.WriteLine("Current Thread Culture/UI Culture: {0}/{1}",
                          Thread.CurrentThread.CurrentCulture.Name,
                          Thread.CurrentThread.CurrentUICulture.Name);
    }

    private static void DisplayValues()
    {
        // Create new thread and display three random numbers.
        Console.WriteLine("Some currency values:");
        for (int ctr = 0; ctr <= 3; ctr++)
            Console.WriteLine("   {0:C2}", rnd.NextDouble() * 10);
    }

    private static void ThreadProc()
    {
        DisplayThreadInfo();
        DisplayValues();
    }
}
// The example displays output similar to the following:
//       Current Thread Name: ''
//       Current Thread Culture/UI Culture: fr-FR/fr-FR
//       Some currency values:
//          8,11 €
//          1,48 €
//          8,99 €
//          9,04 €
//
//       Current Thread Name: 'WorkerThread'
//       Current Thread Culture/UI Culture: en-US/en-US
//       Some currency values:
//          $6.72
//          $6.35
//          $2.90
//          $7.72

そのカルチャを表す CultureInfo オブジェクトを DefaultThreadCurrentCultureDefaultThreadCurrentUICulture プロパティに割り当てることで、アプリケーション ドメイン内のすべてのスレッドのカルチャと UI カルチャを設定できます。 次の例では、これらのプロパティを使って、既定のアプリケーション ドメイン内のすべてのスレッドが同じカルチャを確実に共有するようにしています。

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

public class SetThreadsEx
{
    static Random rnd = new Random();

    public static void Main()
    {
        if (Thread.CurrentThread.CurrentCulture.Name != "fr-FR")
        {
            // If current culture is not fr-FR, set culture to fr-FR.
            CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture("fr-FR");
            CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture("fr-FR");
        }
        else
        {
            // Set culture to en-US.
            CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
            CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture("en-US");
        }
        ThreadProc();

        Thread worker = new Thread(SetThreadsEx.ThreadProc);
        worker.Name = "WorkerThread";
        worker.Start();
    }

    private static void DisplayThreadInfo()
    {
        Console.WriteLine("\nCurrent Thread Name: '{0}'",
                          Thread.CurrentThread.Name);
        Console.WriteLine("Current Thread Culture/UI Culture: {0}/{1}",
                          Thread.CurrentThread.CurrentCulture.Name,
                          Thread.CurrentThread.CurrentUICulture.Name);
    }

    private static void DisplayValues()
    {
        // Create new thread and display three random numbers.
        Console.WriteLine("Some currency values:");
        for (int ctr = 0; ctr <= 3; ctr++)
            Console.WriteLine("   {0:C2}", rnd.NextDouble() * 10);
    }

    private static void ThreadProc()
    {
        DisplayThreadInfo();
        DisplayValues();
    }
}
// The example displays output similar to the following:
//       Current Thread Name: ''
//       Current Thread Culture/UI Culture: fr-FR/fr-FR
//       Some currency values:
//          6,83 €
//          3,47 €
//          6,07 €
//          1,70 €
//
//       Current Thread Name: 'WorkerThread'
//       Current Thread Culture/UI Culture: fr-FR/fr-FR
//       Some currency values:
//          9,54 €
//          9,50 €
//          0,58 €
//          6,91 €

警告

DefaultThreadCurrentCultureDefaultThreadCurrentUICulture プロパティは静的メンバーですが、それらによって定義されるのは、プロパティ値が設定された時点での現在のアプリケーション ドメインに対する既定のカルチャと既定の UI カルチャだけです。 詳しくは、次の「カルチャとアプリケーション ドメイン」セクションをご覧ください。

アプリケーション ドメイン内のスレッドのカルチャと UI カルチャにカルチャが明示的に割り当てられていない場合は、DefaultThreadCurrentCultureDefaultThreadCurrentUICulture プロパティに値を割り当てると、それらも変更されます。 ただし、これらのスレッドに新しいカルチャ設定が反映されるのは、それが現在のアプリケーション ドメインで実行されている間のみです。 これらのスレッドが別のアプリケーション ドメインで実行される場合、そのカルチャは、そのアプリケーション ドメインに対して定義されている既定のカルチャになります。 したがって、メイン アプリケーション スレッドのカルチャを常に設定し、DefaultThreadCurrentCultureDefaultThreadCurrentUICulture プロパティを使ってそれを変更しないことをお勧めします。

カルチャとアプリケーション ドメイン

DefaultThreadCurrentCultureDefaultThreadCurrentUICulture は、プロパティの値が設定または取得された時点での現在のアプリケーション ドメインに対してだけ既定のカルチャを明示的に定義する静的プロパティです。 次の例では、既定のアプリケーション ドメインの既定のカルチャと既定の UI カルチャをフランス語 (フランス) に設定した後、AppDomainSetup クラスと AppDomainInitializer デリゲートを使って、新しいアプリケーション ドメインの既定のカルチャと UI カルチャをロシア語 (ロシア) に設定しています。 その後、1 つのスレッドで各アプリケーション ドメインの 2 つのメソッドを実行します。 スレッドのカルチャと UI カルチャが明示的に設定されていないことに注意してください。これらは、スレッドが実行されているアプリケーション ドメインの既定のカルチャと UI カルチャから取得されます。 また、DefaultThreadCurrentCultureDefaultThreadCurrentUICulture プロパティからは、メソッド呼び出しが行われた時点での現在のアプリケーション ドメインの既定の CultureInfo 値が返されることにも注意してください。

using System;
using System.Globalization;

public class Example
{
    public static void Main()
    {
        // Set the default culture and display the current date in the current application domain.
        Info info1 = new Info();
        SetAppDomainCultures("fr-FR");

        // Create a second application domain.
        AppDomainSetup setup = new AppDomainSetup();
        setup.AppDomainInitializer = SetAppDomainCultures;
        setup.AppDomainInitializerArguments = new string[] { "ru-RU" };
        AppDomain domain = AppDomain.CreateDomain("Domain2", null, setup);
        // Create an Info object in the new application domain.
        Info info2 = (Info)domain.CreateInstanceAndUnwrap(typeof(Example).Assembly.FullName,
                                                           "Info");

        // Execute methods in the two application domains.
        info2.DisplayDate();
        info2.DisplayCultures();

        info1.DisplayDate();
        info1.DisplayCultures();
    }

    public static void SetAppDomainCultures(string[] names)
    {
        SetAppDomainCultures(names[0]);
    }

    public static void SetAppDomainCultures(string name)
    {
        try
        {
            CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture(name);
            CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture(name);
        }
        // If an exception occurs, we'll just fall back to the system default.
        catch (CultureNotFoundException)
        {
            return;
        }
        catch (ArgumentException)
        {
            return;
        }
    }
}

public class Info : MarshalByRefObject
{
    public void DisplayDate()
    {
        Console.WriteLine("Today is {0:D}", DateTime.Now);
    }

    public void DisplayCultures()
    {
        Console.WriteLine("Application domain is {0}", AppDomain.CurrentDomain.Id);
        Console.WriteLine("Default Culture: {0}", CultureInfo.DefaultThreadCurrentCulture);
        Console.WriteLine("Default UI Culture: {0}", CultureInfo.DefaultThreadCurrentUICulture);
    }
}
// The example displays the following output:
//       Today is 14 октября 2011 г.
//       Application domain is 2
//       Default Culture: ru-RU
//       Default UI Culture: ru-RU
//       Today is vendredi 14 octobre 2011
//       Application domain is 1
//       Default Culture: fr-FR
//       Default UI Culture: fr-FR

カルチャとアプリケーション ドメインについて詳しくは、「アプリケーション ドメイン」トピックの「アプリケーション ドメインとスレッド」セクションをご覧ください。

カルチャとタスク ベースの非同期操作

タスク ベースの非同期プログラミング パターンでは、TaskTask<TResult> オブジェクトを使って、スレッド プール スレッドでデリゲートが非同期に実行されます。 特定のタスクが実行される特定のスレッドは、事前には認識されず、実行時にのみ決定されます。

.NET Framework 4.6 以降のバージョンを対象とするアプリの場合、カルチャは非同期操作のコンテキストの一部です。 つまり、非同期操作は、起動元のスレッドの CurrentCultureCurrentUICulture プロパティの値を既定で継承します。 現在のカルチャまたは現在の UI カルチャがシステム カルチャと異なる場合は、現在のカルチャがスレッドの境界を越えて、非同期操作を実行しているスレッド プール スレッドの現在のカルチャになります。

簡単な例を次に示します。 この例では、通貨値として書式設定された数値を返す Func<TResult> デリゲート (formatDelegate) を定義しています。 この例では、現在のシステム カルチャがフランス語 (フランス) に変更されます。ただし、現在のカルチャがフランス語 (フランス) である場合は、英語 (米国) に変更されます。 それから:

  • メイン アプリ スレッドで同期的に実行されるように、デリゲートを直接呼び出します。
  • スレッド プール スレッドでデリゲートを非同期的に実行するタスクを作成します。
  • Task.RunSynchronously メソッドを呼び出して、メイン アプリ スレッドでデリゲートを同期的に実行するタスクを作成します。

例からの出力が示すように、現在のカルチャがフランス語 (フランス) に変更されると、タスクの呼び出し元のスレッドの現在のカルチャが、その非同期操作の現在のカルチャになります。

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

public class AsyncCultureEx1
{
    public static void Main()
    {
        decimal[] values = { 163025412.32m, 18905365.59m };
        string formatString = "C2";

        string FormatDelegate()
        {
            string output = $"Formatting using the {CultureInfo.CurrentCulture.Name} " +
            "culture on thread {Thread.CurrentThread.ManagedThreadId}.\n";
            foreach (decimal value in values)
                output += $"{value.ToString(formatString)}   ";

            output += Environment.NewLine;
            return output;
        }

        Console.WriteLine($"The example is running on thread {Thread.CurrentThread.ManagedThreadId}");
        // Make the current culture different from the system culture.
        Console.WriteLine($"The current culture is {CultureInfo.CurrentCulture.Name}");
        if (CultureInfo.CurrentCulture.Name == "fr-FR")
            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
        else
            Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");

        Console.WriteLine($"Changed the current culture to {CultureInfo.CurrentCulture.Name}.\n");

        // Execute the delegate synchronously.
        Console.WriteLine("Executing the delegate synchronously:");
        Console.WriteLine(FormatDelegate());

        // Call an async delegate to format the values using one format string.
        Console.WriteLine("Executing a task asynchronously:");
        var t1 = Task.Run(FormatDelegate);
        Console.WriteLine(t1.Result);

        Console.WriteLine("Executing a task synchronously:");
        var t2 = new Task<string>(FormatDelegate);
        t2.RunSynchronously();
        Console.WriteLine(t2.Result);
    }
}
// The example displays the following output:
//         The example is running on thread 1
//         The current culture is en-US
//         Changed the current culture to fr-FR.
//
//         Executing the delegate synchronously:
//         Formatting using the fr-FR culture on thread 1.
//         163 025 412,32 €   18 905 365,59 €
//
//         Executing a task asynchronously:
//         Formatting using the fr-FR culture on thread 3.
//         163 025 412,32 €   18 905 365,59 €
//
//         Executing a task synchronously:
//         Formatting using the fr-FR culture on thread 1.
//         163 025 412,32 €   18 905 365,59 €

DefaultThreadCurrentCultureDefaultThreadCurrentUICulture はアプリごとのドメイン プロパティです。つまり、特定のアプリケーション ドメインでカルチャを明示的に割り当てられていないすべてのスレッドに対する既定のカルチャを設定します。 ただし、.NET Framework 4.6 以降を対象とするアプリの場合は、タスクがアプリ ドメインの境界をまたぐ場合でも、呼び出し元スレッドのカルチャは非同期タスクのコンテキストの一部のままになります。

CultureInfo オブジェクトのシリアル化

CultureInfo オブジェクトがシリアル化されるとき、実際に格納されるのは NameUseUserOverride だけです。 これは、その Name が同じ意味を持つ環境でのみ、正常に逆シリアル化されます。 次に示すのは、これが常に当てはまるとは限らない場合の 3 つの例です。

  • CultureTypes プロパティの値が CultureTypes.InstalledWin32Cultures で、そのカルチャが特定のバージョンの Windows オペレーティング システムで最初に導入された場合、それより前のバージョンの Windows でそれを逆シリアル化することはできません。 たとえば、あるカルチャが Windows 10 で導入された場合、Windows 8 ではそれを逆シリアル化できません。

  • CultureTypes の値が CultureTypes.UserCustomCulture で、逆シリアル化が行われるコンピューターにこのユーザー カスタム カルチャがインストールされていない場合、それを逆シリアル化することはできません。

  • CultureTypes の値が CultureTypes.ReplacementCultures で、逆シリアル化が行われるコンピューターにこの置換カルチャがない場合、同じ名前に逆シリアル化されますが、すべての特性が同じになることはありません。 たとえば、代替カルチャ en-US がコンピューター A 上にはあっても、コンピューター B 上にはない場合、このカルチャを参照する CultureInfo オブジェクトをコンピューター A でシリアル化して、コンピューター B で逆シリアル化すると、カルチャのカスタム特性は伝えられません。 カルチャは正常に逆シリアル化されますが、意味は異なります。

コントロール パネルのオーバーライド

ユーザーは、コントロール パネルの地域と言語のオプションの部分を使って、Windows の現在のカルチャに関連付けられている値の一部をオーバーライドすることがあります。 たとえば、ユーザーは、日付を別の形式で表示したり、カルチャの既定値以外の通貨を使用したりする場合があります。 一般に、アプリケーションでは、これらのユーザーのオーバーライドを受け入れる必要があります。

UseUserOverridetrue で、指定されたカルチャが Windows の現在のカルチャと一致する場合、CultureInfo は、DateTimeFormat プロパティによって返される DateTimeFormatInfo インスタンスのプロパティのユーザー設定や、NumberFormat プロパティによって返される NumberFormatInfo インスタンスのプロパティも含め、それらのオーバーライドを使います。 ユーザー設定が CultureInfo に関連付けられているカルチャと互換性がない場合 (たとえば、選ばれたカレンダーが OptionalCalendarsの 1 つでない場合)、メソッドの結果とプロパティの値は未定義になります。

代替並べ替え順序

一部のカルチャでは、複数の並べ替え順序がサポートされています。 次に例を示します。

  • スペイン語 (スペイン) カルチャには、既定の国際並べ替え順序と従来の並べ替え順序の 2 つの並べ替え順序があります。 es-ES カルチャ名で CultureInfo オブジェクトをインスタンス化すると、国際並べ替え順序が使われます。 es-ES-tradnl カルチャ名で CultureInfo オブジェクトをインスタンス化すると、従来の並べ替え順序が使われます。

  • zh-CN (中国語 (簡体字、PRC)) カルチャでは、発音 (既定) とストローク数の 2 つの並べ替え順序がサポートされています。 zh-CN カルチャ名で CultureInfo オブジェクトをインスタンス化すると、既定の並べ替え順序が使われます。 ローカル識別子 0x00020804 で CultureInfo オブジェクトをインスタンス化すると、文字列はストローク数で並べ替えられます。

代替の並べ替え順序をサポートするカルチャと、各カルチャの既定の並べ替え順序および代替の並べ替え順序の識別子を次の表に示します。

カルチャ名 カルチャ 既定の並べ替え名と識別子 代替の並べ替え名と識別子
es-ES スペイン語 (スペイン) International: 0x00000C0A Traditional: 0x0000040A
zh-TW 中国語 (台湾) Stroke Count: 0x00000404 Bopomofo: 0x00030404
zh-CN 中国語 (中華人民共和国) Pronunciation: 0x00000804 Stroke Count: 0x00020804
zh-HK 中国語 (香港特別行政区) Stroke Count: 0x00000c04 Stroke Count: 0x00020c04
zh-SG 中国語 (シンガポール) Pronunciation: 0x00001004 Stroke Count: 0x00021004
zh-MO 中国語 (中華人民共和国マカオ特別行政区) Pronunciation: 0x00001404 Stroke Count: 0x00021404
ja-JP 日本語 (日本) Default: 0x00000411 Unicode: 0x00010411
ko-KR 韓国語 (韓国) Default: 0x00000412 Korean Xwansung - Unicode: 0x00010412
de-DE ドイツ語 (ドイツ) Dictionary: 0x00000407 Phone Book Sort DIN: 0x00010407
hu-HU ハンガリー語 (ハンガリー) Default: 0x0000040e Technical Sort: 0x0001040e
ka-GE グルジア語 (グルジア) Traditional: 0x00000437 Modern Sort: 0x00010437

現在のカルチャと UWP アプリ

ユニバーサル Windows プラットフォーム (UWP) アプリでは、.NET Framework および .NET Core アプリと同様に、CurrentCultureCurrentUICulture プロパティは読み取り/書き込み可能です。 ただし、UWP アプリが認識するカルチャは 1 つです。 CurrentCultureCurrentUICulture プロパティは、Windows.ApplicationModel.Resources.Core.ResourceManager.DefaultContext.Languages コレクションの最初の値にマップされます。

.NET アプリでは、現在のカルチャはスレッドごとの設定であり、CurrentCultureCurrentUICulture プロパティには、現在のスレッドのカルチャと UI カルチャのみが反映されます。 UWP アプリでは、現在のカルチャは、グローバル設定である Windows.ApplicationModel.Resources.Core.ResourceManager.DefaultContext.Languages コレクションにマップされます。 CurrentCulture または CurrentUICulture プロパティを設定すると、アプリ全体のカルチャが変更されます。スレッドごとにカルチャを設定することはできません。