Dela via


Anvisningar: Visa datum i icke-gregorianska kalendrar

Typerna DateTime och DateTimeOffset använder den gregorianska kalendern som standardkalender. Det innebär att metoden för att anropa ett datum- och tidsvärde ToString visar strängrepresentationen av det datumet och tiden i den gregorianska kalendern, även om datum och tid skapades med hjälp av en annan kalender. Detta illustreras i följande exempel, som använder två olika sätt att skapa ett datum- och tidsvärde med den persiska kalendern, men som fortfarande visar dessa datum- och tidsvärden i den gregorianska kalendern när metoden anropas ToString . Det här exemplet visar två vanliga men felaktiga metoder för att visa datumet i en viss 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

Två olika tekniker kan användas för att visa datumet i en viss kalender. Den första kräver att kalendern är standardkalendern för en viss kultur. Den andra kan användas med valfri kalender.

Så här visar du datumet för en kulturs standardkalender

  1. Instansiera ett kalenderobjekt som härleds från klassen Calendar som representerar den kalender som ska användas.

  2. Instansiera ett CultureInfo objekt som representerar kulturen vars formatering ska användas för att visa datumet.

  3. Array.Exists Anropa metoden för att avgöra om kalenderobjektet är medlem i matrisen som returneras av CultureInfo.OptionalCalendars egenskapen. Detta anger att kalendern kan fungera som standardkalender för CultureInfo objektet. Om den inte är medlem i matrisen följer du anvisningarna i avsnittet "Visa datum i valfri kalender".

  4. Tilldela kalenderobjektet till Calendar egenskapen för objektet som DateTimeFormatInfo returneras av egenskapen CultureInfo.DateTimeFormat .

    Kommentar

    Klassen CultureInfo har också en Calendar egenskap. Den är dock skrivskyddad och konstant. den ändras inte för att återspegla den nya standardkalendern som tilldelats egenskapen DateTimeFormatInfo.Calendar .

  5. Anropa antingen ToString metoden eller ToString och skicka det till CultureInfo det objekt vars standardkalender ändrades i föregående steg.

Så här visar du datumet i en kalender

  1. Instansiera ett kalenderobjekt som härleds från klassen Calendar som representerar den kalender som ska användas.

  2. Bestäm vilka datum- och tidselement som ska visas i strängrepresentationen av datum- och tidsvärdet.

  3. För varje datum- och tidselement som du vill visa anropar du kalenderobjektets Get... Metod. Följande metoder finns:

    • GetYear, för att visa året i lämplig kalender.

    • GetMonth, för att visa månaden i lämplig kalender.

    • GetDayOfMonth, för att visa antalet dagar i månaden i lämplig kalender.

    • GetHour, för att visa dagens timme i lämplig kalender.

    • GetMinute, för att visa minuter i timmen i lämplig kalender.

    • GetSecond, för att visa sekunderna i minuten i lämplig kalender.

    • GetMilliseconds, för att visa millisekunderna i den andra i lämplig kalender.

Exempel

I exemplet visas ett datum med två olika kalendrar. Det visar datumet efter att Hijri-kalendern har definierats som standardkalender för ar-JO-kulturen och visar datumet med den persiska kalendern, som inte stöds som en valfri kalender av fa-IR-kulturen.

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

Varje CultureInfo objekt kan ha stöd för en eller flera kalendrar, som anges av egenskapen OptionalCalendars . En av dessa anges som kulturens standardkalender och returneras av den skrivskyddade CultureInfo.Calendar egenskapen. En annan av de valfria kalendrarna kan anges som standard genom att tilldela ett Calendar objekt som representerar den kalendern till egenskapen DateTimeFormatInfo.Calendar som returneras av CultureInfo.DateTimeFormat egenskapen. Vissa kalendrar, till exempel den persiska kalendern som representeras av PersianCalendar klassen, fungerar dock inte som valfria kalendrar för någon kultur.

I exemplet definieras en återanvändbar kalenderverktygsklass, , CalendarUtilityför att hantera många av detaljerna för att generera strängrepresentationen av ett datum med hjälp av en viss kalender. Klassen CalendarUtility har följande medlemmar:

  • En parameteriserad konstruktor vars enda parameter är ett Calendar objekt där ett datum ska representeras. Detta tilldelas till ett privat fält i klassen.

  • CalendarExists, en privat metod som returnerar ett booleskt värde som anger om kalendern som representeras av CalendarUtility objektet stöds av objektet CultureInfo som skickas till metoden som en parameter. Metoden omsluter ett anrop till metoden som den skickar matrisen CultureInfo.OptionalCalendars tillArray.Exists.

  • HasSameName, en privat metod som tilldelats till ombudet Predicate<T> som skickas som en parameter till Array.Exists metoden. Varje medlem i matrisen skickas till metoden tills metoden returnerar true. Metoden avgör om namnet på en valfri kalender är samma som kalendern som representeras av CalendarUtility objektet.

  • DisplayDate, en överbelastad offentlig metod som skickas två parametrar: antingen ett DateTime eller DateTimeOffset -värde som ska uttryckas i kalendern som representeras av CalendarUtility objektet och den kultur vars formateringsregler ska användas. Dess beteende när strängrepresentationen av ett datum returneras beror på om målkalendern stöds av den kultur vars formateringsregler ska användas.

Oavsett vilken kalender som används för att skapa ett DateTime eller DateTimeOffset -värde i det här exemplet uttrycks det vanligtvis som ett gregorianskt datum. Det beror på att typerna DateTime och DateTimeOffset inte bevarar någon kalenderinformation. Internt representeras de som antalet fästingar som har förflutit sedan midnatt den 1 januari 0001. Tolkningen av det talet beror på kalendern. För de flesta kulturer är standardkalendern den gregorianska kalendern.