ここではカルチャに設定される固有の書式・テキスト処理の規則と暦について見ていきます。
ブラウザで使用しているフォントによっては、この文章の一部で正しく表示されない文字があるかもしれません。 実行結果についても、実行環境によって異なる結果となる場合がある点に注意してください。
カルチャと書式
ニュートラルでないカルチャには、日時や数値に固有の書式が割り当てられています。 この書式は、カルチャの言語・国・地域にあわせて桁の区切・月の名前・曜日名・通貨記号などの文字列がローカライズされた表記・形式となっています。 これらの書式は、数値や日付・時間などの値を文字列化する場合などに使用されます。
スレッドのカルチャと書式
ToStringなどのメソッドでは、書式を指定しなかった場合やカルチャに依存する形式に書式化される書式指定文字列を使用した場合は、現在のスレッドのカルチャに従ってローカライズされた形式で文字列化されます。 そのため、スレッドのカルチャを変更するとこれらのメソッドの結果にも影響します。
次のコードでは、スレッドのカルチャを変更して、書式を指定しない場合とローカライズされる書式指定文字列を使った場合の文字列化の結果を出力しています。
このように、スレッドのカルチャに応じて、桁区切り記号や小数点記号・通貨記号、月名・曜日名がローカライズされて文字列化されます。
カルチャと書式プロバイダ
ToStringなどのメソッドは、引数にCultureInfoを指定することが出来ます。 スレッドのカルチャを変更する代わりにToStringメソッドにCultureInfoを指定することで、そのカルチャの書式を使うように指定することが出来ます。
次のコードでは、先のコードを少し変更し、スレッドのカルチャは変更せずにToStringメソッドの引数にCultureInfoを指定した場合の文字列化の結果を出力しています。
このように、ToStringメソッドの引数にCultureInfoを指定した場合、(スレッドのカルチャとは無関係に)指定されたカルチャに固有な形式へとローカライズされた文字列に変換されます。
この例で使用したToStringメソッドのオーバーロードは、IFormatProviderインターフェイスを引数に取るようになっています。 これは書式プロバイダと呼ばれるもので、数値や日付・時間などを文字列化するときに使用する書式を参照する際に呼び出されます。 CultureInfoクラスはIFormatProviderインターフェイスを実装しているため、ToStringメソッドに渡すことが出来ます。 この場合、CultureInfo自身が書式プロバイダとして機能し、ローカライズされた形式の書式を提供するようになります。
このときに使用される具体的な書式は、数値ならCultureInfo.NumberFormatプロパティで取得できるNumberFormatInfoクラス、日付と時間の場合はCultureInfo.DateTimeFormatプロパティで取得できるDateTimeFormatInfoクラスを使って決定されます。
ToString等のメソッドと書式プロバイダ・IFormatProviderインターフェイスの関係については書式の定義と実装で解説しているので、独自に実装する場合やカスタマイズする場合などはそちらを参照してください。
数値の書式 (NumberFormatInfo)
NumberFormatInfoクラスは、桁区切り・小数点・通貨単位など数値に関する記号や書式化のルールを提供するクラスで、特定のカルチャにローカライズされた形式で取得することが出来ます。
このクラスのコンストラクタでは特定の言語や国・地域を指定することは出来ず、インバリアントなインスタンスしか作成出来ません。 代わりに、ニュートラルでないカルチャのCultureInfo.NumberFormatプロパティから、カルチャに対応するNumberFormatInfoを取得することが出来ます。
次のコードでは、いくつかのカルチャでのNumberFormatInfoを取得し、NumberFormatInfoに設定されているプロパティの内容を表示しています。
NumberFormatInfoのプロパティを設定することで、書式を変えることも出来ます。 例えば、桁区切りを4桁毎(万単位)にしたり、通貨記号や小数点・桁区切りの記号を全角にしたりすることが出来ます。 以下の例では、NumberFormatInfoのプロパティを変更して書式をカスタマイズしています。 なお、比較のためにカスタマイズしていないデフォルトの書式も併記しています。
日付と時間の書式 (DateTimeFormatInfo)
DateTimeFormatInfoクラスは、日付・時刻・午前/午後や曜日名・月名など日付と時刻に関する表記と書式化のルールを提供するクラスで、特定のカルチャにローカライズされた形式で取得することが出来ます。
NumberFormatInfoと同様、このクラスのコンストラクタでは特定の言語や国・地域を指定することは出来ず、インバリアントなインスタンスしか作成出来ません。 代わりに、ニュートラルでないカルチャのCultureInfo.DateTimeFormatプロパティから、カルチャに対応するDateTimeFormatInfoを取得することが出来ます。
次のコードでは、いくつかのカルチャでのDateTimeFormatInfoを取得し、DateTimeFormatInfoに設定されているプロパティの内容を表示しています。
NumberFormatInfoと同様、DateTimeFormatInfoのプロパティを変更して書式をカスタマイズすることが出来ます。 以下の例では、月名をカスタマイズしています。 なお、比較のためにカスタマイズしていないデフォルトの書式も併記しています。
ほとんど(すべて?)のカルチャでは、デフォルトでグレゴリオ暦が使用されます。 使用する暦を変更する必要がある場合は、DateTimeFormatInfo.Calendarプロパティを変更します。 また、月名は第十三月が存在する暦に対応するため要素が13個の配列を指定する必要があります。 暦(Calendar)については後ほど詳しく解説します。
カルチャとテキスト処理
書式と同様、ニュートラルでないカルチャには固有の文字列比較・変換の規則が割り当てられています。 例えば、大文字小文字の変換規則や、文字の並べ替えの規則などです。
スレッドのカルチャとテキスト処理
Array.Sortなどのメソッドで文字列を比較する場合、String.Compareメソッドが呼び出されます。 String.Compareにオプションを指定しなかった場合のデフォルトの動作では、現在のスレッドのカルチャに固有な規則に基づいて比較が行われます。 同様に、String.ToUpperやString.ToLowerなどのメソッドでもカルチャ固有の規則で変換されます。 そのため、スレッドのカルチャを変更するとこれらのメソッドの結果にも影響します。
次のコードでは、スレッドのカルチャを変更し、Array.Sortメソッドを使って文字列の配列をソートした場合の結果を出力しています。 なお、この例で使用しているCultureInfo.TextInfo.ListSeparatorはカルチャ固有のリスト区切り文字を取得するプロパティです。
文字列の比較 (CompareInfo)
CompareInfoクラスは、文字列の並べ替え(大小関係)と等価性の規則を提供するクラスで、特定のカルチャでの規則に基づいた文字列の検索・比較を行うことが出来ます。
このクラスのインスタンスを作成するには、GetCompareInfoメソッドでカルチャの名前もしくはIDを指定するか、CultureInfo.CompareInfoプロパティからカルチャに対応するCompareInfoを取得することが出来ます。
次のコードでは、いくつかのカルチャでのCompareInfoを取得し、CompareInfo.Compareメソッドを使って文字列の比較を行っています。
なお、CompareInfoやCompareOptionsを指定した文字列の検索・比較は文字列と比較オプション・カルチャの並べ替え規則でも詳しく解説しています。
文字列の変換 (TextInfo)
TextInfoクラスは、文字列の変換の規則を提供するクラスで、特定のカルチャでの規則に基づいた大文字小文字の変換やコードページの取得などを行うことが出来ます。
このクラスのコンストラクタは公開されていないため、カルチャに対応するTextInfoのインスタンスを取得するには、CultureInfo.TextInfoプロパティを参照します。
次のコードでは、いくつかのカルチャでのTextInfoを取得し、TextInfoのメソッドを使って文字列を大文字化・小文字化・タイトルケース化しています。
なお、StringクラスのToLower/ToUpper/ToUpperInvariant等のメソッドとの違いは文字列の加工・編集で詳しく解説しているのでご覧ください。
また、文字列の変換の他に、特定のカルチャで使用されるコードページの取得を行うことも出来ます。 次の例では、いくつかのカルチャでのTextInfoを取得し、TextInfoに設定されているコードページを表示しています。
カルチャと暦 (Calendar)
Calendarクラスおよびその派生クラスを使うことで、特定の暦を使った年数の計算・日時の変換を行うことが出来ます。 また、いくつかのCalendarの派生クラスはカルチャに設定することが出来、数値の時刻のフォーマットとは別に特定の暦に対応した表記に変更することも出来ます。
例えば、和暦を表すJapaneseCalendarクラスをカルチャに設定すると、年の表記に西暦ではなく年号が用いられるようになります。
日時の変換
DateTime型とCalendarクラスを組み合わせて使うことで、ある暦での日時を別の暦での日時に変換することが出来ます。 次の例は、JapaneseCalendarクラスを使って和暦と西暦(グレゴリオ暦)での日付を相互に変換するものです。
スローされている例外のメッセージにもあるとおり、JapaneseCalendarクラスで実装される暦ではグレゴリオ暦1868年9月8日より前の日付は定義されていません。
日時の加減算
DateTime型ではグレゴリオ暦が用いられるため、DateTime.Add・DateTime.Subtractメソッドでは1年が12ヶ月365日、1週が7日、グレゴリオ暦での閏年の定義に基づいて日時の加減算が行われます。 Calendarクラスを用いることで、特定の暦での年・月・週および置閏の規則に基づいた日時の加減算を行うことが出来ます。 次の例では、.NET Frameworkで実装されている暦を使って基準となる日から数年・数ヶ月・数週前後の日付を求めています。
結果からも分かるとおり、ユリウス暦(JulianCalendar)、ヘブライ暦(HebrewCalendar)やイスラム歴(HijriCalendar)では一年・一月の数え方がグレゴリオ暦(GregorianCalendar)とは異なるので、グレゴリオ暦での一年後・一月後とは異なる日付となります。
和暦(JapaneseCalendar)では年号が異なるだけでそれ以外はグレゴリオ暦と同じなので、加減算の結果は同じとなります。 なお、JapaneseLunisolarCalendarは太陽年および太陰月に基づく太陰太陽暦を実装するクラスです。