Gewusst wie: Anzeigen von Datumsangaben in nicht gregorianischen Kalendern
Aktualisiert: November 2007
Der DateTime-Typ und der DateTimeOffset-Typ verwenden den gregorianischen Kalender als Standardkalender. Durch Aufrufen der ToString-Methode eines Datums- oder Uhrzeitwerts werden also die Zeichenfolgendarstellung dieses Datums und dieser Uhrzeit im gregorianischen Kalender angezeigt, auch wenn Datum und Uhrzeit unter Verwendung eines anderen Kalenders erstellt wurden. Dies wird im folgenden Beispiel veranschaulicht, in dem ein Datums- und Uhrzeitwert auf der Grundlage des persischen Kalenders auf zwei unterschiedliche Weisen erstellt wird. Beim Aufrufen der ToString-Methode werden diese Datums- und Uhrzeitwerte jedoch weiterhin im gregorianischen Kalender angezeigt. In diesem Beispiel werden zwei gängige, aber falsche Verfahrensweisen zur Anzeige des Datums in einem bestimmten Kalender behandelt.
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
Um das Datum in einem bestimmten Kalender anzuzeigen, können zwei unterschiedliche Verfahrensweisen verwendet werden. Die erste erfordert, dass der Kalender der Standardkalender für eine bestimmte Kultur ist. Die zweite kann mit einem beliebigen Kalender verwendet werden.
So zeigen Sie das Datum für den Standardkalender einer Kultur an
Instanziieren Sie ein von der Calendar-Klasse abgeleitetes Kalenderobjekt, das den zu verwendenden Kalender darstellt.
Instanziieren Sie ein CultureInfo-Objekt, das die Kultur darstellt, deren Formatierung zur Datumsanzeige verwendet wird.
Rufen Sie die Array.Exists<T>-Methode auf, um festzulegen, ob das Kalenderobjekt ein Member des von der CultureInfo.OptionalCalendars-Eigenschaft zurückgegebenen Arrays ist. Dadurch wird angegeben, dass der Kalender als Standardkalender für das CultureInfo-Objekt dienen kann. Falls es sich um keinen Member des Arrays handelt, befolgen Sie die Anweisungen im Abschnitt "So zeigen Sie das Datum in einem beliebigen Kalender an".
Weisen Sie das Kalenderobjekt der Calendar-Eigenschaft des von der CultureInfo.DateTimeFormat-Eigenschaft zurückgegebenen DateTimeFormatInfo-Objekts zu.
Hinweis: Die CultureInfo-Klasse verfügt auch über eine Calendar-Eigenschaft. Diese ist jedoch schreibgeschützt und konstant. Sie wird nicht in Anpassung an den neuen Standardkalender geändert, der der DateTimeFormatInfo.Calendar-Eigenschaft zugewiesen wird.
Rufen Sie entweder die ToString-Methode oder die ToString-Methode auf, und übergeben Sie ihr das CultureInfo-Objekt, dessen Standardkalender im vorherigen Schritt geändert wurde.
So zeigen Sie das Datum in einem beliebigen Kalender an
Instanziieren Sie ein von der Calendar-Klasse abgeleitetes Kalenderobjekt, das den zu verwendenden Kalender darstellt.
Legen Sie fest, welche Datums- und Uhrzeitelemente in der Zeichenfolgendarstellung des Datums- und Uhrzeitwerts angezeigt werden sollen.
Rufen Sie für jedes Datums- und Uhrzeitelement, das Sie anzeigen möchten, die Get-Methode des Kalenderobjekts auf. Die folgenden Methoden stehen zur Verfügung:
GetYear zur Anzeige des Jahres im entsprechenden Kalender.
GetMonth zur Anzeige des Monats im entsprechenden Kalender.
GetDayOfMonth zur Anzeige des Tages des Monats im entsprechenden Kalender.
GetHour zur Anzeige der Stunde des Tages im entsprechenden Kalender.
GetMinute zur Anzeige der Minuten in der Stunde im entsprechenden Kalender.
GetSecond zur Anzeige der Sekunden in der Minute im entsprechenden Kalender.
GetMilliseconds zur Anzeige der Millisekunden in der Sekunde im entsprechenden Kalender.
Beispiel
Im Beispiel wird ein Datum unter Verwendung zwei verschiedener Kalender angezeigt. Sie sehen das Datum, nachdem der Hijri-Kalender als Standardkalender für die Kultur ar-JO festgelegt wurde, sowie das Datum auf Grundlage des persischen Kalenders, der von der Kultur fa-IR nicht als optionaler Kalender unterstützt wird.
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
Jedes CultureInfo-Objekt kann einen oder mehrere Kalender unterstützen, die von der OptionalCalendars-Eigenschaft angegeben werden. Einer dieser Kalender wird als Standardkalender der Kultur festgelegt und von der schreibgeschützten CultureInfo.Calendar-Eigenschaft zurückgegeben. Ein anderer optionaler Kalender kann als Standardkalender festgelegt werden, indem ein Calendar-Objekt zugewiesen wird, das diesen Kalender für die DateTimeFormatInfo.Calendar-Eigenschaft darstellt, die von der CultureInfo.DateTimeFormat-Eigenschaft zurückgegeben wird. Einige Kalender, wie der durch die PersianCalendar-Klasse dargestellte persische Kalender, können jedoch nicht als optionale Kalender für beliebige Kulturen verwendet werden.
Im Beispiel wird die wiederverwendbare Kalender-Dienstprogrammklasse CalendarUtility definiert, die viele der Details behandelt, die beim Erstellen der Zeichenfolgendarstellung eines Datums nach einem bestimmten Kalender eine Rolle spielen. Die CalendarUtility-Klasse verfügt über die folgenden Member:
Ein parametrisierter Konstruktor, dessen einzelner Parameter einem Calendar-Objekt entspricht, in dem ein Datum dargestellt werden soll. Dieser wird einem privaten Feld der Klasse zugewiesen.
CalendarExists, eine private Methode, die einen booleschen Wert zurückgibt, der angibt, ob der vom CalendarUtility-Objekt dargestellte Kalender vom CultureInfo-Objekt unterstützt wird, das als Parameter an die Methode übergeben wird. Die Methode umschließt einen Aufruf der Array.Exists<T>-Methode, an die sie das CultureInfo.OptionalCalendars-Array übergibt.
HasSameName, eine private Methode, die dem Predicate<T>-Delegaten zugewiesen wird, der als Parameter an die Array.Exists<T>-Methode übergeben wird. Jeder Member des Arrays wird so lange an die Methode übergeben, bis die Methode true zurückgibt. Durch die Methode wird ermittelt, ob der Name eines optionalen Kalenders dem Kalendernamen entspricht, der vom CalendarUtility-Objekt dargestellt wird.
DisplayDate, eine überladene öffentliche Methode, an die zwei Parameter übergeben werden: entweder ein DateTime-Wert oder ein DateTimeOffset-Wert, der in dem vom CalendarUtility-Objekt dargestellten Kalender ausgedrückt werden soll, sowie die Kultur, deren Formatierungsregeln verwendet werden sollen. Das Verhalten bei der Rückgabe der Zeichenfolgendarstellung eines Datums hängt davon ab, ob der Zielkalender von der Kultur unterstützt wird, deren Formatierungsregeln verwendet werden sollen.
Unabhängig von dem Kalender, der zum Erstellen eines DateTime-Werts oder eines DateTimeOffset-Werts verwendet wird, wird der Wert in diesem Beispiel normalerweise als gregorianisches Datum ausgedrückt. Dies liegt daran, dass der DateTime-Typ und der DateTimeOffset-Typ keine Kalenderinformationen beibehalten. Intern entsprechen sie der Anzahl der Teilstriche, die seit dem 01. Januar 0001, Mitternacht, verstrichen sind. Die Darstellung dieser Zahl hängt vom Kalender ab. In den meisten Kulturen ist der Standardkalender der gregorianische Kalender.
Kompilieren des Codes
Für dieses Beispiel ist ein Verweis auf System.Core.dll erforderlich.
Kompilieren Sie den Code über csc.exe oder vb.exe in der Befehlszeile. Um den Code in Visual Studio zu kompilieren, fügen Sie ihn in eine Projektvorlage für eine Konsolenanwendung ein.