Postupy: Zobrazování dat v jiném než gregoriánském kalendáři

DateTimeOffset Typy DateTime používají gregoriánský kalendář jako výchozí kalendář. To znamená, že volání metody hodnoty ToString data a času zobrazuje řetězcové vyjádření tohoto data a času v gregoriánském kalendáři, i když bylo toto datum a čas vytvořeno pomocí jiného kalendáře. To je znázorněno v následujícím příkladu, který používá dva různé způsoby vytvoření hodnoty data a času s perským kalendářem, ale přesto tyto hodnoty data a času zobrazí v gregoriánském kalendáři, když volá metodu ToString . Tento příklad odráží dva běžně používané, ale nesprávné techniky zobrazení data v konkrétním kalendáři.

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

K zobrazení data v konkrétním kalendáři lze použít dvě různé techniky. První vyžaduje, aby kalendář byl výchozím kalendářem pro určitou jazykovou verzi. Druhý lze použít s libovolným kalendářem.

Zobrazení data výchozího kalendáře jazykové verze

  1. Vytvořte instanci objektu kalendáře odvozeného z Calendar třídy, která představuje kalendář, který se má použít.

  2. Vytvořte instanci objektu CultureInfo představující jazykovou verzi, jejíž formátování se použije k zobrazení data.

  3. Array.Exists Voláním metody určete, zda je objekt kalendáře členem pole vrácené CultureInfo.OptionalCalendars vlastností. To znamená, že kalendář může sloužit jako výchozí kalendář objektu CultureInfo . Pokud není členem pole, postupujte podle pokynů v části Zobrazit datum v libovolném kalendáři.

  4. Přiřaďte objekt kalendáře k Calendar vlastnosti DateTimeFormatInfo objektu vráceného CultureInfo.DateTimeFormat vlastností.

    Poznámka:

    Třída CultureInfoCalendar také vlastnost. Je to ale jen pro čtení a konstanta; nezmění se tak, aby odrážel nový výchozí kalendář přiřazený k DateTimeFormatInfo.Calendar vlastnosti.

  5. Zavolejte metodu ToString nebo metodu ToStringCultureInfo a předejte objekt, jehož výchozí kalendář byl změněn v předchozím kroku.

Zobrazení data v libovolném kalendáři

  1. Vytvořte instanci objektu kalendáře odvozeného z Calendar třídy, která představuje kalendář, který se má použít.

  2. Určete, které prvky data a času by se měly zobrazovat v řetězcové reprezentaci hodnoty data a času.

  3. Pro každý prvek data a času, který chcete zobrazit, zavolejte objekt Getkalendáře ... Metoda. K dispozici jsou následující metody:

    • GetYear, aby se rok zobrazil v příslušném kalendáři.

    • GetMonth, aby se měsíc zobrazil v příslušném kalendáři.

    • GetDayOfMonth, aby se zobrazil počet dnů v měsíci v příslušném kalendáři.

    • GetHour, aby se zobrazila hodina dne v příslušném kalendáři.

    • GetMinute, aby se minuty zobrazily v příslušném kalendáři v hodině.

    • GetSecond, aby se v příslušném kalendáři zobrazily sekundy v minutě.

    • GetMilliseconds, aby se v příslušném kalendáři zobrazily milisekundy v sekundě.

Příklad

Příklad zobrazí datum pomocí dvou různých kalendářů. Zobrazí datum po definování kalendáře Hidžra jako výchozího kalendáře pro jazykovou verzi ar-JO a zobrazí datum pomocí perského kalendáře, který není podporován jako volitelný kalendář pro jazykovou verzi 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ždý CultureInfo objekt může podporovat jeden nebo více kalendářů, které jsou označené OptionalCalendars vlastností. Jedna z těchto možností je určena jako výchozí kalendář jazykové verze a je vrácena vlastností jen CultureInfo.Calendar pro čtení. Další z volitelných kalendářů lze určit jako výchozí přiřazením Calendar objektu, který představuje tento kalendář vlastnosti DateTimeFormatInfo.Calendar vrácené CultureInfo.DateTimeFormat vlastností. Některé kalendáře, například perský kalendář reprezentovaný PersianCalendar třídou, však neslouží jako volitelné kalendáře pro žádnou jazykovou verzi.

Příklad definuje opakovaně použitelnou třídu nástroje kalendáře, CalendarUtilitykterá zpracovává mnoho podrobností o generování řetězcové reprezentace data pomocí určitého kalendáře. Třída CalendarUtility má následující členy:

  • Parametrizovaný konstruktor, jehož jediným parametrem Calendar je objekt, ve kterém má být reprezentováno datum. Toto je přiřazeno k privátnímu poli třídy.

  • CalendarExists, privátní metoda, která vrací logickou hodnotu určující, zda je kalendář reprezentovaný CalendarUtility objektem CultureInfo podporován objektem, který je předán metodě jako parametr. Metoda zabalí volání Array.Exists metody, do které předává CultureInfo.OptionalCalendars pole.

  • HasSameName, privátní metoda přiřazená delegátovi Predicate<T> , který je předán jako parametr metodě Array.Exists . Každý člen pole je předán metodě, dokud metoda nevrátí true. Metoda určuje, zda je název volitelného kalendáře stejný jako kalendář reprezentovaný objektem CalendarUtility .

  • DisplayDate, přetížená veřejná metoda, která se předává dvěma parametry: buď hodnotu DateTimeDateTimeOffset nebo hodnotu vyjádřenou v kalendáři reprezentovaný objektem CalendarUtility ; a jazykovou verzi, jejíž pravidla formátování se mají použít. Jeho chování při vrácení řetězcové reprezentace data závisí na tom, zda je cílový kalendář podporován jazykovou verzí, jejíž pravidla formátování se mají použít.

Bez ohledu na kalendář použitý k vytvoření DateTime nebo DateTimeOffset hodnoty v tomto příkladu se tato hodnota obvykle vyjadřuje jako gregoriánské datum. Důvodem je to, že DateTime tyto typy DateTimeOffset nezachovávají žádné informace kalendáře. Interně jsou reprezentovány jako počet ticků, které uplynuly od půlnoci 1. ledna 0001. Interpretace tohoto čísla závisí na kalendáři. Pro většinu kultur je výchozím kalendářem gregoriánský kalendář.