-
Notifications
You must be signed in to change notification settings - Fork 0
MS_Culture
- 戻る(国際化対応項目)
-
Windows では、ロケール(win32)をカルチャ(.NET)と呼ぶ。
-
.NET では、カルチャ設定によって自動的に動作が変わる国際化(多言語化)機能を持っている。
- Date 型の文字列化時の既定のフォーマットが変化する。
- 画面上のコントロールの配置・キャプションなどの各種プロパティ、
カレンダ コントロールなどの表示が変化する。
-
参考
- CultureInfo クラス (System.Globalization)
https://learn.microsoft.com/ja-jp/dotnet/api/system.globalization.cultureinfo
- CultureInfo クラス (System.Globalization)
補足(「自動的に動作が変わる」ことの怖さ): 本ページの内容を
実務の観点で一言にすると、
**「意識していないと、環境によって動作が変わる」**という点に尽きる。// 実行環境のカルチャに依存する(=環境で結果が変わる) DateTime.Parse("01/02/2026") // ja-JP: 1月2日 / en-US: 1月2日 / en-GB: 2月1日 1234.5.ToString() // ja-JP: "1234.5" / de-DE: "1234,5" "ABC".ToLower() // tr-TR: "I" が "ı" になる(トルコ問題)**「開発機では動くのに本番で落ちる」**という不具合の
典型的な原因の一つがこれである。原則:
用途 使うもの ユーザーに見せる(画面表示) CurrentCulture(=そのまま)機械可読な入出力(ファイル、DB、API、ログ) InvariantCulture識別子の比較(キー、コード値) StringComparison.Ordinal// 保存・通信は常に InvariantCulture(または ISO 8601) var s = value.ToString("O", CultureInfo.InvariantCulture); var v = decimal.Parse(s, CultureInfo.InvariantCulture); // 識別子の比較は Ordinal(カルチャに依存させない) if (string.Equals(code, "ADMIN", StringComparison.Ordinal)) { }
アプリケーションの国際化(多言語化)に利用される Windows ロケールに
対応するカルチャには以下の 3 種類がある。
- 特定の言語や国・地域に依存しない特別なカルチャ
- 英語圏で使われるものを基本とする書式・規則が設定されていて、
特定のカルチャに依存しない形式への変換や比較を行いたい場合に使用する。
- 「日本語」などのように「<言語名>」形式で記述されたカルチャ
- 国や地域に依存せず、言語のみに依存する。
- 「日本語 (日本)」などのように「<言語名> (<国・地域名>)」形式で記述されたカルチャ
- 国や地域に依存する。
補足(用語の対応): 3 種類の使い分けを整理しておく。
種類 例 主な用途 既定(Invariant) ""(空文字列)永続化・通信。人に見せない値 ニュートラル ja,enリソースの選択(リソースファイル) 固有 ja-JP,en-US書式(日付・通貨) **「文言は言語だけで足りるが、書式は地域まで要る」**という
非対称性が、この 2 段構えの理由である。文言: 英語なら en で十分(米英で文言を分けることは稀) 書式: en-US は 8/19/2026、en-GB は 19/08/2026 → 地域が要る
カルチャには階層関係があり、基本的に 3 階層となっている。
既定カルチャ
├ja 日本語
│└ja-JP 日本
│
├en 英語
│├en-US 米国
│├en-GB 英国
│├en-AU オーストラリア
:
例外的に中国語のカルチャは 5 階層となる。
※ zh, zh-Hans, zh-CHS, zh-Hant, zh-CHT はニュートラルカルチャ
既定カルチャ
└zh 中国語
├zh-Hans 簡体字中国語
│└zh-CHS 簡体字中国語(古いカルチャ名)
│ ├zh-CN 中国
│ └zh-SG シンガポール
│
└zh-Hant 繁体字中国語
└zh-CHT 繁体字中国語(古いカルチャ名)
├zh-HK 香港
├zh-MO マカオ
└zh-TW 台湾
補足(この階層が「フォールバック」を決める): 階層構造は
リソースファイル のフォールバックの探索順
そのものである。CurrentUICulture = zh-TW のとき zh-TW → zh-Hant → zh → 既定 の順にリソースを探す中国語が 5 階層になっているのは、
**「言語(zh)と表記体系(簡体字/繁体字)が独立している」**ためで、
中間層(zh-Hans/zh-Hant)が挟まっている。誤: zh-CN と zh-TW でリソースを 2 つ作る 正: zh-Hans と zh-Hant でリソースを 2 つ作る → zh-CN / zh-SG は zh-Hans に、 zh-TW / zh-HK / zh-MO は zh-Hant にフォールバックする
zh-CHS/zh-CHTは非推奨(原文も「古いカルチャ名」と注記)で、
新規ではzh-Hans/zh-Hantを使う。
-
.NET では、カルチャを指定することによって、ユーザの文化的慣習に応じた、
「文字列」、「日付の形式」、「数値の形式」などの情報に対する
一般的な設定のセットを使用できる。 -
カルチャには UICulture と Culture の 2 つのカルチャ値があり、
2 つのカルチャ設定に別々の値を設定することができる。
- UI に表示される言語に関するカルチャ、例外メッセージ等も、こちらのカルチャを使用する。
- カルチャ固有の「リソースファイル」を検索するために
使用されるリソース専用カルチャ。 - 命名規則によりカルチャ毎に読み込むリソース ファイルが選択される。
//CurrentUICultureの取得
System.Globalization.CultureInfo uiCulture = System.Threading.Thread.CurrentThread.CurrentUICulture;
//CurrentUICultureの設定
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");-
Thread.CurrentUICulture プロパティ (System.Threading)
https://learn.microsoft.com/ja-jp/dotnet/api/system.threading.thread.currentuiculture -
CultureInfo クラス (System.Globalization)
https://learn.microsoft.com/ja-jp/dotnet/api/system.globalization.cultureinfo -
ResourceManager クラス (System.Resources)
https://learn.microsoft.com/ja-jp/dotnet/api/system.resources.resourcemanager
-
.NET Framework API の内部動作で使用されるスレッドのカルチャ。
-
CurrentUICulture の UI 以外のすべて(「日付の形式」、「数値の形式」など)を決定する。
-
設定
- .NET Framework 3.5 以前は、en-US や en-GB などの「特定カルチャ」だけ設定できる。
ニュートラル・カルチャを設定しようとすると NotSupportedException 例外が発生する。 - .NET 4 からはニュートラル・カルチャを設定可能になっている。
これにより、en-US と en-GB で異なる通貨記号が使用され、
en に使用する正しい通貨記号を識別する必要がなくなる。
- .NET Framework 3.5 以前は、en-US や en-GB などの「特定カルチャ」だけ設定できる。
-
用途(例)
-
フォーマット
- DateTime.ToString() の既定のフォーマット
- 通貨の書式指定子のフォーマット
-
メソッド
- Microsoft.VisualBasic.Strings.StrConv メソッド(全角半角変換)
全角文字が存在しないカルチャではエラーとなる。
- Microsoft.VisualBasic.Strings.StrConv メソッド(全角半角変換)
-
- 基本
//CurrentCultureの取得
System.Globalization.CultureInfo culture = System.Threading.Thread.CurrentThread.CurrentCulture;
//CurrentCultureの設定
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");- Windows Forms限定で以下の書き方も可能
//CurrentCultureの取得 ※Windows Forms限定
System.Globalization.CultureInfo culture = Application.CurrentCulture;
//CurrentCultureの設定 ※Windows Forms限定
Application.CurrentCulture = new System.Globalization.CultureInfo("en-US");-
Thread.CurrentCulture プロパティ (System.Threading)
https://learn.microsoft.com/ja-jp/dotnet/api/system.threading.thread.currentculture -
Application.CurrentCulture プロパティ (System.Windows.Forms)
https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.forms.application.currentculture -
CultureInfo クラス (System.Globalization)
https://learn.microsoft.com/ja-jp/dotnet/api/system.globalization.cultureinfo
補足(現在は
CultureInfoの静的プロパティを使う):Thread.CurrentThread
経由の書き方は動作するが、現在は
CultureInfo.CurrentCultureを使うのが標準である。CultureInfo.CurrentCulture = new CultureInfo("en-US"); CultureInfo.CurrentUICulture = new CultureInfo("en"); // アプリ全体の既定(.NET 4.5+)— 新規スレッドにも継承される CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("ja-JP"); CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("ja");
DefaultThreadCurrent*が後述のスレッド問題の解決策である。
何も設定せずにアプリケーションを実行した際の値は、
それぞれ以下の環境設定が使用される。
地域と言語の設定値によって決定される。
-
WindowsXP
[コントロールパネル]-[地域と言語のオプション]-[地域オプション]タブ-[標準と形式]グループ -
Windows7
[コントロールパネル]-[時計、言語、および地域]-[地域と言語]-[形式]タブ-[形式]
OS の言語バージョンによって決定される。
- 日本語 OS の場合は、ja-JP
- マルチ言語 OS の場合は、選択中の言語
補足(Linux / コンテナでの既定値/最新化): .NET Core 以降は
Windows 以外でも動くため、既定値の決まり方が増えている。
環境 既定のカルチャ Windows 地域設定 / 表示言語(原文の通り) Linux / macOS LANG/LC_ALL環境変数(ICU 経由)コンテナ(多くの公式イメージ) InvariantCulture(ICU が入っていない)コンテナでの落とし穴が特に重要である。
.NET の公式イメージ(alpine 系や runtime-deps)では、 サイズ削減のため ICU が含まれないことがある → InvariantGlobalization モードで動く → ja-JP を指定しても書式が英語圏のものになる → 文字列の比較・並べ替えも序数比較になる# ICU を入れる(Debian 系) RUN apt-get update && apt-get install -y libicu-dev ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false<!-- 逆に、意図的に Invariant で動かす(サイズ・起動速度を優先) --> <InvariantGlobalization>true</InvariantGlobalization>
InvariantGlobalization=trueにすると、
new CultureInfo("ja-JP")は例外にならないが、
中身は Invariant と同じになる(静かに壊れる)ため、
国際化が必要なアプリでは必ず ICU を入れる
(.NET CoreのDockerコンテナ化)。
-
Windows Forms、WPF などの
ウィンドウ・システム(メッセージ・ループ)を処理する
UI サブシステムは、基本的に UI 処理を行うスレッド=1つの主スレッドである。 -
このため、モーダルダイアログ、モードレスダイアログで表示される子画面は、
親画面と同一スレッドとなり、カルチャ値は子画面と親画面で同一となる。
Web アプリケーション(ASP.NET, ASP.NET AJAX, Web サービス)では
config 設定にて動作の定義が可能である。
※ Windows アプリケーションに config 設定は存在しない。
Web.configの globalization 要素を設定する。
- culture 属性に CurrentCulture の既定値
- uiCulture 属性に CurrentUICulture の既定値
<system.web>
<globalization culture="ja-JP" uiCulture="ja-JP" />
</system.web>※ 空文字を設定するとデフォルト値が使用される。
既定カルチャ(Invariant Culture)は定義できない。
culture 属性、uiCulture 属性に "auto" を定義すると、
クライアントのブラウザの言語設定の値が既定値となる。
<system.web>
<globalization culture="auto" uiCulture="auto" />
</system.web>- Internet Explorer 8
- [ツール]-[インターネットオプション]-[全般]タブ-[言語]
- ここの設定により、HTTP ヘッダに言語情報が追加される(Accept-Language)。
※ クライアントのブラウザの言語設定がされていない(全て削除している)場合、
デフォルト値が既定値となる。
※ Request.UserLanguages プロパティ(string[] 型)にて
ブラウザの言語設定に登録されている言語を全て取得できる。
言語設定がされていない場合は、null 値となる。
- globalization 要素 (ASP.NET 設定スキーマ)
https://learn.microsoft.com/ja-jp/previous-versions/dotnet/netframework-4.0/hy4kkhe0(v=vs.100) - HttpRequest.UserLanguages プロパティ (System.Web)
https://learn.microsoft.com/en-us/dotnet/api/system.web.httprequest.userlanguages
補足(ASP.NET Core での設定):
<globalization>は無く、
RequestLocalizationMiddlewareが同じ役割を担う
(ASP.NET の 国際化対応 の補足を参照)。app.UseRequestLocalization(new RequestLocalizationOptions() .SetDefaultCulture("ja-JP") .AddSupportedCultures("ja-JP", "en-US") // ← CurrentCulture .AddSupportedUICultures("ja", "en")); // ← CurrentUICulture
AddSupportedCulturesに無いカルチャは既定値に落ちる
(ホワイトリスト方式)ため、
「対応していない言語で表示が崩れる」ことを防げる。
auto相当の挙動はAcceptLanguageHeaderRequestCultureProviderが担う。
新しく作成されたスレッドのカルチャはデフォルト値となる。
※ Web.configの設定は適用されない。
- 基本
public void Method1()
{
System.Threading.Thread th = new System.Threading.Thread(StaticMethod1);
th.Start();
}
public static void StaticMethod1()
{
Debug.WriteLine(System.Threading.Thread.CurrentThread.CurrentCulture.ToString()); // → デフォルト値
Debug.WriteLine(System.Threading.Thread.CurrentThread.CurrentUICulture.ToString()); // → デフォルト値
}- 新しく作成されたスレッドにカルチャを設定する
public void Method1()
{
System.Threading.Thread th = new System.Threading.Thread(StaticMethod1);
th.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentCulture; // ← 作成したスレッドにカルチャ値をコピー
th.CurrentUICulture = System.Threading.Thread.CurrentThread.CurrentUICulture; // ← 作成したスレッドにカルチャ値をコピー
th.Start();
}
public static void StaticMethod1()
{
Debug.WriteLine(System.Threading.Thread.CurrentThread.CurrentCulture.ToString()); // → 親カルチャと同じ値
Debug.WriteLine(System.Threading.Thread.CurrentThread.CurrentUICulture.ToString()); // → 親カルチャと同じ値
}移行メモ(誤記): 原文のサンプルには次の誤りがあり、
C# として成立しないため修正した。
public sub Method1()… VB の構文が混在(public void)th,Start()… カンマとピリオドの誤り(th.Start();)public static StaticMethod1()… 戻り値の型が無い(static void)th.CurrentCultureに 2 回ともCurrentCultureを代入していた
→ 2 行目はth.CurrentUICulture = ...CurrentUICultureが正しい
-
Parallel.For、Parallel.Invoke を利用した並列処理では、
本体スレッドによる処理と別スレッドによる処理が混在する。 -
別スレッドのカルチャはデフォルト値となる。
※ Web.configの設定は適用されない。
- 基本
System.Threading.Tasks.Parallel.For(0, 5, i =>
{
Debug.WriteLine(System.Threading.Thread.CurrentThread.CurrentCulture.ToString()); // → 別スレッドで実行される場合はデフォルト値
Debug.WriteLine(System.Threading.Thread.CurrentThread.CurrentUICulture.ToString()); // → 別スレッドで実行される場合はデフォルト値
});- 別スレッドにカルチャを設定する
System.Globalization.CultureInfo culture = System.Threading.Thread.CurrentThread.CurrentCulture; // ← 本体スレッドのカルチャ値をコピー
System.Globalization.CultureInfo uiCulture = System.Threading.Thread.CurrentThread.CurrentUICulture; // ← 本体スレッドのカルチャ値をコピー
System.Threading.Tasks.Parallel.For(0, 5, i =>
{
System.Threading.Thread.CurrentThread.CurrentCulture = culture; // ← コピーしたカルチャを設定
System.Threading.Thread.CurrentThread.CurrentUICulture = uiCulture; // ← コピーしたカルチャを設定
Debug.WriteLine(System.Threading.Thread.CurrentThread.CurrentCulture.ToString()); // → 本体スレッドと同じカルチャ
Debug.WriteLine(System.Threading.Thread.CurrentThread.CurrentUICulture.ToString()); // → 本体スレッドと同じカルチャ
});- Parallel クラス (System.Threading.Tasks)
https://learn.microsoft.com/ja-jp/dotnet/api/system.threading.tasks.parallel
補足(.NET 4.5 以降は引き継がれる/最新化): この 2 節が扱う
**「新しいスレッドではカルチャが既定値に戻る」**という問題は、
.NET Framework 4.5 で改善されている。
版 新規スレッド / Task のカルチャ 〜.NET 4.0 既定値に戻る(本ページの記述) .NET 4.5 以降 DefaultThreadCurrent*で既定を設定できる.NET Framework 4.6 以降 / .NET Core CurrentCultureが非同期の流れで引き継がれる// アプリ起動時に 1 度だけ書けば、以降のスレッド・Task に継承される CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("ja-JP"); CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("ja");.NET Framework 4.6 以降では
CurrentCultureが
AsyncLocal相当の仕組みで保持されるようになったため、
async/await をまたいでも引き継がれる。CultureInfo.CurrentCulture = new CultureInfo("en-US"); await Task.Run(() => Console.WriteLine(CultureInfo.CurrentCulture)); // .NET 4.6+ / .NET Core → en-US(引き継がれる) // .NET 4.5 以前 → 既定値ただし、明示的に
new Thread(...)した場合は引き継がれない
(原文のサンプルの通り、手でコピーが要る)。ASP.NET Core では
RequestLocalizationMiddlewareが
リクエストごとに設定するため、
アプリ コード側で意識する必要はほぼ無い。
-
文字列の書式設定 - クラスライブラリ | ++C++; // 未確認飛行 C
http://ufcpp.net/study/dotnet/bcl_format.html#culture -
総武ソフトウェア推進所
- Programming-.NET Framework-ロケール(カルチャ)
- カルチャの基本とカルチャ情報 (CultureInfo)
http://smdn.jp/programming/netfx/locale/0_abstract/ - カルチャと書式・テキスト処理・暦
http://smdn.jp/programming/netfx/locale/1_infoes/
- カルチャの基本とカルチャ情報 (CultureInfo)
- Programming-.NET Framework-文字列
- 文字列と比較オプション・カルチャの並べ替え規則
http://smdn.jp/programming/netfx/string/2_2_compareoptions/
- 文字列と比較オプション・カルチャの並べ替え規則
- Programming-.NET Framework-ロケール(カルチャ)
- CultureInfo クラス
https://learn.microsoft.com/ja-jp/dotnet/api/system.globalization.cultureinfo - .NET のグローバリゼーション
https://learn.microsoft.com/ja-jp/dotnet/core/extensions/globalization - .NET グローバリゼーションと ICU
https://learn.microsoft.com/ja-jp/dotnet/core/extensions/globalization-icu - 文字列を比較するためのベスト プラクティス
https://learn.microsoft.com/ja-jp/dotnet/standard/base-types/best-practices-strings
Tags: 移行, .NET開発, 国際化対応
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。