CultureInfo クラスでは、各カルチャ(ロケール)に対応した数値、日時などの書式(パターン)を管理していて、CultureInfo.DateTimeFormat プロパティで日時表示関連の情報 DateTimeFormatInfo を取得でき、更に、DateTimeFormatInfo.FullDateTimePattern プロパティで、標準の完全な日時表示書式(長い形式の日付と長い形式の時刻を合わせた書式で、書式文字列「"F"」に関連付けられている)を取得できる。
- MSDN:CultureInfo クラス(System.Globalization)
- MSDN:CultureInfo.DateTimeFormat プロパティ(System.Globalization)
- MSDN:DateTimeFormatInfo.FullDateTimePattern プロパティ(System.Globalization)
例えば「今日」を、標準の完全な日時表示書式で表す場合は、
using System; using System.Globalization; namespace CultureInfoExample { public class Program { public static void Main(string[] args) { CultureInfo cci = CultureInfo.CurrentCulture; Console.WriteLine(" CULTURE NAME FULL DATE TIME PATTERN"); Console.WriteLine("========================================="); Console.WriteLine(" {0,-17}{1}", cci.Name, cci.DateTimeFormat.FullDateTimePattern); Console.WriteLine("\nTODAY : "); Console.WriteLine(" Standard Full {0}", DateTime.Now.ToString("F")); Console.WriteLine(" Custom {0}", DateTime.Now.ToString("yyyy/MM/dd (ddd) H:mm:ss")); } } } /* * ビルド: * * gmcs cultureinfoexample01.cs * * 実行: * * mono cultureinfoexample01.exe * */
$ mono cultureinfoexample01.exe CULTURE NAME FULL DATE TIME PATTERN ========================================= ja-JP yyyy'年'M'月'd'日' H:mm:ss TODAY : Standard Full 2010年3月10日 22:51:21 Custom 2010/03/10 (水) 22:51:21
そして、次のコードを使用して、Mono 2.6.1(on Ubuntu 9.04)と .NET Framework 3.5 SP1(on Windows 7 RC)の各カルチャ標準の完全な日時表示書式を、出力結果で比較してみると
using System; using System.Globalization; namespace CultureInfoExample { public class Program { public static void Main(string[] args) { string[] cultures = new [] { "", // インバリアント カルチャ "af-ZA", // アフリカーンス語 (南アフリカ) "sq-AL", // アルバニア語 (アルバニア) "ar-DZ", // アラビア語 (アルジェリア) "ar-BH", // アラビア語 (バーレーン) "ar-EG", // アラビア語 (エジプト) "ar-IQ", // アラビア語 (イラク) "ar-JO", // アラビア語 (ヨルダン) "ar-KW", // アラビア語 (クウェート) "ar-LB", // アラビア語 (レバノン) "ar-LY", // アラビア語 (リビア) "ar-MA", // アラビア語 (モロッコ) "ar-OM", // アラビア語 (オマーン) "ar-QA", // アラビア語 (カタール) "ar-SA", // アラビア語 (サウジアラビア) "ar-SY", // アラビア語 (シリア) "ar-TN", // アラビア語 (チュニジア) "ar-AE", // アラビア語 (U.A.E.) "ar-YE", // アラビア語 (イエメン) "hy-AM", // アルメニア語 (アルメニア) "az-Cyrl-AZ", // アゼリ語 (アゼルバイジャン、キリル文字) "az-Latn-AZ", // アゼリ語 (アゼルバイジャン、ラテン文字) "eu-ES", // バスク語 (バスク) "be-BY", // ベラルーシ語 (ベラルーシ) "bg-BG", // ブルガリア語 (ブルガリア) "ca-ES", // カタロニア語 (カタルーニャ) "zh-HK", // 中国語 (香港特別行政区) "zh-MO", // 中国語 (マカオ) "zh-CN", // 中国語 (中国) "zh-Hans", // 簡体字中国語 "zh-SG", // 中国語 (シンガポール) "zh-TW", // 中国語 (台湾) "zh-Hant", // 繁体字中国語 "hr-HR", // クロアチア語 (クロアチア) "cs-CZ", // チェコ語 (チェコ共和国) "da-DK", // デンマーク語 (デンマーク) "dv-MV", // ディベヒ語 (モルジブ) "nl-BE", // オランダ語 (ベルギー) "nl-NL", // オランダ語 (オランダ) "en-AU", // 英語 (オーストラリア) "en-BZ", // 英語 (ベリーズ) "en-CA", // 英語 (カナダ) "en-029", // 英語 (西インド諸島) "en-IE", // 英語 (アイルランド) "en-JM", // 英語 (ジャマイカ) "en-NZ", // 英語 (ニュージーランド) "en-PH", // 英語 (フィリピン) "en-ZA", // 英語 (南アフリカ) "en-TT", // 英語 (トリニダードトバゴ) "en-GB", // 英語 (英国) "en-US", // 英語 (U.S.) "en-ZW", // 英語 (ジンバブエ) "et-EE", // エストニア語 (エストニア) "fo-FO", // フェロー語 (フェロー諸島) "fa-IR", // ペルシア語 (イラン) "fi-FI", // フィンランド語 (フィンランド) "fr-BE", // フランス語 (ベルギー) "fr-CA", // フランス語 (カナダ) "fr-FR", // フランス語 (フランス) "fr-LU", // フランス語 (ルクセンブルグ) "fr-MC", // フランス語 (モナコ) "fr-CH", // フランス語 (スイス) "gl-ES", // ガリシア語 (スペイン) "ka-GE", // グルジア語 (グルジア共和国) "de-AT", // ドイツ語 (オーストリア) "de-DE", // ドイツ語 (ドイツ) "de-LI", // ドイツ語 (リヒテンシュタイン) "de-LU", // ドイツ語 (ルクセンブルグ) "de-CH", // ドイツ語 (スイス) "el-GR", // ギリシア語 (ギリシア) "gu-IN", // グジャラート語 (インド) "he-IL", // ヘブライ語 (イスラエル) "hi-IN", // ヒンディー語 (インド) "hu-HU", // ハンガリー語 (ハンガリー) "is-IS", // アイスランド語 (アイスランド) "id-ID", // インドネシア語 (インドネシア) "it-IT", // イタリア語 (イタリア) "it-CH", // イタリア語 (スイス) "ja-JP", // 日本語 (日本) "kn-IN", // カナラ語 (インド) "kk-KZ", // カザフ語 (カザフスタン) "kok-IN", // コンカニ語 (インド) "ko-KR", // 韓国語 (韓国) "ky-KG", // キルギス語 (キルギス) "lv-LV", // ラトビア語 (ラトビア) "lt-LT", // リトアニア語 (リトアニア) "mk-MK", // マケドニア語 (マケドニア) "ms-BN", // マレー語 (ブルネイ ダルサラーム) "ms-MY", // マレー語 (マレーシア) "mr-IN", // マラティー語 (インド) "mn-MN", // モンゴル語 (モンゴル) "nb-NO", // ノルウェー語 (ブークモール、ノルウェー) "nn-NO", // ノルウェー語 (ニノーシク、ノルウェー) "pl-PL", // ポーランド語 (ポーランド) "pt-BR", // ポルトガル語 (ブラジル) "pt-PT", // ポルトガル語 (ポルトガル) "pa-IN", // パンジャブ語 (インド) "ro-RO", // ルーマニア語 (ルーマニア) "ru-RU", // ロシア語 (ロシア) "sa-IN", // サンスクリット語 (インド) "sr-Cyrl-CS", // セルビア語 (セルビア、キリル文字) "sr-Latn-CS", // セルビア語 (セルビア、ラテン文字) "sk-SK", // スロバキア語 (スロバキア) "sl-SI", // スロベニア語 (スロベニア) "es-AR", // スペイン語 (アルゼンチン) "es-BO", // スペイン語 (ボリビア) "es-CL", // スペイン語 (チリ) "es-CO", // スペイン語 (コロンビア) "es-CR", // スペイン語 (コスタリカ) "es-DO", // スペイン語 (ドミニカ共和国) "es-EC", // スペイン語 (エクアドル) "es-SV", // スペイン語 (エルサルバドル) "es-GT", // スペイン語 (グアテマラ) "es-HN", // スペイン語 (ホンジュラス) "es-MX", // スペイン語 (メキシコ) "es-NI", // スペイン語 (ニカラグア) "es-PA", // スペイン語 (パナマ) "es-PY", // スペイン語 (パラグアイ) "es-PE", // スペイン語 (ペルー) "es-PR", // スペイン語 (プエルトリコ) "es-ES", // スペイン語 (スペイン) "es-ES_tradnl", // スペイン語 (スペイン、従来の並べ替え順序) "es-UY", // スペイン語 (ウルグアイ) "es-VE", // スペイン語 (ベネズエラ) "sw-KE", // スワヒリ語 (ケニア) "sv-FI", // スウェーデン語 (フィンランド) "sv-SE", // スウェーデン語 (スウェーデン) "syr-SY", // シリア語 (シリア) "ta-IN", // タミル語 (インド) "tt-RU", // タタール語 (ロシア) "te-IN", // テルグ語 (インド) "th-TH", // タイ語 (タイ) "tr-TR", // トルコ語 (トルコ) "uk-UA", // ウクライナ語 (ウクライナ) "ur-PK", // ウルドゥー語 (パキスタン) "uz-Cyrl-UZ", // ウズベク語 (ウズベキスタン、キリル文字) "uz-Latn-UZ", // ウズベク語 (ウズベキスタン、ラテン文字) "vi-VN" // ベトナム語 (ベトナム) }; string pattern = ""; Console.WriteLine(" CULTURE NAME FULL DATE TIME PATTERN"); Console.WriteLine("========================================="); foreach (string culture in cultures) { try { pattern = CultureInfo.GetCultureInfo(culture).DateTimeFormat.FullDateTimePattern; } catch { pattern = "error"; } Console.WriteLine(" {0,-17}{1}", culture, pattern); } } } } /* * ビルド: * * gmcs cultureinfoexample02.cs * * 実行: * * mono cultureinfoexample02.exe * */
おおお、けっこうな違いがある。
どうしてこんなことを調べたかというと、ASP.NET MVC 2 RC の単体テストの失敗ケースで、この差異に起因するものがあったからだ。
Mono では、CultureInfo のインスタンスの生成などは、Mono ランタイム内部の関数を呼び出して処理されており、各カルチャの数値、日時などの書式は、Mono ソース資源的には「/path/to/monosrc/mono/metadata/culture-info-table.h」でまとめられている。では、この「culture-info-table.h」を直接修正し、Mono ランタイムの再ビルドを行えばよいのかと言えば、「culture-info-table.h」自体はツールを使用して生成されており、「Do not edit.」と「culture-info-table.h」の頭に記述されている。
もちろん、その生成ツール(のソース)もソース資源に含まれており、「/path/to/monosrc/tools/locale-builder」配下に存在する。locale-builder の「README」によれば、「culture-info-table.h」のインプットとして「Unicode CLDR」(Unicode Releases Common Locale Data Repository version 1.7)を使用していて、MS.NET との差異を埋めるために「supplementalData.xml and supp/*.xml」以下の資源が用意されているということだ。
上記の、単体テストの失敗ケースの対応としては、カルチャ「es-PR」(スペイン語(プエルトリコ))の標準の完全な日時表示書式を「"d' de 'MMMM' de 'yyyy hh:mm:ss tt"」から「"dddd, dd' de 'MMMM' de 'yyyy hh:mm:ss tt"」に修正する必要があり(MS.NET に合致させるとしたら)、ならば、「supp/es_PR.xml」を修正し、生成ツールのビルド、実行をし、「culture-info-table.h」を再生成すればよいと考えられる。
しかし、そもそも MS.NET に合致させるのが正しいのだろうか?とか、「supp/*.xml」を具体的にどの様に修正したらいいのだろうか?とか、生成用の元ネタである「unicode CLDR」の資源をどのように配置して、生成ツールを実行すればいいのだろうか?とか、めんどくさいなど、基本的なことがよく分からないことに起因したり、しなかったりする、やりたくない理由がてんこ盛りなため、多分やらないwww。
0 件のコメント:
コメントを投稿