Udostępnij za pośrednictwem


Porady: wyświetlanie dat w kalendarzach innych niż gregoriański

Typy DateTime i DateTimeOffset używają kalendarza gregoriańskiego jako kalendarza domyślnego. Oznacza to, że wywołanie metody wartości ToString daty i godziny wyświetla ciąg reprezentujący tę datę i godzinę w kalendarzu gregoriańskim, nawet jeśli ta data i godzina została utworzona przy użyciu innego kalendarza. Przedstawiono to w poniższym przykładzie, który używa dwóch różnych sposobów tworzenia wartości daty i godziny z kalendarzem perskim, ale nadal wyświetla te wartości daty i godziny w kalendarzu gregoriańskim, gdy wywołuje metodę ToString . W tym przykładzie przedstawiono dwie powszechnie używane, ale niepoprawne techniki wyświetlania daty w określonym kalendarzu.

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

Dwie różne techniki mogą służyć do wyświetlania daty w określonym kalendarzu. Pierwszy wymaga, aby kalendarz był domyślnym kalendarzem dla określonej kultury. Drugi może być używany z dowolnym kalendarzem.

Aby wyświetlić datę domyślnego kalendarza kultury

  1. Utwórz wystąpienie obiektu kalendarza pochodzącego Calendar z klasy reprezentującej kalendarz do użycia.

  2. Utwórz wystąpienie obiektu reprezentującego kulturę CultureInfo , której formatowanie będzie używane do wyświetlania daty.

  3. Wywołaj metodę , Array.Exists aby określić, czy obiekt kalendarza jest elementem członkowskim tablicy zwracanej przez CultureInfo.OptionalCalendars właściwość . Oznacza to, że kalendarz może służyć jako domyślny kalendarz dla CultureInfo obiektu. Jeśli nie jest członkiem tablicy, postępuj zgodnie z instrukcjami w sekcji "Aby wyświetlić datę w dowolnym kalendarzu".

  4. Przypisz obiekt kalendarza do Calendar właściwości DateTimeFormatInfo obiektu zwróconego CultureInfo.DateTimeFormat przez właściwość .

    Uwaga

    Klasa CultureInfo ma Calendar również właściwość . Jednak jest to tylko do odczytu i stała; nie zmienia się tak, aby odzwierciedlał nowy kalendarz domyślny przypisany do DateTimeFormatInfo.Calendar właściwości.

  5. Wywołaj metodę ToStringToString lub i przekaż go CultureInfo do obiektu, którego kalendarz domyślny został zmodyfikowany w poprzednim kroku.

Aby wyświetlić datę w dowolnym kalendarzu

  1. Utwórz wystąpienie obiektu kalendarza pochodzącego Calendar z klasy reprezentującej kalendarz do użycia.

  2. Określ, które elementy daty i godziny powinny być wyświetlane w ciągu reprezentującym wartość daty i godziny.

  3. Dla każdego elementu daty i godziny, który chcesz wyświetlić, wywołaj obiekt Getkalendarza ... Metoda. Dostępne są następujące metody:

    • GetYear, aby wyświetlić rok w odpowiednim kalendarzu.

    • GetMonth, aby wyświetlić miesiąc w odpowiednim kalendarzu.

    • GetDayOfMonth, aby wyświetlić liczbę dni miesiąca w odpowiednim kalendarzu.

    • GetHour, aby wyświetlić godzinę dnia w odpowiednim kalendarzu.

    • GetMinute, aby wyświetlić minuty w godzinie w odpowiednim kalendarzu.

    • GetSecond, aby wyświetlić sekundy w minutie w odpowiednim kalendarzu.

    • GetMilliseconds, aby wyświetlić milisekundy w drugim w odpowiednim kalendarzu.

Przykład

W przykładzie jest wyświetlana data używająca dwóch różnych kalendarzy. Wyświetla datę po zdefiniowaniu kalendarza Hidżry jako kalendarza domyślnego dla kultury ar-JO i wyświetla datę przy użyciu kalendarza perskiego, który nie jest obsługiwany jako opcjonalny kalendarz przez kulturę fa-IR.

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

Każdy CultureInfo obiekt może obsługiwać co najmniej jeden kalendarz, który jest wskazywany OptionalCalendars przez właściwość . Jeden z nich jest wyznaczony jako domyślny kalendarz kultury i jest zwracany przez właściwość tylko do CultureInfo.Calendar odczytu. Innym z opcjonalnych kalendarzy można wyznaczyć jako domyślne, przypisując Calendar obiekt reprezentujący ten kalendarz do DateTimeFormatInfo.Calendar właściwości zwróconej CultureInfo.DateTimeFormat przez właściwość . Jednak niektóre kalendarze, takie jak kalendarz perski reprezentowany przez klasę PersianCalendar , nie służą jako opcjonalne kalendarze dla żadnej kultury.

W przykładzie zdefiniowano klasę narzędzia kalendarza wielokrotnego użytku , CalendarUtilityw celu obsługi wielu szczegółów generowania reprezentacji ciągu daty przy użyciu określonego kalendarza. Klasa CalendarUtility ma następujące elementy członkowskie:

  • Konstruktor sparametryzowany, którego pojedynczy parametr jest obiektem Calendar , w którym ma być reprezentowana data. Jest to przypisane do pola prywatnego klasy.

  • CalendarExists, metoda prywatna zwracająca wartość logiczną wskazującą, czy kalendarz reprezentowany przez obiekt jest obsługiwany przez CalendarUtilityCultureInfo obiekt przekazywany do metody jako parametr. Metoda opakowuje wywołanie Array.Exists metody , do której przekazuje tablicę CultureInfo.OptionalCalendars .

  • HasSameName, metoda prywatna przypisana do Predicate<T> delegata, który jest przekazywany jako parametr do Array.Exists metody . Każdy element członkowski tablicy jest przekazywany do metody, dopóki metoda nie zwróci truemetody . Metoda określa, czy nazwa opcjonalnego kalendarza jest taka sama jak kalendarz reprezentowany przez CalendarUtility obiekt.

  • DisplayDate, przeciążona metoda publiczna, która jest przekazywana dwa parametry: DateTime wartość lub DateTimeOffset do wyrażenia w kalendarzu CalendarUtility reprezentowanym przez obiekt; oraz kultury, której reguły formatowania mają być używane. Jego zachowanie w zwracaniu reprezentacji ciągu daty zależy od tego, czy kalendarz docelowy jest obsługiwany przez kulturę, której reguły formatowania mają być używane.

Niezależnie od kalendarza użytego do utworzenia DateTime wartości lub DateTimeOffset w tym przykładzie ta wartość jest zwykle wyrażona jako data gregoriański. Dzieje się tak, ponieważ DateTime typy i DateTimeOffset nie zachowują żadnych informacji kalendarza. Wewnętrznie są one reprezentowane jako liczba kleszczy, które upłynęły od północy 1 stycznia 0001 roku. Interpretacja tej liczby zależy od kalendarza. W przypadku większości kultur domyślnym kalendarzem jest kalendarz gregoriański.