Vorgehensweise: Anzeigen von Datumsangaben in nicht gregorianischen Kalendern

Die Typen DateTime und DateTimeOffset verwenden den gregorianischen Kalender als Standardkalender. Das bedeutet, dass ein Aufruf der ToString-Methode eines Datums- und Uhrzeitwerts die Zeichenfolgendarstellung dieses Datums und dieser Uhrzeit im gregorianischen Kalender anzeigt, selbst wenn dieses Datum und diese Uhrzeit in einem anderen Kalender erstellt wurden. Dies wird im folgenden Beispiel veranschaulicht. Hierbei werden zwei verschiedene Möglichkeiten verwendet, um einen Datums- und Uhrzeitwert mit dem persischen Kalender zu erstellen. Beim Aufruf der ToString-Methode werden diese Datums- und Uhrzeitwerte aber weiterhin im gregorianischen Kalender angezeigt. Dieses Beispiel zeigt zwei häufig verwendete, aber falsche Verfahren zum Anzeigen des Datums in einem bestimmten Kalender.

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
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

Zum Anzeigen des Datums in einem bestimmten Kalender können zwei verschiedene Verfahren verwendet werden. Für das erste Verfahren muss der Kalender der Standardkalender für eine bestimmte Kultur sein. Das zweite kann mit jedem beliebigen Kalender verwendet werden.

Anzeigen des Datums für den Standardkalender einer Kultur

  1. Instanziieren Sie ein aus der Calendar-Klasse abgeleitetes Kalenderobjekt, das den zu verwendenden Kalender darstellt.

  2. Instanziieren Sie ein CultureInfo-Objekt, das die Kultur darstellt, deren Formatierung für die Datumsanzeige verwendet wird.

  3. Rufen Sie die Array.Exists-Methode auf, um zu ermitteln, ob das Kalenderobjekt ein Member des von der CultureInfo.OptionalCalendars-Eigenschaft zurückgegebenen Arrays ist. Wenn dies der Fall ist, kann der Kalender als Standardkalender für das CultureInfo-Objekt dienen. Wenn das Objekt kein Member des Arrays ist, befolgen Sie die Anweisungen im Abschnitt „Anzeigen des Datums in einem beliebigen Kalender“.

  4. Weisen Sie das Kalenderobjekt zu, um die von der CultureInfo.DateTimeFormat-Eigenschaft zurückgegebene Calendar-Eigenschaft des DateTimeFormatInfo-Objekts festzulegen.

    Hinweis

    Die CultureInfo-Klasse verfügt auch über eine Calendar-Eigenschaft. Diese ist jedoch schreibgeschützt und konstant. Sie ändert sich nicht, um den neuen, der DateTimeFormatInfo.Calendar-Eigenschaft zugewiesenen Standardkalender widerzuspiegeln.

  5. Rufen Sie entweder die ToString- oder ToString-Methode auf, und übergeben Sie ihr das CultureInfo-Objekt, dessen Standardkalender im vorherigen Schritt geändert wurde.

Anzeigen des Datums in einem beliebigen Kalender

  1. Instanziieren Sie ein aus der Calendar-Klasse abgeleitetes Kalenderobjekt, das den zu verwendenden Kalender darstellt.

  2. Bestimmen Sie, welche Datums- und Uhrzeitelemente in der Zeichenfolgendarstellung des Datums- und Uhrzeitwerts angezeigt werden sollen.

  3. Rufen Sie für jedes Datums- und Uhrzeitelement, das Sie anzeigen möchten, die Get... -Methode. Die folgenden Methoden sind verfügbar:

    • GetYear zum Anzeigen des Jahrs im entsprechenden Kalender

    • GetMonth zum Anzeigen des Monats im entsprechenden Kalender

    • GetDayOfMonth zum Anzeigen der Zahl, die dem Tag des Monats im entsprechenden Kalender entspricht

    • GetHour zum Anzeigen der Stunde des Tages im entsprechenden Kalender

    • GetMinute zum Anzeigen der Minuten in der Stunde im entsprechenden Kalender

    • GetSecond zum Anzeigen der Sekunden in der Minute im entsprechenden Kalender

    • GetMilliseconds zum Anzeigen der Millisekunden in der Sekunde im entsprechenden Kalender.

Beispiel

Das Beispiel zeigt ein Datum mithilfe von zwei verschiedenen Kalendern an. Es zeigt das Datum an, nachdem der Hijri-Kalender als Standardkalender für die Kultur „ar-JO“ definiert wurde, und es zeigt das Datum unter Verwendung des persischen Kalenders an, der nicht als optionaler Kalender von der fa-IR-Kultur unterstützt wird.

using System;
using System.Globalization;

public class CalendarDates
{
   public static void Main()
   {
      HijriCalendar hijriCal = new HijriCalendar();
      CalendarUtility hijriUtil = new CalendarUtility(hijriCal);
      DateTime dateValue1 = new DateTime(1429, 6, 29, hijriCal);
      DateTimeOffset dateValue2 = new DateTimeOffset(dateValue1,
                                  TimeZoneInfo.Local.GetUtcOffset(dateValue1));
      CultureInfo jc = CultureInfo.CreateSpecificCulture("ar-JO");

      // Display the date using the Gregorian calendar.
      Console.WriteLine("Using the system default culture: {0}",
                        dateValue1.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}",
                        dateValue1.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(dateValue1, jc));
      // Display a DateTimeOffset value.
      Console.WriteLine(hijriUtil.DisplayDate(dateValue2, 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}",
                        dateValue1.ToString("d", ic));
      // Display a Date value.
      Console.WriteLine(persianUtil.DisplayDate(dateValue1, ic));
      // Display a DateTimeOffset value.
      Console.WriteLine(persianUtil.DisplayDate(dateValue2, 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
Imports System.Globalization

Public Class CalendarDates
    Public Shared Sub Main()
        Dim hijriCal As New HijriCalendar()
        Dim hijriUtil As New CalendarUtility(hijriCal)
        Dim dateValue1 As Date = New Date(1429, 6, 29, hijriCal)
        Dim dateValue2 As DateTimeOffset = New DateTimeOffset(dateValue1, _
                                           TimeZoneInfo.Local.GetUtcOffset(dateValue1))
        Dim jc As CultureInfo = CultureInfo.CreateSpecificCulture("ar-JO")

        ' Display the date using the Gregorian calendar.
        Console.WriteLine("Using the system default culture: {0}", _
                          dateValue1.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}", _
                          dateValue1.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(dateValue1, jc))
        ' Display a DateTimeOffset value.
        Console.WriteLine(hijriUtil.DisplayDate(dateValue2, 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}", _
                          dateValue1.ToString("d", ic))
        ' Display a Date value.
        Console.WriteLine(persianUtil.DisplayDate(dateValue1, ic))
        ' Display a DateTimeOffset value.
        Console.WriteLine(persianUtil.DisplayDate(dateValue2, 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

Jedes CultureInfo-Objekt kann mindestens einen Kalender unterstützen, der von der OptionalCalendars-Eigenschaft angegeben wird. Einer dieser Kalender ist als Standardkalender der Kultur festgelegt und wird von der schreibgeschützten CultureInfo.Calendar-Eigenschaft zurückgegeben. Ein anderer der optionalen Kalender kann als Standard festgelegt werden, indem ein Calendar-Objekt, das diesen Kalender darstellt, der von der CultureInfo.DateTimeFormat-Eigenschaft zurückgegebenen DateTimeFormatInfo.Calendar-Eigenschaft zugewiesen wird. Einige Kalender jedoch, wie der von der PersianCalendar-Klasse dargestellte persische Kalender, dienen nicht als optionale Kalender für irgendeine Kultur.

Das Beispiel definiert eine wiederverwendbare Kalenderhilfsprogrammklasse, CalendarUtility, um viele der Details beim Generieren der Zeichenfolgendarstellung eines Datums mithilfe eines bestimmten Kalenders zu verarbeiten. Die CalendarUtility-Klasse verfügt über die folgenden Member:

  • Einen parametrisierten Konstruktor, dessen einziger Parameter ein Calendar-Objekt ist, in dem ein Datum dargestellt werden soll. Dieser wird einem privaten Klassenfeld zugewiesen.

  • CalendarExists, eine private Methode, die einen booleschen Wert zurückgibt, um anzugeben, ob der durch das CalendarUtility-Objekt dargestellte Kalender von dem CultureInfo-Objekt unterstützt wird, das als Parameter an die Methode übergeben wird. Die Methode umschließt einen Aufruf der Array.Exists-Methode, an die das CultureInfo.OptionalCalendars-Array übergeben wird.

  • HasSameName, eine dem Predicate<T>-Delegaten zugewiesene private Methode, die als Parameter an die Array.Exists-Methode übergeben wird. Jeder Member des Arrays wird an die Methode übergeben, bis die Methode true zurückgibt. Die Methode bestimmt, ob der Name eines optionalen Kalenders dem Kalender entspricht, der durch das CalendarUtility-Objekt dargestellt wird.

  • DisplayDate, eine überladene öffentliche Methode, an die zwei Parameter übergeben werden: erstens entweder ein DateTime- oder ein DateTimeOffset-Wert, der in dem durch das CalendarUtility-Objekt dargestellten Kalender ausgedrückt werden soll. Zweitens wird die Kultur übergeben, deren Formatierungsregeln verwendet werden sollen. Das Verhalten bei der Rückgabe der Zeichenfolgendarstellung eines Datums richtet sich danach, ob der Zielkalender von der Kultur unterstützt wird, deren Formatierungsregeln verwendet werden sollen.

Unabhängig von dem Kalender, der in diesem Beispiel zum Erstellen eines DateTime- oder DateTimeOffset-Werts verwendet wird, wird dieser Wert üblicherweise als gregorianisches Datum ausgedrückt. Dies liegt daran, dass die Typen DateTime und DateTimeOffset keine Kalenderinformationen beibehalten. Intern werden sie als Anzahl von Zeiteinheiten (Ticks) dargestellt, die seit Mitternacht des 1. Januar 0001 verstrichen sind. Die Interpretation dieser Zahl hängt vom Kalender ab. In den meisten Kulturen ist der Gregorianische Kalender der Standardkalender.