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 件のコメント:
コメントを投稿