System.Globalizationでグローバル指向プログラミング
注意:
この文書は以前「.NETでいきまっしょい!」で公開していたものですが、公開以降メンテナンスされていません。 今や古い情報となった内容が記載されている場合があるのでご注意ください。
1.現在のカルチャ情報を取得
System.Globalization名前空間にあるクラスを利用すれば、カレンダーや書式などの部分を国際対応することができます。 そのまえに、ひとまず国際化というのを置いておいて、自分の国(現在のカルチャ)の情報を取得することから始めます。 CultureInfoクラスは、カルチャに関する様々な情報を扱うためのクラスです。 このクラスの共有読み取り専用プロパティであるCurrentCultureを参照すれば、現在のカルチャ(OSが使用しているカルチャ)の情報を取得することができます。
現在のカルチャ情報を取得
001 002 003 004 005 006 007 008 009 010
011 012 013 014 015 016 017 018 019 020
021 022 023 024 025 026 027 028 029
|
Imports System
Imports System.Globalization
Module Globalization
Sub Main()
' 現在のカルチャ
Dim culture As CultureInfo = CultureInfo.CurrentCulture
' カルチャ名
Console.WriteLine(culture.Name)
Console.WriteLine(culture.DisplayName)
Console.WriteLine(culture.EnglishName)
Console.WriteLine(culture.NativeName)
Console.WriteLine(culture.ThreeLetterISOLanguageName)
' カルチャ情報
Console.WriteLine(culture.Calendar)
Console.WriteLine(culture.DateTimeFormat.LongDatePattern)
Console.WriteLine(culture.DateTimeFormat.LongTimePattern)
Console.WriteLine(culture.DateTimeFormat.ShortDatePattern)
Console.WriteLine(culture.DateTimeFormat.ShortTimePattern)
Console.WriteLine(culture.TextInfo.ANSICodePage)
Console.WriteLine(culture.NumberFormat.CurrencySymbol)
End Sub
End Module
|
| 出力結果 |
ja-JP
日本語 (日本)
Japanese (Japan)
日本語 (日本)
jpn
System.Globalization.GregorianCalendar
yyyy'年'M'月'd'日'
H:mm:ss
yyyy/MM/dd
H:mm
932
\
Press any key to continue
|
前半のコードではカルチャ名に関する文字列を出力しています。 基本的なカルチャの名前は一行目の出力のように「xx-XX」となっています。 前の二文字は言語を表し、後の二文字は国(地域)を表します。 たとえば英語-米国の場合は「en-US」となります。 そのほかにも表記方法が数種類あり、前半の出力がそれを出力したものです。
後半のコードは、カルチャ特有の情報を取得し、表示するものです。 Calenderプロパティは使用するカレンダーを表し、Calendarクラスの派生クラスになります。 この場合ではGregorianCalendarクラス、つまりグレゴリオ暦を使用していることがわかります。 DateTimeFormat、NumberFormatからは日時・数値などの表記に関する情報、TextInfoからはコードページなどに関する情報が取得できます。
2.他のカルチャ情報を取得
このように現在のカルチャについての情報を取得できたわけですが、当然他のカルチャの情報を取得することもできます。 CultureInfoのインスタンスを生成する際に、コンストラクタにカルチャ名を指定することでそのカルチャの情報を記述したCultureInfoオブジェクトを取得できます。
他のカルチャ情報を取得
001 002 003 004 005 006 007 008 009 010
011 012 013 014 015 016 017 018 019 020
021 022 023 024 025
|
Imports System
Imports System.Globalization
Module Globalization
Sub Main()
' 他のカルチャ情報 (英語 - 米国)
Dim culture As New CultureInfo("en-US")
' カルチャ名
Console.WriteLine("{0}, {1}", culture.Name, culture.NativeName)
' カルチャ情報
Console.WriteLine(culture.Calendar)
Console.WriteLine(culture.DateTimeFormat.LongDatePattern)
Console.WriteLine(culture.DateTimeFormat.LongTimePattern)
Console.WriteLine(culture.DateTimeFormat.ShortDatePattern)
Console.WriteLine(culture.DateTimeFormat.ShortTimePattern)
Console.WriteLine(culture.TextInfo.ANSICodePage)
Console.WriteLine(culture.NumberFormat.CurrencySymbol)
End Sub
End Module
|
| 出力結果 |
en-US, English (United States)
System.Globalization.GregorianCalendar
dddd, MMMM dd, yyyy
h:mm:ss tt
M/d/yyyy
h:mm tt
1252
$
Press any key to continue
|
この例では特定のカルチャの情報を取得していますが、使用可能なすべてのカルチャ情報を取得するにはCultureInfo.GetCultures()メソッドを使用します。 この例では出力される文字の関係上、Debugに出力しています。 また、実行結果はCultureTypes.AllCulturesではなくCultureTypes.SpecificCulturesを指定して出力したものです。
すべてのカルチャ情報を取得
001 002 003 004 005 006 007 008 009 010
011 012 013 014 015 016 017 018 019 020
021
|
Imports System
Imports System.Globalization
Module Globalization
Sub Main()
Dim cultures() As CultureInfo = CultureInfo.GetCultures(CultureTypes.AllCultures)
Dim culture As CultureInfo
Debug.WriteLine("Cultures: " + cultures.Length.ToString())
For Each culture In cultures
Debug.WriteLine(culture.Name + ", " + culture.NativeName)
Next
End Sub
End Module
|

実行結果
3.カルチャに対応した書式
様々な国・地域のカルチャ情報を取得できたら、後はそれを活用するだけです。 次の例は、Decimal型の値を通貨として文字列化し、その際の書式をカルチャに依存した書式にするようにしているものです。
カルチャに対応した書式 (通貨)
001 002 003 004 005 006 007 008 009 010
011 012 013 014 015 016 017 018 019 020
021 022 023 024 025 026 027 028 029 030
031 032 033 034 035 036 037 038 039 040
041 042
|
Imports System
Imports System.Globalization
Module Globalization
Sub Main()
Dim currency As Decimal = 123456.78D
' 現在のカルチャ(日本)
OutputCurrency(currency, CultureInfo.CurrentCulture)
' アメリカ
OutputCurrency(currency, New CultureInfo("en-US"))
' カナダ
OutputCurrency(currency, New CultureInfo("en-CA"))
' イギリス
OutputCurrency(currency, New CultureInfo("en-GB"))
' フランス
OutputCurrency(currency, New CultureInfo("fr-FR"))
' ドイツ
OutputCurrency(currency, New CultureInfo("de-DE"))
' イタリア
OutputCurrency(currency, New CultureInfo("it-IT"))
' ロシア
OutputCurrency(currency, New CultureInfo("ru-RU"))
End Sub
Sub OutputCurrency(ByVal currency As Decimal, ByVal culture As CultureInfo)
Debug.WriteLine(culture.DisplayName + ": " + currency.ToString("C", culture.NumberFormat))
End Sub
End Module
|

実行結果
この例ではG8各国のカルチャ情報から通貨形式の書式を取得しています。 ToString()メソッドには、カルチャ情報に依存した形式で出力するバージョンがあります。 今回はそれを用いています。 CultureInfo.NumberFormatプロパティはそのカルチャの数値に関する書式を記述したクラスです。 これをToString()メソッドに渡すことによってその書式に従って数値が文字列化されます。 ちなみに、一つ目の引数である"C"は、その数値を通貨として出力するように指定する数値書式指定文字列というものです。 この実行結果を見てわかるとおり、単なるDecimal型の数値を渡したにも関わらず、通貨文字がその国で用いられているものになったり、通貨文字が先頭に来るか末尾に来るかが変わっています。 また、日本円では通常小数点以下(銭に相当する部分)は扱わないので、この書式では小数点以下が四捨五入され出力されていません。
さらに、数値に関しても各国で表記方法が異なるので、その場合についても見てみることにします。
カルチャに対応した書式 (数値)
001 002 003 004 005 006 007 008 009 010
011 012 013 014 015 016 017 018 019 020
021 022 023 024 025 026 027 028 029 030
031 032 033 034 035 036 037 038 039 040
041 042 043 044 045 046 047 048
|
Imports System
Imports System.Globalization
Module Globalization
Sub Main()
Dim intValue As Integer = 12345678
Dim realValue As Double = 12345.678
' 現在のカルチャ(日本)
OutputValue(intValue, realValue, CultureInfo.CurrentCulture)
' アメリカ
OutputValue(intValue, realValue, New CultureInfo("en-US"))
' カナダ
OutputValue(intValue, realValue, New CultureInfo("en-CA"))
' イギリス
OutputValue(intValue, realValue, New CultureInfo("en-GB"))
' フランス
OutputValue(intValue, realValue, New CultureInfo("fr-FR"))
' ドイツ
OutputValue(intValue, realValue, New CultureInfo("de-DE"))
' イタリア
OutputValue(intValue, realValue, New CultureInfo("it-IT"))
' ロシア
OutputValue(intValue, realValue, New CultureInfo("ru-RU"))
End Sub
Sub OutputValue(ByVal i As Integer, ByVal r As Double, ByVal culture As CultureInfo)
Debug.WriteLine(culture.DisplayName + ": " + _
i.ToString("D", culture.NumberFormat) + _
" " + r.ToString("E", culture.NumberFormat) + _
" " + r.ToString("F", culture.NumberFormat) + _
" " + r.ToString("G", culture.NumberFormat) + _
" " + r.ToString("N", culture.NumberFormat))
End Sub
End Module
|

実行結果 (見やすさのために多少体裁を整えてあります)
まず始めに、数値書式指定文字列について説明すると、「D」は十進、「E」は指数形式、「F」は固定小数点、「G」は一般表記、「N」は数値として書式指定するものです。 この実行結果のように、小数点の表記について「 . (ピリオド)」を用いたり「 , (カンマ)」と国によって小数点の表記が異なります。 さらに、三桁毎の区切り文字も、使用したり使用しなかったりする場合があります。
通貨や数値だけでなく、日付・時刻の表記もローカライズすることができます。
カルチャに対応した書式 (日付・時刻)
001 002 003 004 005 006 007 008 009 010
011 012 013 014 015 016 017 018 019 020
021 022 023 024 025 026 027 028 029 030
031 032 033 034 035 036 037 038 039 040
041 042 043 044 045 046 047 048
|
Imports System
Imports System.Globalization
Module Globalization
Sub Main()
Dim dtmNow As DateTime = DateTime.Now
' 現在のカルチャ(日本)
OutputDateTime(dtmNow, CultureInfo.CurrentCulture)
' アメリカ
OutputDateTime(dtmNow, New CultureInfo("en-US"))
' カナダ
OutputDateTime(dtmNow, New CultureInfo("en-CA"))
' イギリス
OutputDateTime(dtmNow, New CultureInfo("en-GB"))
' フランス
OutputDateTime(dtmNow, New CultureInfo("fr-FR"))
' ドイツ
OutputDateTime(dtmNow, New CultureInfo("de-DE"))
' イタリア
OutputDateTime(dtmNow, New CultureInfo("it-IT"))
' ロシア
OutputDateTime(dtmNow, New CultureInfo("ru-RU"))
' 韓国
OutputDateTime(dtmNow, New CultureInfo("ko-KR"))
' 中国
OutputDateTime(dtmNow, New CultureInfo("zh-CN"))
End Sub
Sub OutputDateTime(ByVal dtm As DateTime, ByVal culture As CultureInfo)
Debug.WriteLine(culture.DisplayName + ": " + dtm.ToString(culture.DateTimeFormat))
End Sub
End Module
|

実行結果 (見やすさのために多少体裁を整えてあります)
4.カルチャに対応した月・曜日
書式や通貨単位だけがカルチャに依存するものではありません。 暦もカルチャに依存します。 日本がそのよい例です。 日本では基本的にはグレゴリオ歴を採用していますが、同時に和暦というものも存在し、年号を用いて「平成〜年」とか「昭和〜年」という表記をします。
さらに、曜日の呼び方や月の名前などもカルチャによって異なります。 次の例ではカルチャ情報から日時に関する情報を取得し、そこから様々なカルチャ依存の情報を取り出しています。
日時に関する情報
001 002 003 004 005 006 007 008 009 010
011 012 013 014 015 016 017 018 019 020
021 022 023 024 025 026 027 028 029 030
031 032 033 034 035 036 037 038 039 040
041 042 043 044 045 046 047 048 049 050
051 052 053 054 055 056 057 058 059 060
061 062 063 064 065 066 067 068 069 070
071 072 073 074 075 076 077 078 079 080
081 082
|
Imports System
Imports System.Globalization
Module Globalization
Sub Main()
' カルチャのインスタンスを生成
Dim culture As New CultureInfo("ja-JP")
' カルチャから日時のフォーマット情報を取得
Dim format As DateTimeFormatInfo = culture.DateTimeFormat
' 現在のカレンダ
Debug.WriteLine(format.Calendar.ToString())
' 曜日名を列挙
EnumerateDayNames(format)
' 月の名前を列挙
EnumerateMonthNames(format)
' 時代(年号)を列挙
EnumerateEras(format)
' 暦を和暦に設定
format.Calendar = New JapaneseCalendar()
' 現在のカレンダ
Debug.WriteLine(format.Calendar.ToString())
' 時代(年号)を列挙
EnumerateEras(format)
End Sub
' 曜日を表す文字列を列挙するメソッド
Sub EnumerateDayNames(ByVal format As DateTimeFormatInfo)
Dim dayName As String
For Each dayName In format.DayNames
Debug.Write(dayName + ", ")
Next
Debug.WriteLine("")
End Sub
' 月を表す文字列を列挙するメソッド
Sub EnumerateMonthNames(ByVal format As DateTimeFormatInfo)
Dim monthName As String
For Each monthName In format.MonthNames
Debug.Write(monthName + ", ")
Next
Debug.WriteLine("")
End Sub
' 時代(年号)を列挙するメソッド
Sub EnumerateEras(ByVal format As DateTimeFormatInfo)
Dim era As Integer
For Each era In format.Calendar.Eras
Debug.WriteLine(era.ToString() + " : " + format.GetEraName(era))
Next
End Sub
End Module
|

実行結果
この例では曜日名、月名、年号などを取得しています。 またDateTimeFormatInfoクラスのCalendarプロパティに和暦を表すJapanezeCalendarクラスのインスタンスを代入してその違いを見ています。 実行結果から分かるとおり、初期状態ではGregorianCalendarが代入されています。 グレゴリオ暦で年号を列挙した場合は「西暦」だけですが、和暦の場合は「平成」、「昭和」などが出力されます。 Calendarクラスについてはこの次以降で説明します。
これ以外の情報として、曜日名と月名を取得していますが、月名は十三項目存在しているかのような出力になっています。 これは、閏月などで第十三月が存在する暦を考慮したものと考えられます。 次のコードでは、各カルチャでは曜日・月の名前をどのように記述するかを調べることができます。
各カルチャでの曜日・月の名前を取得
001 002 003 004 005 006 007 008 009 010
011 012 013 014 015 016 017 018 019 020
021 022 023 024 025 026 027 028 029 030
031 032 033 034 035 036 037 038 039 040
041 042 043 044 045 046 047 048 049 050
051 052 053
|
Imports System
Imports System.Globalization
Module Globalization
Sub Main()
' カルチャのインスタンスを生成
Dim cultures() As CultureInfo = { _
New CultureInfo("ja-JP"), _
New CultureInfo("en-US"), _
New CultureInfo("de-DE"), _
New CultureInfo("fr-FR"), _
New CultureInfo("ru-RU"), _
New CultureInfo("ko-KR"), _
New CultureInfo("zh-CN")}
Dim culture As CultureInfo
Dim format As DateTimeFormatInfo
For Each culture In cultures
' カルチャから日時のフォーマット情報を取得
format = culture.DateTimeFormat
Debug.WriteLine(culture.ToString())
' 曜日名を列挙
EnumerateDayNames(format)
' 月の名前を列挙
EnumerateMonthNames(format)
Next
End Sub
' 曜日を表す文字列を列挙するメソッド
Sub EnumerateDayNames(ByVal format As DateTimeFormatInfo)
' 省略
End Sub
' 月を表す文字列を列挙するメソッド
Sub EnumerateMonthNames(ByVal format As DateTimeFormatInfo)
' 省略
End Sub
End Module
|

実行結果
5.カルチャに対応した暦(こよみ)
先程述べたように、曜日・月の名前のほかにも暦も当然カルチャに依存します。 世界にはグレゴリオ暦ではなくヘブライ暦や回教暦を採用している国・地域もあります。 そのために必ずしも「2003/01/01」が西暦(グレゴリオ暦)を表すとは限らなくなります。 そこで使用されるのがCalendarクラスです。 このクラス自体は抽象クラスですが、この派生クラスである GregorianCalendar や HebrewCalendar では一年の日数、一月の日数などの暦に関する処理が実装されています。
次のコードは和暦で表した日付をシステムが現在使用している暦(このコードを実行した環境ではグレゴリオ暦)になおして表示するコードです。 システムの暦を調べるには、「コントロール パネル」の「地域と言語のオプション」にある「地域オプション」タブで「カスタマイズ」をクリックし、表示されるダイアログの日付タブで調べることができます。 また、ここを変更することで異なる実行結果を得ることもできます。

暦の確認・変更
和暦からシステムの暦(グレゴリオ暦)への日付の変換
001 002 003 004 005 006 007 008 009 010
011 012 013 014 015 016 017 018 019 020
021 022 023 024 025 026 027
|
Imports System
Imports System.Globalization
Module Globalization
Sub Main()
Dim japanese As New JapaneseCalendar()
Dim gregorian As New GregorianCalendar()
Dim gregDateTime As DateTime
' 和暦の平成15年2月7日をグレゴリオ暦(西暦)に直す
gregDateTime = japanese.ToDateTime(15, 2, 7, 0, 0, 0, 0, japanese.CurrentEra)
Console.WriteLine(gregDateTime)
' 西暦でその年を取得する
Console.WriteLine("Gregorian: {0}", gregorian.GetYear(gregDateTime))
' 和暦でその年を取得する
Console.WriteLine("Japanese: {0}", japanese.GetYear(gregDateTime))
End Sub
End Module
|
| 出力結果 |
2003/02/07 0:00:00
Gregorian: 2003
Japanese: 15
Press any key to continue
|
実行した環境では西暦を使用していたので、ToDateTime()メソッドの戻り値は西暦になります。 次のコードは、システムの暦での2001年1月1日から、各暦での一年後および十年後の日付をシステムの暦で取得するものです。
各暦での一年・十年の加算
001 002 003 004 005 006 007 008 009 010
011 012 013 014 015 016 017 018 019 020
021 022 023 024 025 026 027 028 029 030
031 032 033 034 035 036 037 038 039 040
041 042 043 044
|
Imports System
Imports System.Globalization
Module Globalization
Sub Main()
' システムの暦での2001年1月1日
Dim dtm As DateTime = New DateTime(2001, 1, 1)
' 和暦
Dim japanese As New JapaneseCalendar()
' ヘブライ暦
Dim hebrew As New HebrewCalendar()
' 回教暦
Dim hijri As New HijriCalendar()
' 西暦
Dim gregorian As New GregorianCalendar()
' システムの暦を表示
Console.WriteLine("Using {0}", CultureInfo.CurrentCulture.Calendar)
' 日付を表示
Console.WriteLine(dtm)
' 和暦での一年後、十年後
Console.WriteLine("Japanese: {0}, {1}", japanese.AddYears(dtm, 1), japanese.AddYears(dtm, 10))
' ヘブライ暦での一年後、十年後
Console.WriteLine("Hebrew: {0}, {1}", hebrew.AddYears(dtm, 1), hebrew.AddYears(dtm, 10))
' 回教暦での一年後、十年後
Console.WriteLine("Hijri: {0}, {1}", hijri.AddYears(dtm, 1), hijri.AddYears(dtm, 10))
' 西暦での一年後、十年後
Console.WriteLine("Gregorian: {0}, {1}", gregorian.AddYears(dtm, 1), gregorian.AddYears(dtm, 10))
End Sub
End Module
|
| 出力結果 |
Using System.Globalization.GregorianCalendar
2001/01/01 0:00:00
Japanese: 2002/01/01 0:00:00, 2011/01/01 0:00:00
Hebrew: 2001/12/21 0:00:00, 2010/12/13 0:00:00
Hijri: 2001/12/21 0:00:00, 2010/09/14 0:00:00
Gregorian: 2002/01/01 0:00:00, 2011/01/01 0:00:00
Press any key to continue
|
このように、ヘブライ暦や回教暦では一年の日数・一月の日数などがグレゴリオ暦とは異なるので、グレゴリオ暦での一年後・十年後とは異なった値になります。 また、和暦については年号だけが異なり、基本的にはグレゴリオ暦と同じなので日付のずれはありません。 この例ではAddYears()メソッドを使用しましたが、場合によっては月数や日数を加減算することもできます。
6.現在のスレッドのカルチャを変更する
今まではシステムのカルチャ設定に基づいたコーディングをしてきましたが、場合によっては現在のカルチャを変更したくなる場合があります。 そのような場合に対応するため、現在のスレッドのカルチャを変えることが可能になっています。 次のコードではカルチャを途中で「en-US (英語・米国)」に変えています。
現在のスレッドのカルチャを変更する
001 002 003 004 005 006 007 008 009 010
011 012 013 014 015 016 017 018 019 020
021 022 023 024 025 026 027 028 029 030
031 032 033 034
|
Option Strict On
Imports System
Imports System.Globalization
Imports System.Threading
Module Globalization
Sub Main()
Console.WriteLine("現在のカルチャ: {0}", CultureInfo.CurrentCulture.NativeName)
' 通貨の表示
Console.WriteLine("{0:C}", 123456.789)
' 日時の表示
Console.WriteLine("{0}", DateTime.Now)
' 現在のスレッドのカルチャを変更
Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US")
Console.WriteLine("現在のカルチャ: {0}", CultureInfo.CurrentCulture.NativeName)
' 通貨の表示
Console.WriteLine("{0:C}", 123456.789)
' 日時の表示
Console.WriteLine("{0}", DateTime.Now)
End Sub
End Module
|
| 出力結果 |
現在のカルチャ: 日本語 (日本)
\123,457
2003/12/14 2:40:53
現在のカルチャ: English (United States)
$123,456.79
12/14/2003 2:40:53 AM
Press any key to continue
|
実際にカルチャを変更しているコードが21行目です。 CurrentThread.CurrentCultureプロパティに新しいCultureInfoクラスのインスタンスを指定することでカルチャを変更しています。 さらに、これを利用して暦を変えることも可能です。
現在のスレッドのカルチャを変更する (暦を変更)
001 002 003 004 005 006 007 008 009 010
011 012 013 014 015 016 017 018 019 020
021 022 023 024 025 026
|
Imports System
Imports System.Globalization
Imports System.Threading
Module Globalization
Sub Main()
' 日時の表示
Console.WriteLine("{0}", DateTime.Now)
' 新しいカルチャのインスタンスを生成
Dim culture As New CultureInfo("ja-JP")
' カルチャに新しく和暦を指定
culture.DateTimeFormat.Calendar = New JapaneseCalendar()
' 現在のスレッドのカルチャを変更
Thread.CurrentThread.CurrentCulture = culture
' 日時の表示
Console.WriteLine("{0}", DateTime.Now)
End Sub
End Module
|
| 出力結果 |
2003/12/14 2:41:23
平成 15/12/14 2:41:23
Press any key to continue
|