方法 : グレゴリオ暦以外の暦の日付を表示する
更新 : 2007 年 11 月
DateTime 型と DateTimeOffset 型は、既定の暦としてグレゴリオ暦を使用します。つまり、日付および時刻の値の ToString メソッドを呼び出すと、その日付および時刻が別の暦を使って作成された場合でも、グレゴリオ暦でその日付および時刻を表した文字列表現が表示されます。この動作を次のコード例に示します。ここでは、2 つの異なる方法でペルシャ暦の日付および時刻の値を作成しますが、ToString メソッドを呼び出すときにはグレゴリオ暦で日付および時刻の値を表示します。この例の 2 つの技法はよく使用されますが、特定の暦で日付を表示する方法としては適切ではありません。
Dim persianCal As New PersianCalendar()
Dim persianDate As Date = persianCal.ToDateTime(1387, 3, 18, _
12, 0, 0, 0)
Console.WriteLine(persianDate.ToString())
persianDate = New DateTime(1387, 3, 18, persianCal)
Console.WriteLine(persianDate.ToString())
' The example displays the following output to the console:
' 6/7/2008 12:00:00 PM
' 6/7/2008 12:00:00 AM
PersianCalendar persianCal = new PersianCalendar();
DateTime persianDate = persianCal.ToDateTime(1387, 3, 18, 12, 0, 0, 0);
Console.WriteLine(persianDate.ToString());
persianDate = new DateTime(1387, 3, 18, persianCal);
Console.WriteLine(persianDate.ToString());
// The example displays the following output to the console:
// 6/7/2008 12:00:00 PM
// 6/7/2008 12:00:00 AM
特定の暦で日付を表示するために 2 つの異なる技法を使用できます。最初の方法では、暦は特定のカルチャの既定の暦である必要があります。2 番目の方法は、任意の暦で使用できます。
カルチャの既定の暦で日付を表示するには
使用する暦 (カレンダー) を表す、Calendar クラスから派生したカレンダー オブジェクトをインスタンス化します。
日付の表示に使われる書式設定が属するカルチャを表す CultureInfo オブジェクトをインスタンス化します。
Array.Exists<T> メソッドを呼び出すことにより、カレンダー オブジェクトが CultureInfo.OptionalCalendars プロパティによって返される配列のメンバかどうかを判別します。これは、そのカレンダー (暦) を CultureInfo オブジェクトの既定の暦に指定できることを示します。配列のメンバでない場合には、「任意の暦で日付を表示するには」の説明に従ってください。
カレンダー オブジェクトを、CultureInfo.DateTimeFormat プロパティによって返される DateTimeFormatInfo オブジェクトの Calendar プロパティに割り当てます。
メモ : CultureInfo クラスには、Calendar プロパティもあります。ただし、これは読み取り専用の定数であるため、DateTimeFormatInfo.Calendar プロパティに割り当てられた新しい既定の暦を表すようには変更されません。
ToString メソッドまたは ToString メソッドを呼び出して、前の手順で既定の暦が変更された CultureInfo オブジェクトをそれに渡します。
任意の暦で日付を表示するには
使用する暦 (カレンダー) を表す、Calendar クラスから派生したカレンダー オブジェクトをインスタンス化します。
日付および時刻の値の文字列表現にどの日付および時刻要素を表示させるかを決定します。
表示させるそれぞれの日付および時刻要素ごとに、カレンダー オブジェクトの Get… メソッドを呼び出します。次のメソッドを使用できます。
GetYear は、適切な暦の年を表示します。
GetMonth は、適切な暦の月を表示します。
GetDayOfMonth は、適切な暦の月の日付を表示します。
GetHour は、適切な暦の日付の時間を表示します。
GetMinute は、適切な暦の時刻の分を表示します。
GetSecond は、適切な暦の時刻の秒を表示します。
GetMilliseconds は、適切な暦の時刻のミリ秒を表示します。
使用例
この例では、2 つの異なる暦を使って日付を表示します。ar-JO カルチャの既定の暦としてヒジュラ暦を定義した後、日付を表示します。さらに、fa-IR カルチャのオプションの暦としてサポートされないペルシャ暦を使って日付を表示します。
Imports System.Globalization
Public Class CalendarDates
Public Shared Sub Main()
Dim hijriCal As New HijriCalendar()
Dim hijriUtil As New CalendarUtility(hijriCal)
Dim hijriDate1 As Date = New Date(1429, 6, 29, hijriCal)
Dim hijriDate2 As DateTimeOffset = New DateTimeOffset(hijriDate1, _
TimeZoneInfo.Local.GetUtcOffset(hijriDate1))
Dim jc As CultureInfo = CultureInfo.CreateSpecificCulture("ar-JO")
' Display the date using the Gregorian calendar.
Console.WriteLine("Using the system default culture: {0}", _
hijriDate1.ToString("d"))
' Display the date using the ar-JO culture's original default calendar.
Console.WriteLine("Using the ar-JO culture's original default calendar: {0}", _
hijriDate1.ToString("d", jc))
' Display the date using the Hijri calendar.
Console.WriteLine("Using the ar-JO culture with Hijri as the default calendar:")
' Display a Date value.
Console.WriteLine(hijriUtil.DisplayDate(hijriDate1, jc))
' Display a DateTimeOffset value.
Console.WriteLine(hijriUtil.DisplayDate(hijriDate2, jc))
Console.WriteLine()
Dim persianCal As New PersianCalendar()
Dim persianUtil As New CalendarUtility(persianCal)
Dim ic As CultureInfo = CultureInfo.CreateSpecificCulture("fa-IR")
' Display the date using the ir-FA culture's default calendar.
Console.WriteLine("Using the ir-FA culture's default calendar: {0}", _
hijriDate1.ToString("d", ic))
' Display a Date value.
Console.WriteLine(persianUtil.DisplayDate(hijriDate1, ic))
' Display a DateTimeOffset value.
Console.WriteLine(persianUtil.DisplayDate(hijriDate2, ic))
End Sub
End Class
Public Class CalendarUtility
Private thisCalendar As Calendar
Private targetCulture As CultureInfo
Public Sub New(cal As Calendar)
Me.thisCalendar = cal
End Sub
Private Function CalendarExists(culture As CultureInfo) As Boolean
Me.targetCulture = culture
Return Array.Exists(Me.targetCulture.OptionalCalendars, _
AddressOf Me.HasSameName)
End Function
Private Function HasSameName(cal As Calendar) As Boolean
If cal.ToString() = thisCalendar.ToString() Then
Return True
Else
Return False
End If
End Function
Public Function DisplayDate(dateToDisplay As Date, _
culture As CultureInfo) As String
Dim displayOffsetDate As DateTimeOffset = dateToDisplay
Return DisplayDate(displayOffsetDate, culture)
End Function
Public Function DisplayDate(dateToDisplay As DateTimeOffset, _
culture As CultureInfo) As String
Dim specifier As String = "yyyy/MM/dd"
If Me.CalendarExists(culture) Then
Console.WriteLine("Displaying date in supported {0} calendar...", _
thisCalendar.GetType().Name)
culture.DateTimeFormat.Calendar = Me.thisCalendar
Return dateToDisplay.ToString(specifier, culture)
Else
Console.WriteLine("Displaying date in unsupported {0} calendar...", _
thisCalendar.GetType().Name)
Dim separator As String = targetCulture.DateTimeFormat.DateSeparator
Return thisCalendar.GetYear(dateToDisplay.DateTime).ToString("0000") & separator & _
thisCalendar.GetMonth(dateToDisplay.DateTime).ToString("00") & separator & _
thisCalendar.GetDayOfMonth(dateToDisplay.DateTime).ToString("00")
End If
End Function
End Class
' The example displays the following output to the console:
' Using the system default culture: 7/3/2008
' Using the ar-JO culture's original default calendar: 03/07/2008
' Using the ar-JO culture with Hijri as the default calendar:
' Displaying date in supported HijriCalendar calendar...
' 1429/06/29
' Displaying date in supported HijriCalendar calendar...
' 1429/06/29
'
' Using the ir-FA culture's default calendar: 7/3/2008
' Displaying date in unsupported PersianCalendar calendar...
' 1387/04/13
' Displaying date in unsupported PersianCalendar calendar...
' 1387/04/13
using System;
using System.Globalization;
public class CalendarDates
{
public static void Main()
{
HijriCalendar hijriCal = new HijriCalendar();
CalendarUtility hijriUtil = new CalendarUtility(hijriCal);
DateTime hijriDate1 = new DateTime(1429, 6, 29, hijriCal);
DateTimeOffset hijriDate2 = new DateTimeOffset(hijriDate1,
TimeZoneInfo.Local.GetUtcOffset(hijriDate1));
CultureInfo jc = CultureInfo.CreateSpecificCulture("ar-JO");
// Display the date using the Gregorian calendar.
Console.WriteLine("Using the system default culture: {0}",
hijriDate1.ToString("d"));
// Display the date using the ar-JO culture's original default calendar.
Console.WriteLine("Using the ar-JO culture's original default calendar: {0}",
hijriDate1.ToString("d", jc));
// Display the date using the Hijri calendar.
Console.WriteLine("Using the ar-JO culture with Hijri as the default calendar:");
// Display a Date value.
Console.WriteLine(hijriUtil.DisplayDate(hijriDate1, jc));
// Display a DateTimeOffset value.
Console.WriteLine(hijriUtil.DisplayDate(hijriDate2, jc));
Console.WriteLine();
PersianCalendar persianCal = new PersianCalendar();
CalendarUtility persianUtil = new CalendarUtility(persianCal);
CultureInfo ic = CultureInfo.CreateSpecificCulture("fa-IR");
// Display the date using the ir-FA culture's default calendar.
Console.WriteLine("Using the ir-FA culture's default calendar: {0}",
hijriDate1.ToString("d", ic));
// Display a Date value.
Console.WriteLine(persianUtil.DisplayDate(hijriDate1, ic));
// Display a DateTimeOffset value.
Console.WriteLine(persianUtil.DisplayDate(hijriDate2, ic));
}
}
public class CalendarUtility
{
private Calendar thisCalendar;
private CultureInfo targetCulture;
public CalendarUtility(Calendar cal)
{
this.thisCalendar = cal;
}
private bool CalendarExists(CultureInfo culture)
{
this.targetCulture = culture;
return Array.Exists(this.targetCulture.OptionalCalendars,
this.HasSameName);
}
private bool HasSameName(Calendar cal)
{
if (cal.ToString() == thisCalendar.ToString())
return true;
else
return false;
}
public string DisplayDate(DateTime dateToDisplay, CultureInfo culture)
{
DateTimeOffset displayOffsetDate = dateToDisplay;
return DisplayDate(displayOffsetDate, culture);
}
public string DisplayDate(DateTimeOffset dateToDisplay,
CultureInfo culture)
{
string specifier = "yyyy/MM/dd";
if (this.CalendarExists(culture))
{
Console.WriteLine("Displaying date in supported {0} calendar...",
this.thisCalendar.GetType().Name);
culture.DateTimeFormat.Calendar = this.thisCalendar;
return dateToDisplay.ToString(specifier, culture);
}
else
{
Console.WriteLine("Displaying date in unsupported {0} calendar...",
thisCalendar.GetType().Name);
string separator = targetCulture.DateTimeFormat.DateSeparator;
return thisCalendar.GetYear(dateToDisplay.DateTime).ToString("0000") +
separator +
thisCalendar.GetMonth(dateToDisplay.DateTime).ToString("00") +
separator +
thisCalendar.GetDayOfMonth(dateToDisplay.DateTime).ToString("00");
}
}
}
// The example displays the following output to the console:
// Using the system default culture: 7/3/2008
// Using the ar-JO culture's original default calendar: 03/07/2008
// Using the ar-JO culture with Hijri as the default calendar:
// Displaying date in supported HijriCalendar calendar...
// 1429/06/29
// Displaying date in supported HijriCalendar calendar...
// 1429/06/29
//
// Using the ir-FA culture's default calendar: 7/3/2008
// Displaying date in unsupported PersianCalendar calendar...
// 1387/04/13
// Displaying date in unsupported PersianCalendar calendar...
// 1387/04/13
それぞれの CultureInfo オブジェクトは、OptionalCalendars プロパティによって示される暦を 1 つ以上サポートすることができます。このうち 1 つがカルチャの既定の暦として指定され、読み取り専用の CultureInfo.Calendar プロパティによって返されます。オプションの暦の 1 つを既定として指定するには、その暦を表す Calendar オブジェクトを、CultureInfo.DateTimeFormat プロパティによって返される DateTimeFormatInfo.Calendar プロパティに割り当てます。ただし、(PersianCalendar クラスによって表されるペルシャ暦のような) いくつかの暦は、どのカルチャのオプションの暦としても機能しません。
この例では、特定の暦を使って日付の文字列表現を生成する際の多くの詳細な処理を行うために、再利用可能なカレンダー ユーティリティ クラス CalendarUtility を定義します。CalendarUtility クラスには、次のメンバがあります。
パラメータ化されたコンストラクタ。その単一のパラメータは、日付を表す際に使用される Calendar オブジェクトです。クラスのプライベート フィールドにこれが割り当てられます。
プライベート メソッド CalendarExists。これは、CalendarUtility オブジェクトによって表される暦が、パラメータとしてメソッドに渡される CultureInfo オブジェクトでサポートされるかどうかを示すブール値を返します。
プライベート メソッド HasSameName。これは、Array.Exists<T> メソッドにパラメータとして渡される Predicate<T> デリゲートに割り当てられます。メソッドが true を返すまで、配列の各メンバがメソッドに渡されます。このメソッドは、オプションの暦の名前が、CalendarUtility オブジェクトによって表される暦と同じかどうかを判断します。
オーバーロードされたパブリック メソッド DisplayDate。これに渡されるパラメータは、CalendarUtility オブジェクトによって表される暦で表示する DateTime または DateTimeOffset 値と、使用する書式指定規則が属するカルチャの 2 つです。日付の文字列表現を返す際の動作は、使用する書式指定規則が属するカルチャにおいて、対象となる暦がサポートされるかどうかに依存します。
この例の DateTime または DateTimeOffset 値を作成するのにどんな暦が使われたかにかかわらず、この値は通常、グレゴリオ暦の日付で表現されます。これは、暦の情報が DateTime 型と DateTimeOffset 型に保持されないためです。内部的には、これは 0001 年 1 月 1 日の真夜中から数えたタイマ刻みの回数として表されます。この回数の解釈は、暦によって異なります。ほとんどのカルチャでは、既定の暦はグレゴリオ暦です。
コードのコンパイル方法
この例では System.Core.dll を参照する必要があります。
コマンド ラインで csc.exe または vb.exe を使用してコードをコンパイルします。Visual Studio でコードをコンパイルするには、コンソール アプリケーション プロジェクト テンプレートの中にコードを配置します。