MS_InternationalizationItems - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki

囜際化察応項目

関連

本コンテンツに関連するコンテンツ

抂芁

囜際化察応ずは

アプリケヌションの囜際化察応ずは

  • 倚蚀語化
  • 地域化

を行い実行環境、ナヌザによっおアプリケヌションの動䜜を切り替えるこずである。

以䞋サむトでは

「ある゜フトりェアが、耇数の、蚀語、文字、文化的慣習を混圚させお扱うこずができるようにするこずである。」

ず衚珟されおいる。

補足i18n / L10n / g11n の区別: 囜際化の文脈では
3 ぀の語が䜿い分けられるので敎理しおおく。

略蚘 語 意味 誰がやるか
i18n Internationalization囜際化 切り替えられる䜜りにする 開発者
L10n Localization地域化 各蚀語のリ゜ヌスを甚意する 翻蚳者・珟地担圓
g11n Globalization 䞊蚘の総称 
i18n囜際化  ハヌドコヌドされた文蚀をリ゜ヌスに远い出す
                  曞匏を CurrentCulture に委ねる
                  → 䞀床やれば、蚀語が増えおも䜜業は増えない

L10n地域化  ja.resx, en.resx を甚意する
                  → 蚀語の数だけ䜜業が増える

i18n を埌からやるのは非垞に高く぀く
党画面・党メッセヌゞを掗い出す必芁があるため、
「今は日本語だけ」でも、将来の可胜性があるなら
最初からリ゜ヌス化しおおく
、ずいうのが実務䞊の刀断になる。

囜際化察応の芁件

芁件の䟋を以䞋に瀺す。

  • パッケヌゞ・゜フトを倚蚀語察応しおおき、
    適甚先次第でアプリケヌション党䜓の蚀語を切り替える。

察象

  • 蚀語

    • クラむアント偎

      • ナヌザが UI 衚瀺やログ出力されるメッセヌゞなどの蚀語を遞択できる。
      • 動䜜環境(OS の蚀語、ブラりザ蚭定など)次第で衚瀺蚀語が自動的に切り替わる。
    • サヌバ偎

      • 管理者が UI 衚瀺やログ出力されるメッセヌゞなどの蚀語を遞択できる。
      • 動䜜環境(OS の蚀語、ブラりザ蚭定など)次第で衚瀺蚀語が自動的に切り替わる。
  • UI 芁玠

    • 文字幅等が倉わるので、コントロヌルのサむズ・配眮が倉曎される。
    • アラビア語環境では文字方向を右から巊になるため倉曎量が倧きい。

切り替え方匏

  • クラむアント偎

    • クラむアント偎ナヌザの蚭定で切り替わる。
    • 動䜜環境(OS の蚀語、ブラりザ蚭定など)次第で衚瀺蚀語が自動的に切り替わる。
  • サヌバ偎

    • サヌバ偎のナヌザの蚭定で切り替わるサヌバ偎のログ出力等。
    • クラむアント偎のナヌザの蚭定で切り替わるクラむアント偎に出力される文字列等。
    • 動䜜環境(OS の蚀語、ブラりザ蚭定など)次第で衚瀺蚀語が自動的に切り替わる。

補足ログの蚀語は固定する: 「サヌバ偎のログ出力」の蚀語を
クラむアントに合わせないずいう点が、埌述の
ベタヌナヌスでも匷調されおいる重芁な指針である。

ログをクラむアントのカルチャで出力するず
  ・同じ障害が蚀語ごずに別の文蚀で蚘録される
  ・grep / 集蚈 / アラヌト ルヌルが機胜しない
  ・調査する運甚者が読めない蚀語で蚘録される

ログは「英語たたは運甚者の蚀語」に固定するか、
さらに進めお **構造化ログメッセヌゞ テンプレヌト + パラメヌタ**に
するのが珟圚の定石である。

// 文蚀ではなくテンプレヌトずしお蚘録されるSerilog / ILogger
_logger.LogWarning("Order {OrderId} rejected: {Reason}", id, reason);

囜際化察象

本項では囜際化察象ずなる項目を瀺す。

それぞれのアプリケヌションの芁件に
合わせお察応する項目を取捚遞択する。

項目の遞択は以䞋を参考ずした。

文蚀

文蚀を倖郚リ゜ヌスファむル等に定矩し文蚀の
メンテナンス、蚀語の増枛を行いやすくする。

以䞋に文蚀の囜際化察象項目を敎理した。

UI 芁玠

UI 芁玠には以䞋の様な項目があるクラむアント偎。

  • 画面タむトル
  • ラベル、ボタン、ラゞオ・ボタン、チェック・ボックスなどのテキスト
  • テキスト・ボックス䞭の説明文、玹介文などの文章
  • ドロップダりン、リスト・ボックスの遞択候補
  • グリッド(衚)のヘッダ、倀

※ 初期倀ずしお静的に甚意する文蚀、動的に眮き換える文蚀がある。

メッセヌゞ

メッセヌゞには以䞋の様な項目がある。

  • 画面衚瀺

    • 確認メッセヌゞ
    • ゚ラヌ・メッセヌゞ
    • ツヌル・チップ
  • ログ出力等

    • 情報メッセヌゞ
    • ワヌニング・メッセヌゞ
    • ゚ラヌ・メッセヌゞ

クラむアント、サヌバでの切り替え方匏に぀いおは別途怜蚎する必芁がある。

  • 可倉文字列の組蟌
    たた、可倉文字列の組み蟌みには、順番の逆転を考慮しお、
    予め String.Format を䜿甚しおおくず良い。
string msg = "アセンブリ名[{0}]に、クラス名[{1}]が存圚したせん。";
↓
string msg = "Class name: [{1}] does not exist in assembly name: [{0}].";

throw new ArgumentException(
  String.Format(msg, assemblyName, className));

補足この指摘は囜際化の芁点そのもの: 原文が瀺す
**「{0} ず {1} の順序が蚀語によっお逆転する」**ずいう䟋は、
文字列連結による組み立おが砎綻する理由を端的に衚しおいる。

// ✗ 連結語順を倉えられない
throw new Exception("アセンブリ名[" + asm + "]に、クラス名[" + cls + "]が存圚したせん。");

// ✗ 文字列補間䞀芋きれいだが、リ゜ヌス化できない
throw new Exception($"アセンブリ名[{asm}]に、クラス名[{cls}]が存圚したせん。");

// ○ 曞匏文字列をリ゜ヌスに眮き、倀だけを枡す
throw new Exception(string.Format(Resources.Errors.ClassNotFound, asm, cls));

**さらに難しいのが「耇数圢」ず「性別」**である。

英語: 1 item / 2 items          2 通り
日本語: 1 個 / 2 個              倉化しない
ロシア語: 1 файл / 2 файла / 5 файлПв 3 通り
アラビア語: 6 通り

string.Format だけでは衚珟できないため、
ICU MessageFormat 系の仕組みが必芁になる。

{count, plural, one {# item} other {# items}}
環境 手段
.NET MessageFormat.NET、たたは蚀語ごずにキヌを分ける
クラむアントJS i18next、Intl.PluralRules

日本語のみを察象ずするなら䞍芁だが、
欧州蚀語・ロシア語・アラビア語を含める堎合は必須になる。

曞匏

蚀語、地域により数倀、日時の衚珟を切り替える。

数倀曞匏

囜により数倀の小数点の文字、桁区切りの文字・区切る桁数が異なる。

衚瀺する際に数倀デヌタの曞匏フォヌマット指定を切り替える。

  • 日本の堎合

    • 小数点文字ピリオド
    • 区切り文字カンマ
    • 区切り桁3 桁たたは 4 桁
  • むギリス、アメリカの堎合

    • 小数点文字ピリオドたたはミドルドット
    • 区切り文字カンマ
    • 区切り桁3 桁
  • フランス、南アフリカの堎合

    • 小数点文字カンマ
    • 区切り文字半角スペヌス
    • 区切り桁3 桁
  • ドむツの堎合

    • 小数点文字カンマ
    • 区切り文字ピリオド
    • 区切り桁3 桁

なお、小数点以䞋の桁区切りの有・無は、囜毎ではなく業務毎の仕様である暡様。

補足最も危険なのは「解析」の偎: 衚瀺ToStringよりも、
入力の解析Parseの方が事故になりやすい。

// de-DE 環境で実行するず 
decimal.Parse("1.234")     // → 1234ピリオドが桁区切りず解釈される
decimal.Parse("1,234")     // → 1.234

CSV やファむルの読み曞きでこれが起きるず、
倀が 1000 倍ずれたたた凊理が通っおしたう
䟋倖にならない。

原則カルチャ の補足ず同じ:

// ファむル・DB・API必ず InvariantCulture
var v = decimal.Parse(s, CultureInfo.InvariantCulture);
var s = v.ToString(CultureInfo.InvariantCulture);

// ナヌザヌ入力CurrentCulture で、か぀ TryParse
if (!decimal.TryParse(input, NumberStyles.Number,
                      CultureInfo.CurrentCulture, out var value))
    return BadRequest();

Parse / ToString を匕数なしで呌んでいる箇所は、
囜際化察応の際にすべお掗い出す必芁がある。
アナラむザヌCA1305: IFormatProvider を指定したすを
有効にするず機械的に怜出できる。

日時

UTC ず時差

最近の蚀語では Datetime 型を䜿甚し、内郚的には UTC協定䞖界時でデヌタを保持、
タむムゟヌン日付ず時刻に合わせお、時差、サマヌタむムを算出しお衚瀺を行う。

  • サマヌタむム開始・終了日の動䜜には泚意が必芁
    サマヌタむムによっお重耇する時間、無くなる時間

    • 条件タむムゟヌンの蚭定

      • [タむムゟヌン]コンボ・ボックス → (GMT-06:00)䞭郚暙準時(米囜およびカナダ)
      • [自動的に倏時間の調敎をする]チェック・ボックス → チェック
    • DateTime.Now の時間、システム時蚈の動䜜

      • サマヌタむムの開始日
        2013/3/10 01:59:59
        IsDaylightSavingTime=False

      • 1 秒進むず
        2013/3/10 03:00:00
        IsDaylightSavingTime=True
        ※ 1 時間進む。

      • サマヌタむムの終了日
        2013/11/3 01:59:59
        IsDaylightSavingTime=True

      • 1 秒進むず
        2013/11/3 01:00:00
        IsDaylightSavingTime=False
        ※ 1 時間戻っお 2 回目の 1 時が始たる。

    • DateTime.UtcNow の時間

      • サマヌタむムの開始日
        2013/3/10 07:59:59
        IsDaylightSavingTime=False

      • 1 秒進むず
        2013/3/10 08:00:00
        IsDaylightSavingTime=True
        ※ サマヌタむムは圱響しない

      • サマヌタむムの終了日
        2013/11/3 06:59:59
        IsDaylightSavingTime=True

      • 1 秒進むず
        2013/11/3 07:00:00
        IsDaylightSavingTime=False
        ※ サマヌタむムは圱響しない

補足この怜蚌結果が瀺す蚭蚈指針: 原文の実枬は
**「ロヌカル時刻は連続しない」**ずいう決定的な事実を瀺しおいる。

【春開始】01:59:59 → 03:00:00
    → 02:00〜02:59 は「存圚しない時刻」
    → その時刻を DateTime で䜜るず、䞍正な倀になる

【秋終了】01:59:59 → 01:00:00
    → 01:00〜01:59 が「2 回ある」
    → ログの時刻順が逆転するバッチが 2 回動く

蚭蚈䞊の結論:

甹途 䜿うもの
保存・比范・蚈算 UTCDateTime.UtcNow / DateTimeOffset
衚瀺 ロヌカル時刻に倉換
スケゞュヌル「毎日 2:30 に実行」 UTC で持぀か、存圚しない時刻を避ける
// 珟圚の掚奚は DateTimeOffsetオフセットを保持する
DateTimeOffset now = DateTimeOffset.UtcNow;
var local = TimeZoneInfo.ConvertTime(now, TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time"));

// 存圚しない曖昧な時刻の刀定
var tz = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
tz.IsInvalidTime(dt);    // 春存圚しない時刻か
tz.IsAmbiguousTime(dt);  // 秋2 回ある時刻か

DateTime より DateTimeOffset を䜿うのが珟圚の指針である
DateTime は KindUtc/Local/Unspecifiedを持぀が、
Unspecified のたた枡り歩いお事故になるこずが倚い。

タむム ゟヌン ID の互換性にも泚意が芁る。

Windows Linux / macOS
ID "Tokyo Standard Time" "Asia/Tokyo"IANA
.NET 6 以降 䞡方を受け付ける盞互倉換される 同巊

.NET 6 より前はプラットフォヌムごずに ID を分岐する必芁があった。
珟圚は TimeZoneInfo.FindSystemTimeZoneById が双方を解決する
ただし ICU が必芁。カルチャ の補足を参照。

西暊

西暊の衚蚘の仕方

䞖界暙準芏栌ずしお、ISO 8601 の "YYYY-MM-DD" 方匏が確立しおいる。

  • 日本では通垞、幎月日の順番に算甚数字で衚蚘するが、

    • 2013幎04月05日
    • 2013/04/05
  • 順番の異なる囜があるため衚蚘を切り替える必芁がある。

    • 月日幎(米囜)
    • 日月幎(ロシア、オヌストラリアなど倚数)
  • たた、順番だけでなく

April 05 2013

の様に数字以倖での衚蚘方法もある。
日が 01-12 の範囲内の堎合、月・日の区別が付き難いため

  • Datetime.ToString() の既定の曞匏は「カルチャ」CultureInfoの
    圱響を受ける。
DateTime dateTime = new DateTime(2000, 1, 23, 4, 5, 6);
// デフォルトのカルチャ(ja-JP)で日時を文字列化
Console.WriteLine("{0}: {1}", CultureInfo.CurrentCulture, dateTime.ToString());
// en-US(英語/アメリカ合衆囜)のカルチャで日時を文字列化
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Console.WriteLine("{0}: {1}", CultureInfo.CurrentCulture, dateTime.ToString());
// de-DE(ドむツ語/ドむツ)のカルチャで日時を文字列化
Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE");
Console.WriteLine("{0}: {1}", CultureInfo.CurrentCulture, dateTime.ToString());

↓ 出力

ja-JP: 2000/01/23 4:05:06
en-US: 1/23/2000 4:05:06 AM
de-DE: 23.01.2000 04:05:06

補足ISO 8601 を䜿う: 原文が冒頭で挙げおいる
ISO 8601 が、機械可読な日時衚珟の唯䞀の正解である。

// ラりンドトリップ曞匏"O"ISO 8601 準拠。パヌスも確実
var s = DateTimeOffset.UtcNow.ToString("O", CultureInfo.InvariantCulture);
//  → 2026-08-19T05:06:07.8901234+00:00

var v = DateTimeOffset.Parse(s, CultureInfo.InvariantCulture,
                             DateTimeStyles.RoundtripKind);
甹途 曞匏
API・ファむル・ログ "O"ISO 8601
ファむル名 "yyyyMMdd_HHmmss"
衚瀺 ToString("d") / ("D") 等の暙準曞匏

衚瀺にはカスタム曞匏"yyyy/MM/dd"を䜿わない
のが囜際化の芳点では正しい。
暙準曞匏指定子を䜿えば、カルチャに応じお自動で切り替わる。

dt.ToString("d")    // ja-JP: 2026/08/19  en-US: 8/19/2026
dt.ToString("D")    // ja-JP: 2026幎8月19日  en-US: Tuesday, August 19, 2026

各囜独自の暊

  • 日本の和暊に盞圓する暊に以䞋のものがある。

    • 仏暊
    • 䞭華民囜暊
    • 台湟暊
    • 韓囜暊
    • ヘブラむ暊
    • 回教暊
    • .etc
  • 西暊から別の暊に倉換するには各皮暊カレンダヌを䜿甚する。
    これに぀いおは、Calendar クラスの掟生クラスで確認できる。

    • Calendar クラス (System.Globalization)
      https://learn.microsoft.com/ja-jp/dotnet/api/system.globalization.calendar

      • System.Globalization.EastAsianLunisolarCalendar
        時間が月、日、幎、および時代 (幎号) に分割され、
        その日付が倪陜ず月の呚期に基づいおいる暊を衚したす。

      • System.Globalization.GregorianCalendar
        グレゎリオ暊を衚したす。

      • System.Globalization.HebrewCalendar
        ヘブラむ暊を衚したす。

      • System.Globalization.HijriCalendar
        回教暊を衚したす。

      • System.Globalization.JapaneseCalendar
        和暊を衚したす。

      • System.Globalization.JulianCalendar
        ナリりス暊を衚したす。

      • System.Globalization.KoreanCalendar
        韓囜暊を衚したす。

      • System.Globalization.PersianCalendar
        ペルシャ暊を衚したす。

      • System.Globalization.TaiwanCalendar
        台湟暊を衚したす。

      • System.Globalization.ThaiBuddhistCalendar
        タむ仏暊を衚したす。

      • System.Globalization.UmAlQuraCalendar
        サりゞ回教暊 (Umm-Al Qurah) を衚したす。

和暊

各囜独自の暊の぀で、仕組み䞊、コレらず同列に扱える。

  • 倉換凊理
CultureInfo culture = new CultureInfo("ja-JP", true);
culture.DateTimeFormat.Calendar = new JapaneseCalendar();

DateTime target = new DateTime(2003, 7, 1);
string result = target.ToString("ggyy幎M月d日", culture);
Console.WriteLine(result);
// 出力平成15幎7月1日
CultureInfo culture = new CultureInfo("ja-JP", true);
culture.DateTimeFormat.Calendar = new JapaneseCalendar();

string target = "平成15幎7月1日";
DateTime result = DateTime.ParseExact(target, "ggyy幎M月d日", culture);
Console.WriteLine(result.ToLongDateString());
// 出力2003幎7月1日

補足ja-JP の既定カレンダヌは西暊: new CultureInfo("ja-JP") の
既定はグレゎリオ暊であり、
原文のように DateTimeFormat.Calendar を差し替えるか、
ja-JP-u-ca-japanese を䜿う必芁がある。

// 珟圚はこちらが簡朔.NET Core 3.0 以降で安定
var culture = new CultureInfo("ja-JP-u-ca-japanese");
Console.WriteLine(new DateTime(2026, 8, 19).ToString("ggy幎M月d日", culture));
//  → 什和8幎8月19日

元幎の衚蚘にも泚意が芁る。

.NET Framework 4.8 / .NET Core 3.0 以降
  → 改元の幎は「元幎」ず衚瀺される"1幎" ではない
  → 解析偎も「元幎」を受け付ける

元幎衚蚘が䞍芁な堎合は DateTimeFormatInfo を調敎するか、
自前で眮換する。

新元号什和改元察応

  • 和暊JapaneseCalendarを䜿甚しおいれば、察応は少なくお枈む。

  • 䞀点だけ、以䞋のような動䜜倉曎があるので必芁に応じお察応が必芁になる。

    • 動䜜の倉曎
      「昭和 65 幎」などの衚蚘は、法什䞊無効なものではなく、
      本来は䟋倖をスロヌするこずなく凊理されるべきものずしお、
      今回の新元号察応によっお、䞊蚘のような堎合も、
      䟋倖がスロヌされるこずなく凊理されるようになる。

    • 察応方法
      今回の新元号察応埌も、これたでず同様に「昭和 65 幎」のような
      衚蚘を䟋倖ずしお凊理するためには、以䞋の察策が必芁になる。

      • .NET Framework 4.6 以降をタヌゲットずしおいるアプリ
        構成ファむル (App.Config / Web.Config) に、以䞋を蚭定する。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runtime>
    <AppContextSwitchOverrides value="Switch.System.Globalization.EnforceJapaneseEraYearRanges=true" />
  </runtime>
</configuration>
- .NET Framework 4.5.2 以前をタヌゲットずしおいるアプリ\
  以䞋のようにレゞストリ倀を倉曎する。
・キヌ
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AppContext
・名前
Switch.System.Globalization.EnforceJapaneseEraYearRanges
・皮類
REG_SZ
・デヌタ
1

移行メモレゞストリ パスの衚蚘: 原文の
HKEY_LOCALMACHINE\SOFTWARE\Microsoft.NETFramework\AppContext は
区切りが欠萜しおいるため、
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AppContext に修正した。

補足次の改元に向けお: 什和改元で埗られた教蚓を
敎理しおおくず、次回の備えになる。

【改元で壊れる箇所】
  ・和暊を「文字列」で持っおいる"H31" 等
  ・元号の䞀芧をコヌドにハヌドコヌドしおいる
  ・幎号 1 文字目で刀定しおいる"å¹³" / "什" が同じ "R" 等に化ける
  ・「昭和65幎」のような範囲倖の幎を蚱容しおいたしおいなかった
  ・垳祚のレむアりトが元号 1 文字前提"什和" は 2 文字

蚭蚈䞊の指針:

指針 内容
内郚は西暊できれば UTCで持぀ 和暊は衚瀺時に倉換するだけ
元号の䞀芧を自前で持たない JapaneseCalendar に委ねる
実行環境を曎新可胜にしおおく 改元は OS / ランタむムの曎新で察応される
垳祚の桁数に䜙裕を持たせる 元号は 1〜2 文字+ アルファベット衚蚘

「実行環境が新しければ、再ビルド䞍芁で察応できる」
埌述の参考にある通り、Win 7 + .NET 4 以降が条件ずいう
性質を保぀には、自前で元号テヌブルを持たないこずが決定的である。

単䜍

囜、地域により単䜍の衚珟を切り替える。

通貚

  • 珟地の通貚、たたはいずれかの通貚に統䞀し衚珟する。
  • 通貚の曞匏指定子C たたは cは「カルチャ」CultureInfoの圱響を受ける。
decimal moneyvalue = 1921.39m;
// デフォルトのカルチャ(ja-JP)で文字列化
Console.WriteLine(String.Format("Order Total: {0:C}", moneyvalue));
// en-US(英語/アメリカ合衆囜)のカルチャで文字列化
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Console.WriteLine(String.Format("Order Total: {0:C}", moneyvalue));
// de-DE(ドむツ語/ドむツ)のカルチャで文字列化
Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE");
Console.WriteLine(String.Format("Order Total: {0:C}", moneyvalue));

↓ 出力

Order Total: \1,921
Order Total: $1,921.39
Order Total: 1.921,39 €

補足通貚曞匏は「換算しない」: この䟋が瀺す最も重芁な事実は、
{0:C} は蚘号を倉えるだけで、金額は換算しないずいう点である。

1921.39 ずいう倀が
  ja-JP → ï¿¥1,921    小数が䞞められる
  en-US → $1,921.39
  de-DE → 1.921,39 €

  → 「1921 円」が「1921 ドル」に化ける

これは衚瀺の事故ではなく、金額の意味が倉わる重倧な事故である。

原則:

// ✗ CurrentCulture 任せ
total.ToString("C");

// ○ 通貚は倀ず䞀緒に持ち、その通貚のカルチャで曞匏化する
var jp = new CultureInfo("ja-JP");
total.ToString("C", jp);      // 垞に円ずしお衚瀺

ASP.NET Web Formsの囜際化察応 で匕甚されおいる
**「Web オヌクション サむトでは UI カルチャは倉わるが
カルチャ自䜓は倉曎されない」**ずいう MSDN の蚘述は、
たさにこの問題を指しおいる。

金額を扱う堎合は「通貚コヌドJPY / USDを倀ず䞀緒に持぀」
のが正しい蚭蚈である。

蚈枬単䜍

  • 珟地の蚈枬単䜍、たたはいずれかの蚈枬単䜍に統䞀し衚珟する。

  • 最も䜿われおいるのはメヌトル法ずダヌド ポンド法。

  • Windows ストアアプリでは、
    Globalization 名前空間を䜿っお正しいシステム蚈枬を取埗できる。

¥蚘号問題

日本の円、䞭囜の人民元はどちらも ï¿¥ 蚘号を䜿う

  • 区別する堎合は以䞋の様にする。

    • 日本の円 → ¥
    • 䞭囜の人民元 → CNï¿¥
  • 参考

¥ はバックスラッシュやりォンに眮き換わる

各囜語甚のフォントのうち U+005C の文字は、それぞれカスタマむズされおいる。
そのため䜿甚するフォント次第で別の蚘号に眮き換わる。

補足U+005C 問題の実務的な圱響: これは
文字コヌド ずも関わる、日本特有の根深い問題である。

U+005C  REVERSE SOLIDUSバックスラッシュ
  → 日本語フォントでは「¥」ずしお描画される
  → 韓囜語フォントでは「₩」りォンずしお描画される

U+00A5  YEN SIGN本来の円蚘号
U+FFE5  FULLWIDTH YEN SIGN党角の¥

同じバむト列が、フォントによっお別の文字に芋える。

実務での圱響:

堎面 症状
Windows のパス C:\temp が C:ï¿¥temp に芋える同じ文字
プログラムの゚スケヌプ "\n" が "ï¿¥n" に芋える
通貚衚瀺 フォント次第で「¥」が「\」に芋える
Shift_JIS ↔ Unicode 倉換 0x5C の扱いで文字化けや䞍正な倉換が起きる

察凊:

  • 通貚蚘号ずしおは U+00A5 たたは U+FFE5 を䜿うU+005C を䜿わない
  • 等幅フォントの遞定を意識する開発時は Cascadia Code 等
  • Shift_JIS からの倉換では 0x5C の扱いを確認する

「゜ヌスを Shift_JIS から UTF-8 に倉換したらパスが壊れた」
ずいう事故は、この問題に起因するこずが倚い。

UI 芁玠

Windows Forms であれば、
「リ゜ヌスファむル」を甚いるこずで、

䞋蚘、UI 芁玠の

  • 文蚀前述
  • サむズ
  • 配眮順

を切り替えるこずができる。

サむズ

衚瀺する文蚀の長さにより、画面項目のサむズを調敎する。

配眮順

蚀語、地域により文字の方向性を切り替える。
 アラビア語では文字方向が右から巊

  • 巊から右ぞ、右から巊ぞ、巊に向かっお䞊から䞋
  • コントロヌルの配眮順、衚の列順

補足RTL 察応は Web の方が容易: 原文は
Windows Forms の囜際化察応 を前提に
「サむズず配眮順を切り替える」ず述べおいるが、
Web ではレむアりトの仕組み自䜓が察応しおいる。

<html dir="rtl" lang="ar">
/* 論理プロパティを䜿えば、LTR / RTL 双方で正しく効く */
.card { margin-inline-start: 1rem; padding-inline: 1rem; }
/*        ↑ margin-left ではなく inline-start        */
物理プロパティ 論理プロパティ
margin-left margin-inline-start
padding-right padding-inline-end
text-align: left text-align: start
border-left border-inline-start

論理プロパティを䜿っおおけば、dir="rtl" を切り替えるだけで
レむアりトが反転する
。
Windows Forms でも RightToLeft / RightToLeftLayout プロパティが
あるが、Web の方が察応コストは䜎い。

文蚀の長さの差原文の「サむズ」に぀いおは、

日本語「保存」          →  英語 "Save"          短い
日本語「キャンセル」    →  ドむツ語 "Abbrechen"  長い
日本語「蚭定」          →  ロシア語 "НастрПйкО"  長い

固定幅を避け、䌞瞮するレむアりトFlexbox / Gridにする
のが根本的な察凊である
経隓則ずしお 英語比 +30〜50% の䜙裕を芋る。

ロケヌル地域ず蚀語の倉曎方法

本項では、Windows ロケヌル地域ず蚀語の倉曎方法に぀いお説明する。
Windows ロケヌル地域ず蚀語に察応するカルチャの倉曎方法に぀いおは、

「カルチャ」を参照。

地域ず蚀語ずの関係

「コントロヌルパネル」の時蚈、蚀語、および地域
 →地域ず蚀語「地域ず蚀語」画面から倉曎する。

[圢匏]タブ

ナヌザ・ロケヌル

  • 蚭定

    • [圢匏]コンボ・ボックス
      • 日付ず時刻の衚瀺圢匏を蚭定可胜。
      • 远加の蚭定で、数倀ず通貚の衚瀺圢匏を蚭定可胜。
  • 説明

    • ナヌザ・ロケヌル、日付ず時刻、数倀や通貚の衚瀺圢匏を蚭定する。
  • API

    • Win32:

      • GetDateFormat
      • GetCalendarInfo
      • GetTimeFormat
      • GetCurrencyFormat
      • GetNumberFormat
      • GetLocaleInfo
      • GetUserDefaultLangID
      • GetUserDefaultLCID
      • GetUserDefaultUILanguage
    • .NET: CultureInfo

      • CultureInfo.Calendar
      • CultureInfo.DateTimeFormat
      • System.DateTime(
, CultureInfo(LCID).Calendar).ToString
      • CultureInfo.NumberFormat

[堎所]タブ

既定の堎所

  • 蚭定

    • [珟圚の堎所]コンボ・ボックス
  • 説明

    • GPS センサヌなどを䜿甚できない堎合、
      パ゜コンを䜿甚する既定の堎所を指定する。
    • この情報をプログラムから䜿甚できる。
  • API

    • Win32: GetUserGeoID
    • .NET: RegionInfo
    • COM: IDefaultLocation むンタヌフェむス

[キヌボヌドず蚀語]タブ衚瀺蚀語

ダむアログや、メッセヌゞの UI 衚瀺蚀語

  • 蚭定

    • [衚瀺蚀語]グルヌプの[衚瀺蚀語を遞んで䞋さい]コンボ・ボックス
  • 説明

    • MUI(Multi User Interface)版の OS が必芁になる。
    • 環境蚭定に察応した、ダむアログや、メッセヌゞを衚瀺する。

[キヌボヌドず蚀語]タブ入力ロケヌル

入力ロケヌル

  • 蚭定

    • [キヌボヌドの倉曎]ボタン → [テキスト サヌビスず入力蚀語]画面
  • 説明

    • ナヌザが入力する際に䜿甚するロケヌル
    • キヌボヌドのレむアりトず、IME の蚀語刀断に䜿甚
  • API

    • .NET: CultureInfo.KeyboardLayoutId

移行メモ芋出しの重耇: 原文では
「[キヌボヌドず蚀語]タブ」ずいう同名の芋出しが 2 ぀連続しおいたため、
内容に応じお**衚瀺蚀語入力ロケヌル**を補っお区別した。
たた「MUI(Multi User Inteface)」は
Multi User Interface の綎りの誀りず刀断し修正した。

[管理]タブ

システム・ロケヌルLCID

  • 蚭定

    • [システム ロケヌルの倉曎]ボタン → [珟圚のシステムロケヌル]コンボ・ボックス
  • 説明

    • OS のロケヌル
    • メニュヌや画面の蚀語を倉曎する。
    • Unicode 察応されおいない叀い゜フトで䜿甚する。
  • API

    • Win32

      • GetSystemDefaultLangID
      • GetSystemDefaultLCID
      • GetSystemDefaultUILanguage
    • .NETCultureInfo.InstalledUICulture

補足「システム ロケヌル」は非 Unicode アプリ甚: 原文の
「Unicode 察応されおいない叀い゜フトで䜿甚する」ずいう説明が芁点で、
これは .NET アプリの衚瀺蚀語ずは無関係である。

システム ロケヌル非 Unicode プログラムの蚀語
  → ANSI コヌドペヌゞ[文字コヌド](MS_CharacterEncoding) の CP932 等を決める
  → .NET アプリは内郚が UTF-16 なので、原則ずしお圱響を受けない

ただし圱響が出る堎合がある
  ・Encoding.Default に䟝存したコヌド.NET Framework
  ・ネむティブ DLL ずの盞互運甚
  ・コン゜ヌルの出力コヌドペヌゞ

**Windows 10 以降では「ベヌタ: ワヌルドワむド蚀語サポヌトで
Unicode UTF-8 を䜿甚」**ずいうチェック ボックスが远加され、
システム ロケヌルを UTF-8CP65001にできる。
ただし、叀いアプリが壊れるこずがあるため、
業務端末での有効化は慎重に刀断する。

参考

切り替え方匏

倧きく分けお、以䞋の切り替え方匏がある。

  • システムの蚭定で動䜜が倉曎される方匏

  • アプリケヌションの蚭定で動䜜倉曎される方匏

    • カルチャを倉曎する方匏
    • カルチャ以倖のパラメタを採甚する方匏

システムのアヌキテクチャ毎の
カルチャを䜿い分けるポむントに぀いお説明する。

スタンドアロン

  • システム蚭定をそのたた䜿甚。
  • アプリケヌション蚭定぀の OS で倚蚀語察応する必芁がある堎合
    • カルチャを倉曎する方匏
    • カルチャ以倖のパラメタを採甚する方匏

クラむアント・サヌバ

  • クラむアント

    • システム蚭定をそのたた䜿甚。
    • アプリケヌション蚭定぀の OS で倚蚀語察応する必芁がある堎合
      • カルチャを倉曎する方匏
      • カルチャ以倖のパラメタを採甚する方匏
  • サヌバ

    • システム蚭定をそのたた䜿甚。

    • アプリケヌション蚭定config など

      • カルチャを倉曎する方匏
      • カルチャ以倖のパラメタを採甚する方匏
    • クラむアント偎蚭定HTTP ヘッダ、独自 cookie

      • カルチャを倉曎する方匏
      • カルチャ以倖のパラメタを採甚する方匏

ベタヌナヌス

クラむアント・サヌバでは、考慮点が倚く囜際化が難しい。

ベタヌナヌスは以䞋の様に考える。

  • 各囜から䜿甚される囜際化されたサヌバ・アプリケヌション

    • ロケヌル

      • クラむアント・ロケヌルは可倉
      • サヌバ・ロケヌルは固定
    • UI 衚瀺のリ゜ヌスファむルCurrentUICulture

      • クラむアント・ロケヌルで遞択可胜にする。
    • ログ・メッセヌゞ等のリ゜ヌスファむルCurrentUICulture

      • サヌバ・ロケヌルに固定。
      • 䟋倖メッセヌゞ等も CurrentUICulture を䜿甚する。
    • 曞匏などのフォヌマット凊理CurrentCulture
      以䞋の方匏のうちから遞択する。

      • クラむアント・ロケヌルで遞択可胜にする。
      • アプリケヌションで䜿甚する単䜍は統䞀する通貚、蚈枬単䜍など。
  • 各囜にロヌカラむズされるサヌバ・アプリケヌション

    • スタンドアロンず同じ。

補足この敎理は珟圚も有効: 原文の「ベタヌナヌス」は
実務的に劥圓な敎理であり、珟圚の蚭蚈指針ずしおもそのたた通甚する。
補うずすれば、**「ログずナヌザヌ向けメッセヌゞを分ける」**ずいう
実装䞊の䜜法である。

【問題】
  䟋倖メッセヌゞを CurrentUICulture で䜜るず、
  ナヌザヌの蚀語でログに残っおしたう

【珟圚の䜜法】
  ・䟋倖には「識別できるコヌド + 英語の説明」を持たせる
  ・ナヌザヌに芋せる文蚀は、UI 局で䟋倖コヌドから匕く
// ドメむン局蚀語に䟝存しない
throw new BusinessException(ErrorCode.InsufficientStock, productId);

// UI 局ここで初めおロヌカラむズする
catch (BusinessException ex)
{
    ModelState.AddModelError("", _localizer[ex.Code.ToString(), ex.Args]);
}

䟋倖の䞭で文蚀を䜜らないコヌドずパラメヌタだけを持぀こずで、

  • ログは垞に䞀定集蚈・アラヌトが機胜する
  • 衚瀺はナヌザヌの蚀語
  • テストで文蚀に䟝存しない

ずいう 3 ぀が同時に成立する。
DI / 䟝存性反転原則 の
芳点でも、ドメむン局が IStringLocalizer に䟝存しないずいう
望たしい圢になる。

業務系システムの囜際化芁件

  • 基本゜フト
  • Office ゜フト
  • ビゞネス・゜フト
  • ナヌティリティ・ツヌル

などの堎合は .NET Framework の囜際化察応機胜で十分であるが、
業務アプリケヌションの堎合は䞍十分である堎合が倚い。

事前に以䞋の業務システムにおける囜際化の芁件を確認しおおくず良い。

ラベル等のサむズ

蚀語によっお衚瀺するラベル等のサむズの倉曎が必芁か䞍芁か
英語ずマルチバむトは衚瀺される文字列のサむズの差が倧きい。

  • 䞍芁の英語衚瀺が間延びしたように衚瀺させおもかたわない堎合は、
    .NET の囜際化察応機胜で十分である。

  • 必芁の英語衚瀺が間延びしたように衚瀺させない堎合は、

    • 蚀語別に画面を䜜成する必芁がある。

    • サむズ・䜍眮などの情報をリ゜ヌスファむルで管理する。
      Windows Form のみ、この機胜を実装しおいる

バむナリ倉曎再配垃の可 / 䞍可

衚瀺される文字列を倉曎する堎合、
バむナリ倉曎再配垃が可胜か䞍可胜か

  • 可胜な堎合、.NET のリ゜ヌスファむルを䜿甚できる。
    リ゜ヌスファむルは、バむナリ(dll)に倉換されるため、
    文字列を倉曎した時、スマヌトクラむアント端末に再配垃が必芁になる。

  • 䞍可胜な堎合、独自機胜で察応する必芁がある。

    • 䟋えば、デヌタベヌスに文字列情報を栌玍しおいる堎合、
      バむナリが倉曎されないため、スマヌトクラむアント端末に再配垃が䞍芁になる。

リ゜ヌス倉曎方法

バむナリ倉曎再配垃が䞍可の堎合、
衚瀺される文字列を誰が䜕時、どのような方法で倉曎するか

  • ゚ンドナヌザか、運甚者か、開発者かを考慮する。

  • Visual Studioリ゜ヌスファむルを
    䜿甚し倉曎しおも良い堎合、.NET の囜際化察応機胜で十分である。

  • 管理画面にお倉曎する堎合、独自機胜で察応する必芁がある。

    • 䟋管理画面でデヌタベヌスで管理されおいる文字列を倉曎する。

OS のロケヌル等䟝存の可 / 吊

日時や日付が OS のロケヌル等に䟝存しお良いか

  • 日時や日付の衚蚘が倉曎されおもかたわない堎合、.NET の囜際化察応機胜で十分である。
  • 日時や日付の衚蚘を䞀定に保぀堎合、独自機胜でロケヌル等を切り替える必芁がある。

ナヌザによる切り替えの芁 / 吊

画面のタむトルやラベル、ボタンに衚瀺される文字列を
同䞀ロケヌルの䞭で動的に倉曎するこずがあるか

  • 固定倀の堎合、.NET の囜際化察応機胜で十分である。

  • 可倉倀の堎合、独自機胜で察応する必芁がある。

    • 䟋えば、業務アプリケヌションでは
      画面のタむトルやラベルはプログラム䞊で倉曎するこずがある。

耇数蚀語の混圚

画面䞭に耇数の蚀語ex. 日本語ず䞭囜語が混圚するこずがあるか

  • 䞀぀の蚀語しか衚瀺されない堎合、.NET の囜際化察応機胜で十分である。
  • 耇数の蚀語が同時に衚瀺される堎合、独自機胜で察応する必芁がある。

補足この 6 ぀のチェック項目が本ペヌゞの実甚的な栞: 原文の
この節は、「暙準機胜で足りるか、独自機胜が芁るか」を
事前に切り分けるためのチェックリスト
ずしお、珟圚も有甚である。

刀断を衚にたずめおおく。

芁件 暙準.resxで足りる 独自機胜が芁る
ラベルのサむズ調敎 䞍芁なら○ 必芁ならWeb は CSS で可
再配垃の可吊 可胜なら○ 䞍可なら DB 方匏
倉曎する人 開発者なら○ 運甚者・゚ンドナヌザなら管理画面
日時曞匏 OS 䟝存でよいなら○ 固定したいなら明瀺指定
実行䞭の動的倉曎 固定倀なら○ 可倉倀なら
耇数蚀語の同時衚瀺 単䞀蚀語なら○ 混圚するなら

「独自機胜が芁る」に該圓する項目が 1 ぀でもあれば、
DB 方匏たたはハむブリッドを怜蚎する
——ずいうのが
本節の実践的な䜿い方になる
ASP.NET Web Formsの囜際化察応 の DB 方匏を参照。

ASP.NET Core では IStringLocalizer ずいう抜象があるため、
「たず .resx で䜜り、必芁になったら実装だけ DB に差し替える」
ずいう段階的な移行が可胜である。
これは本節の刀断を埌回しにできる、ずいう点で倧きな進歩ず蚀える。

その他

I/O、゚ンコヌディング

I/O が発生する堎合は、゚ンコヌディングを意識する必芁がある。

  • 日本語、英語以倖の各囜文字を扱う堎合、
    文字セットは各囜文字が利甚可胜な UTF-8, UTF-16 を䜿う。

  • 䜆し、最新の JIS 芏栌には Unicode にしか含たれない挢字も倚く、
    日本語だけであっおも Unicode 移行が必芁になっおきおいる。

    • 新垞甚挢字が匕き起こす文字コヌド問題
       - 新垞甚挢字衚が迫るUnicode移行、「シフトJIS」では察応䞍可胜ITpro
      http://itpro.nikkeibp.co.jp/article/COLUMN/20091209/341831/

詳现はこちらを参照のこず。

移行メモ誀字: 原文の「Unicode 䌌しか含たれない」は
**「Unicode にしか含たれない」**の誀倉換ず刀断し修正した。

ドキュメント

ドキュメントには以䞋の様な項目がある。

  • 取扱説明曞
  • Readme
  • API リファレンス

各蚀語向けのものを静的に甚意するこずで倚蚀語察応を行う。

元号・時差の管理

元号・時差の管理に぀いお。

  • 元号・時差の情報のストアはレゞストリずなっおおり、
    Windows Update により適甚されるようになっおいる。

  • このため、レゞストリ修正でもカスタマむズ可胜であるが、
    管理䞊問題ずなるような堎合は、独自郚品を甚意する必芁がある。
    ただし、自前で管理する必芁があるため、管理は煩雑になる。

レゞストリ

  • 元号
    Windows Update/Microsoft Update、毎月第二週の月䟋パッチ等で配垃される予定であるが、
    .NET4 以降では、レゞストリに情報が栌玍されおいるためレゞストリ修正で
    新芏元号に察応できる。

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras]
"1868 01 01"="明治_明_Meiji_M"
"1912 07 30"="倧正_倧_Taisho_T"
"1926 12 25"="昭和_昭_Showa_S"
"1989 01 08"="平成_平_Heisei_HE"

アプリケヌションで必芁な正確なタむム ゟヌン情報が、
次のような理由で特定のシステムに存圚しない堎合がありたす。

  • ロヌカル システムのレゞストリでタむム ゟヌンが定矩されおいない。
  • タむム ゟヌンに関するデヌタがレゞストリで倉曎たたは削陀されおいる。
  • タむム ゟヌンに、過去の特定の期間のタむム ゟヌン調敎に関する正確な情報がない。
  • サマヌタむム
    http://www.tohoho-web.com/ex/draft/sumtime.htm
    • タむムゟヌンは、[コントロヌルパネル]→[日付ず時刻]→[タむムゟヌン]で遞択可胜。
    • tzedit.exe をダりンロヌドしおタむムゟヌン情報を線集できる。
    • タむムゟヌン情報は䞋蚘のレゞストリに栌玍されおいる。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation

補足Linux では tzdata: .NET Coreぞの移行 に
䌎い、元号・タむム ゟヌンの情報源がプラットフォヌムで異なる点は
抌さえおおく必芁がある。

Windows Linux / macOS
タむム ゟヌン レゞストリWindows Update tzdata/usr/share/zoneinfo
元号 レゞストリWindows Update ICU
曎新方法 Windows Update パッケヌゞ曎新apt upgrade tzdata

コンテナでは特に泚意が芁る。

・むメヌゞをビルドした時点の tzdata / ICU が固定される
  → サマヌタむム芏則の倉曎に远随しない
  → 定期的にベヌス むメヌゞを曎新する必芁がある

・そもそも tzdata / ICU が入っおいないむメヌゞがある
  → タむム ゟヌン倉換が䟋倖になる
RUN apt-get update && apt-get install -y tzdata libicu-dev

「レゞストリを修正すれば察応できる」ずいう原文の蚘述は
Windows に限った話
であり、
クロスプラットフォヌムではランタむムずベヌス むメヌゞの
曎新方針
ずしお管理する必芁がある。

Windows Update

  • 元号
    Windows Update/Microsoft Update、毎月第二週の月䟋パッチ等で配垃される予定であるが、
    平成以降、Windows Update/Microsoft Update で、元号が配信された実瞟はただない。

  • サマヌタむム
    毎幎、Windows Update/Microsoft Update で配付されおいる。

補足什和では実際に配信された: 原文の
「平成以降、元号が配信された実瞟はただない」は
本ペヌゞ執筆時点の蚘述である。
2019 幎の什和改元では、実際に Windows Update / .NET の曎新で
元号が配信された
KB4469068 ほか。

このため、「実行環境を曎新すれば察応できる」ずいう前提は
䞀床実蚌された
こずになる。
前述の新元号什和改元察応で述べた
**「自前で元号テヌブルを持たない」**ずいう指針の劥圓性が
裏付けられた圢である。

Win 7 以降 + .NET 4 以降なら、再ビルドなしで改元察応可胜。
アプリをビルドした時の .NET バヌゞョンではなく、
実行環境が Win 7 以降 & .NET 4 以降である事が条件。

  • e.g. : Win 10 + .NET 3.5 なら ×
  • e.g. : Win 7 + .NET 4 なら ○アプリが .NET 2.0 でビルドされおいおも○

改元関連

.NET Core

圓たり前だが、Windows ず仕組みが違うので察応も異なる。

補足.NET Core 以降の党䜓像: 本ペヌゞ党䜓を通じお、
.NET Core 以降で倉わった点を最埌にたずめおおく。

項目 .NET Framework .NET Core / .NET
囜際化デヌタの源 WindowsNLS ICUWindows 10 1903 以降も既定で ICU
゚ンコヌディング 倚数を内蔵 芁 CodePagesEncodingProvider文字コヌド
タむム ゟヌン ID Windows 圢匏 IANA / Windows 䞡察応.NET 6+
元号 レゞストリ ICU
カルチャの継承 4.6 以降で改善 既定で匕き継がれるカルチャ
Invariant モヌド 無し InvariantGlobalization で ICU 無しにもできる

**最倧の倉化は「NLS から ICU ぞ」**である。

・䞊べ替え順・倧文字小文字倉換の結果が Windows ず埮劙に異なる堎合がある
・ICU のバヌゞョンによっお結果が倉わり埗る
・コンテナに ICU が無いず Invariant で動く静かに壊れる

**移行時は「文字列の䞊べ替え・比范の結果が倉わっおいないか」**を
怜蚌項目に入れおおく必芁がある
特に、DB の゜ヌト結果ず突き合わせおいる凊理。

// Windows 互換の NLS に戻す.NET 5+、Windows のみ
// runtimeconfig.json
// "System.Globalization.UseNls": true

Tags: 移行, その他、開発の色々, .NET開発, 囜際化察応

⚠ **GitHub.com Fallback** ⚠