Práce s kalendáři

Ačkoli hodnota data a času představuje okamžik v čase, jeho řetězcové vyjádření je citlivé na jazykovou verzi a závisí jak na konvencích používaných k zobrazení hodnot data a času konkrétní jazykovou verzí, tak v kalendáři používaném touto jazykovou verzí. Toto téma zkoumá podporu kalendářů v .NET a popisuje použití tříd kalendáře při práci s hodnotami kalendářních dat.

Kalendáře v .NET

Všechny kalendáře v rozhraní .NET jsou odvozeny od třídy System.Globalization.Calendar, která poskytuje základní implementaci kalendáře. Jednou z tříd, které dědí z třídy Calendar, je třída EastAsianLunisolarCalendar, což je základní třída pro všechny lunisolar kalendáře. .NET zahrnuje následující implementace kalendáře:

Kalendář lze použít jedním ze dvou způsobů:

  • Kalendář používaný konkrétní kulturou Každý CultureInfo objekt má aktuální kalendář, což je kalendář, který objekt právě používá. Řetězcové reprezentace všech hodnot data a času automaticky odrážejí aktuální jazykovou verzi a její aktuální kalendář. Aktuální kalendář je obvykle výchozím kalendářem kultury. CultureInfo objekty mají také volitelné kalendáře, které zahrnují další kalendáře, které může daná kultura používat.

  • Samostatný kalendář nezávislý na konkrétní kultuře. V tomto případě se Calendar metody používají k vyjádření kalendářních dat jako hodnot, které odrážejí kalendář.

Všimněte si, že šest tříd kalendáře – ChineseLunisolarCalendar, JapaneseLunisolarCalendar, JulianCalendar, KoreanLunisolarCalendar, PersianCalendara TaiwanLunisolarCalendar – lze použít pouze jako samostatné kalendáře. Nejsou používány žádnou kulturou jako výchozí kalendář nebo jako volitelný kalendář.

Kalendáře a kultury

Každá kultura má výchozí kalendář, který je definován vlastností CultureInfo.Calendar. Vlastnost CultureInfo.OptionalCalendars vrátí pole Calendar objektů, které určují všechny kalendáře podporované konkrétní jazykovou verzí, včetně výchozího kalendáře této jazykové verze.

Následující příklad znázorňuje vlastnosti CultureInfo.Calendar a CultureInfo.OptionalCalendars. Vytvoří objekty typu CultureInfo pro thajskou (Thajsko) a japonskou (Japonsko) kulturu a zobrazí jejich výchozí a volitelné kalendáře. Všimněte si, že v obou případech je výchozí kalendář kultury také součástí kolekce CultureInfo.OptionalCalendars.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      // Create a CultureInfo for Thai in Thailand.
      CultureInfo th = CultureInfo.CreateSpecificCulture("th-TH");
      DisplayCalendars(th);

      // Create a CultureInfo for Japanese in Japan.
      CultureInfo ja = CultureInfo.CreateSpecificCulture("ja-JP");
      DisplayCalendars(ja);
   }

   static void DisplayCalendars(CultureInfo ci)
   {
      Console.WriteLine($"Calendars for the {ci.Name} culture:");

      // Get the culture's default calendar.
      Calendar defaultCalendar = ci.Calendar;
      Console.Write("   Default Calendar: {0}", GetCalendarName(defaultCalendar));

      if (defaultCalendar is GregorianCalendar)
         Console.WriteLine($" ({((GregorianCalendar) defaultCalendar).CalendarType})");
      else
         Console.WriteLine();

      // Get the culture's optional calendars.
      Console.WriteLine("   Optional Calendars:");
      foreach (var optionalCalendar in ci.OptionalCalendars) {
         Console.Write("{0,6}{1}", "", GetCalendarName(optionalCalendar));
         if (optionalCalendar is GregorianCalendar)
            Console.Write(" ({0})",
                          ((GregorianCalendar) optionalCalendar).CalendarType);

         Console.WriteLine();
      }
      Console.WriteLine();
   }

   static string GetCalendarName(Calendar cal)
   {
      return cal.ToString().Replace("System.Globalization.", "");
   }
}
// The example displays the following output:
//       Calendars for the th-TH culture:
//          Default Calendar: ThaiBuddhistCalendar
//          Optional Calendars:
//             ThaiBuddhistCalendar
//             GregorianCalendar (Localized)
//
//       Calendars for the ja-JP culture:
//          Default Calendar: GregorianCalendar (Localized)
//          Optional Calendars:
//             GregorianCalendar (Localized)
//             JapaneseCalendar
//             GregorianCalendar (USEnglish)
Imports System.Globalization

Public Module Example
    Public Sub Main()
        ' Create a CultureInfo for Thai in Thailand.
        Dim th As CultureInfo = CultureInfo.CreateSpecificCulture("th-TH")
        DisplayCalendars(th)

        ' Create a CultureInfo for Japanese in Japan.
        Dim ja As CultureInfo = CultureInfo.CreateSpecificCulture("ja-JP")
        DisplayCalendars(ja)
    End Sub

    Sub DisplayCalendars(ci As CultureInfo)
        Console.WriteLine("Calendars for the {0} culture:", ci.Name)

        ' Get the culture's default calendar.
        Dim defaultCalendar As Calendar = ci.Calendar
        Console.Write("   Default Calendar: {0}", GetCalendarName(defaultCalendar))

        If TypeOf defaultCalendar Is GregorianCalendar Then
            Console.WriteLine(" ({0})",
                              CType(defaultCalendar, GregorianCalendar).CalendarType)
        Else
            Console.WriteLine()
        End If

        ' Get the culture's optional calendars.
        Console.WriteLine("   Optional Calendars:")
        For Each optionalCalendar In ci.OptionalCalendars
            Console.Write("{0,6}{1}", "", GetCalendarName(optionalCalendar))
            If TypeOf optionalCalendar Is GregorianCalendar Then
                Console.Write(" ({0})",
                              CType(optionalCalendar, GregorianCalendar).CalendarType)
            End If
            Console.WriteLine()
        Next
        Console.WriteLine()
    End Sub

    Function GetCalendarName(cal As Calendar) As String
        Return cal.ToString().Replace("System.Globalization.", "")
    End Function
End Module
' The example displays the following output:
'       Calendars for the th-TH culture:
'          Default Calendar: ThaiBuddhistCalendar
'          Optional Calendars:
'             ThaiBuddhistCalendar
'             GregorianCalendar (Localized)
'       
'       Calendars for the ja-JP culture:
'          Default Calendar: GregorianCalendar (Localized)
'          Optional Calendars:
'             GregorianCalendar (Localized)
'             JapaneseCalendar
'             GregorianCalendar (USEnglish)

Kalendář, který aktuálně používá konkrétní objekt CultureInfo, je definován vlastností DateTimeFormatInfo.Calendar kultury. Objekt DateTimeFormatInfo kultury je vrácen vlastností CultureInfo.DateTimeFormat. Když se vytvoří kultura, její výchozí hodnota je stejná jako hodnota vlastnosti CultureInfo.Calendar. Můžete však změnit aktuální kalendář kultury na libovolný kalendář obsažený v poli vrácené vlastností CultureInfo.OptionalCalendars. Pokud se pokusíte nastavit aktuální kalendář na kalendář, který není součástí hodnoty vlastnosti CultureInfo.OptionalCalendars, vyvolá se ArgumentException.

Následující příklad změní kalendář používaný kulturou arabštiny (Saúdská Arábie). Nejprve vytvoří instanci hodnoty DateTime a zobrazí ji pomocí aktuální jazykové verze , což je v tomto případě angličtina (Spojené státy) a kalendář aktuální jazykové verze (což je v tomto případě gregoriánský kalendář). V dalším kroku změní aktuální jazykovou verzi na arabštinu (Saúdská Arábie) a zobrazí datum pomocí výchozího kalendáře Um Al-Qura. Potom zavolá metodu CalendarExists, která určí, jestli je kalendář Hidžra podporovaný jazykovou verzí arabštiny (Saúdská Arábie). Protože je kalendář podporovaný, změní aktuální kalendář na Hidžra a znovu zobrazí datum. Všimněte si, že v každém případě se datum zobrazí pomocí kalendáře aktuálně používaného v současné jazykové verzi.

using System;
using System.Globalization;
using System.Threading;

public class Example
{
   public static void Main()
   {
      DateTime date1 = new DateTime(2011, 6, 20);

      DisplayCurrentInfo();
      // Display the date using the current culture and calendar.
      Console.WriteLine(date1.ToString("d"));
      Console.WriteLine();

      CultureInfo arSA = CultureInfo.CreateSpecificCulture("ar-SA");

      // Change the current culture to Arabic (Saudi Arabia).
      Thread.CurrentThread.CurrentCulture = arSA;
      // Display date and information about the current culture.
      DisplayCurrentInfo();
      Console.WriteLine(date1.ToString("d"));
      Console.WriteLine();

      // Change the calendar to Hijri.
      Calendar hijri = new HijriCalendar();
      if (CalendarExists(arSA, hijri)) {
         arSA.DateTimeFormat.Calendar = hijri;
         // Display date and information about the current culture.
         DisplayCurrentInfo();
         Console.WriteLine(date1.ToString("d"));
      }
   }

   private static void DisplayCurrentInfo()
   {
      Console.WriteLine($"Current Culture: {CultureInfo.CurrentCulture.Name}");
      Console.WriteLine($"Current Calendar: {DateTimeFormatInfo.CurrentInfo.Calendar}");
   }

   private static bool CalendarExists(CultureInfo culture, Calendar cal)
   {
      foreach (Calendar optionalCalendar in culture.OptionalCalendars)
         if (cal.ToString().Equals(optionalCalendar.ToString()))
            return true;

      return false;
   }
}
// The example displays the following output:
//    Current Culture: en-US
//    Current Calendar: System.Globalization.GregorianCalendar
//    6/20/2011
//
//    Current Culture: ar-SA
//    Current Calendar: System.Globalization.UmAlQuraCalendar
//    18/07/32
//
//    Current Culture: ar-SA
//    Current Calendar: System.Globalization.HijriCalendar
//    19/07/32
Imports System.Globalization
Imports System.Threading

Module Example
    Public Sub Main()
        Dim date1 As Date = #6/20/2011#

        DisplayCurrentInfo()
        ' Display the date using the current culture and calendar.
        Console.WriteLine(date1.ToString("d"))
        Console.WriteLine()

        Dim arSA As CultureInfo = CultureInfo.CreateSpecificCulture("ar-SA")

        ' Change the current culture to Arabic (Saudi Arabia).
        Thread.CurrentThread.CurrentCulture = arSA
        ' Display date and information about the current culture.
        DisplayCurrentInfo()
        Console.WriteLine(date1.ToString("d"))
        Console.WriteLine()

        ' Change the calendar to Hijri.
        Dim hijri As Calendar = New HijriCalendar()
        If CalendarExists(arSA, hijri) Then
            arSA.DateTimeFormat.Calendar = hijri
            ' Display date and information about the current culture.
            DisplayCurrentInfo()
            Console.WriteLine(date1.ToString("d"))
        End If
    End Sub

    Private Sub DisplayCurrentInfo()
        Console.WriteLine("Current Culture: {0}",
                          CultureInfo.CurrentCulture.Name)
        Console.WriteLine("Current Calendar: {0}",
                          DateTimeFormatInfo.CurrentInfo.Calendar)
    End Sub

    Private Function CalendarExists(ByVal culture As CultureInfo,
                                    cal As Calendar) As Boolean
        For Each optionalCalendar As Calendar In culture.OptionalCalendars
            If cal.ToString().Equals(optionalCalendar.ToString()) Then Return True
        Next
        Return False
    End Function
End Module
' The example displays the following output:
'    Current Culture: en-US
'    Current Calendar: System.Globalization.GregorianCalendar
'    6/20/2011
'    
'    Current Culture: ar-SA
'    Current Calendar: System.Globalization.UmAlQuraCalendar
'    18/07/32
'    
'    Current Culture: ar-SA
'    Current Calendar: System.Globalization.HijriCalendar
'    19/07/32

Datumy a kalendáře

S výjimkou konstruktorů, které obsahují parametr typu Calendar a umožňují prvky data (tj. měsíce, dne a roku), aby odrážely hodnoty v určeném kalendáři, DateTime i DateTimeOffset hodnoty jsou vždy založeny na gregoriánském kalendáři. To znamená, že například vlastnost DateTime.Year vrátí rok v gregoriánském kalendáři a vlastnost DateTime.Day vrátí den v měsíci v gregoriánském kalendáři.

Důležité

Je důležité si uvědomit, že mezi hodnotou data a řetězcovou reprezentací existuje rozdíl. První je založen na gregoriánském kalendáři; ten je založen na aktuálním kalendáři konkrétní jazykové verze.

Následující příklad ukazuje tento rozdíl mezi DateTime vlastnosti a jejich odpovídajícími metodami Calendar. V příkladu je aktuální kultura arabština (Egypt) a aktuální kalendář je Um Al Qura. Hodnota DateTime je nastavena na patnáctý den sedmého měsíce roku 2011. Je zřejmé, že to je interpretováno jako gregoriánské datum, protože tyto stejné hodnoty jsou vráceny DateTime.ToString(String, IFormatProvider) metodou při použití konvencí invariantní jazykové verze. Řetězcové vyjádření data, které je formátováno podle konvencí aktuální kultury, je 14/08/32, což je ekvivalentní datum v kalendáři Um Al Qura. Dále se členové DateTime a Calendar použijí k vrácení dne, měsíce a roku hodnoty DateTime. V každém případě hodnoty vrácené DateTime členy odrážejí hodnoty v gregoriánském kalendáři, zatímco hodnoty vrácené UmAlQuraCalendar členy odrážejí hodnoty v kalendáři Uum al-Qura.

using System;
using System.Globalization;
using System.Threading;

public class Example
{
   public static void Main()
   {
      // Make Arabic (Egypt) the current culture
      // and Umm al-Qura calendar the current calendar.
      CultureInfo arEG = CultureInfo.CreateSpecificCulture("ar-EG");
      Calendar cal = new UmAlQuraCalendar();
      arEG.DateTimeFormat.Calendar = cal;
      Thread.CurrentThread.CurrentCulture = arEG;

      // Display information on current culture and calendar.
      DisplayCurrentInfo();

      // Instantiate a date object.
      DateTime date1 = new DateTime(2011, 7, 15);

      // Display the string representation of the date.
      Console.WriteLine($"Date: {date1:d}");
      Console.WriteLine($"Date in the Invariant Culture: {date1.ToString("d", CultureInfo.InvariantCulture)}");
      Console.WriteLine();

      // Compare DateTime properties and Calendar methods.
      Console.WriteLine($"DateTime.Month property: {date1.Month}");
      Console.WriteLine($"UmAlQura.GetMonth: {cal.GetMonth(date1)}");
      Console.WriteLine();

      Console.WriteLine($"DateTime.Day property: {date1.Day}");
      Console.WriteLine($"UmAlQura.GetDayOfMonth: {cal.GetDayOfMonth(date1)}");
      Console.WriteLine();

      Console.WriteLine($"DateTime.Year property: {date1.Year:D4}");
      Console.WriteLine($"UmAlQura.GetYear: {cal.GetYear(date1)}");
      Console.WriteLine();
   }

   private static void DisplayCurrentInfo()
   {
      Console.WriteLine($"Current Culture: {CultureInfo.CurrentCulture.Name}");
      Console.WriteLine($"Current Calendar: {DateTimeFormatInfo.CurrentInfo.Calendar}");
   }
}
// The example displays the following output:
//    Current Culture: ar-EG
//    Current Calendar: System.Globalization.UmAlQuraCalendar
//    Date: 14/08/32
//    Date in the Invariant Culture: 07/15/2011
//
//    DateTime.Month property: 7
//    UmAlQura.GetMonth: 8
//
//    DateTime.Day property: 15
//    UmAlQura.GetDayOfMonth: 14
//
//    DateTime.Year property: 2011
//    UmAlQura.GetYear: 1432
Imports System.Globalization
Imports System.Threading

Module Example
    Public Sub Main()
        ' Make Arabic (Egypt) the current culture 
        ' and Umm al-Qura calendar the current calendar. 
        Dim arEG As CultureInfo = CultureInfo.CreateSpecificCulture("ar-EG")
        Dim cal As Calendar = New UmAlQuraCalendar()
        arEG.DateTimeFormat.Calendar = cal
        Thread.CurrentThread.CurrentCulture = arEG

        ' Display information on current culture and calendar.
        DisplayCurrentInfo()

        ' Instantiate a date object.
        Dim date1 As Date = #07/15/2011#

        ' Display the string representation of the date.
        Console.WriteLine("Date: {0:d}", date1)
        Console.WriteLine("Date in the Invariant Culture: {0}",
                          date1.ToString("d", CultureInfo.InvariantCulture))
        Console.WriteLine()

        ' Compare DateTime properties and Calendar methods.
        Console.WriteLine("DateTime.Month property: {0}", date1.Month)
        Console.WriteLine("UmAlQura.GetMonth: {0}",
                          cal.GetMonth(date1))
        Console.WriteLine()

        Console.WriteLine("DateTime.Day property: {0}", date1.Day)
        Console.WriteLine("UmAlQura.GetDayOfMonth: {0}",
                          cal.GetDayOfMonth(date1))
        Console.WriteLine()

        Console.WriteLine("DateTime.Year property: {0:D4}", date1.Year)
        Console.WriteLine("UmAlQura.GetYear: {0}",
                          cal.GetYear(date1))
        Console.WriteLine()
    End Sub

    Private Sub DisplayCurrentInfo()
        Console.WriteLine("Current Culture: {0}",
                          CultureInfo.CurrentCulture.Name)
        Console.WriteLine("Current Calendar: {0}",
                          DateTimeFormatInfo.CurrentInfo.Calendar)
    End Sub
End Module
' The example displays the following output:
'    Current Culture: ar-EG
'    Current Calendar: System.Globalization.UmAlQuraCalendar
'    Date: 14/08/32
'    Date in the Invariant Culture: 07/15/2011
'    
'    DateTime.Month property: 7
'    UmAlQura.GetMonth: 8
'    
'    DateTime.Day property: 15
'    UmAlQura.GetDayOfMonth: 14
'    
'    DateTime.Year property: 2011
'    UmAlQura.GetYear: 1432

Inicializovat data podle kalendáře

Protože jsou hodnoty DateTime a DateTimeOffset založeny na gregoriánském kalendáři, je nutné zavolat přetížený konstruktor s parametrem typu Calendar k vytvoření instance hodnoty data, pokud chcete použít hodnoty dne, měsíce nebo roku z jiného kalendáře. Můžete také volat jedno z přetížení metody konkrétního kalendáře Calendar.ToDateTime, abyste vytvořili instanci objektu DateTime na základě hodnot určitého kalendáře.

Následující příklad vytvoří instanci jedné DateTime hodnoty předáním objektu HebrewCalendar konstruktoru DateTime a vytvoří instanci druhé DateTime hodnoty voláním HebrewCalendar.ToDateTime(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32) metody. Vzhledem k tomu, že jsou tyto dvě hodnoty vytvořeny s identickými hodnotami z hebrejského kalendáře, volání metody DateTime.Equals ukazuje, že tyto dvě DateTime hodnoty jsou stejné.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      HebrewCalendar hc = new HebrewCalendar();

      DateTime date1 = new DateTime(5771, 6, 1, hc);
      DateTime date2 = hc.ToDateTime(5771, 6, 1, 0, 0, 0, 0);

      Console.WriteLine("{0:d} (Gregorian) = {1:d2}/{2:d2}/{3:d4} ({4}): {5}",
                        date1,
                        hc.GetMonth(date2),
                        hc.GetDayOfMonth(date2),
                        hc.GetYear(date2),
                        GetCalendarName(hc),
                        date1.Equals(date2));
   }

   private static string GetCalendarName(Calendar cal)
   {
      return cal.ToString().Replace("System.Globalization.", "").
                            Replace("Calendar", "");
   }
}
// The example displays the following output:
//    2/5/2011 (Gregorian) = 06/01/5771 (Hebrew): True
Imports System.Globalization

Module Example
    Public Sub Main()
        Dim hc As New HebrewCalendar()

        Dim date1 As New Date(5771, 6, 1, hc)
        Dim date2 As Date = hc.ToDateTime(5771, 6, 1, 0, 0, 0, 0)

        Console.WriteLine("{0:d} (Gregorian) = {1:d2}/{2:d2}/{3:d4} ({4}): {5}",
                          date1,
                          hc.GetMonth(date2),
                          hc.GetDayOfMonth(date2),
                          hc.GetYear(date2),
                          GetCalendarName(hc),
                          date1.Equals(date2))
    End Sub

    Private Function GetCalendarName(cal As Calendar) As String
        Return cal.ToString().Replace("System.Globalization.", "").
                              Replace("Calendar", "")
    End Function
End Module
' The example displays the following output:
'   2/5/2011 (Gregorian) = 06/01/5771 (Hebrew): True

Reprezentovat data v aktuálním kalendáři

Metody formátování data a času vždy používají aktuální kalendář při převodu kalendářních dat na řetězce. To znamená, že řetězcové vyjádření roku, měsíce a dne v měsíci odrážejí aktuální kalendář a nemusí nutně odrážet gregoriánský kalendář.

Následující příklad ukazuje, jak aktuální kalendář ovlivňuje řetězcové vyjádření data. Změní aktuální kulturní nastavení na čínštinu (Tradiční, Tchaj-wan) a inicializuje hodnotu data. Pak zobrazí aktuální kalendář a datum, změní aktuální kalendář na TaiwanCalendara znovu zobrazí aktuální kalendář a datum. Při prvním zobrazení je datum reprezentováno jako datum v gregoriánském kalendáři. Podruhé, kdy se zobrazí, je reprezentován jako datum v tchajwanském kalendáři.

using System;
using System.Globalization;
using System.Threading;

public class Example
{
   public static void Main()
   {
      // Change the current culture to zh-TW.
      CultureInfo zhTW = CultureInfo.CreateSpecificCulture("zh-TW");
      Thread.CurrentThread.CurrentCulture = zhTW;
      // Define a date.
      DateTime date1 = new DateTime(2011, 1, 16);

      // Display the date using the default (Gregorian) calendar.
      Console.WriteLine($"Current calendar: {zhTW.DateTimeFormat.Calendar}");
      Console.WriteLine(date1.ToString("d"));

      // Change the current calendar and display the date.
      zhTW.DateTimeFormat.Calendar = new TaiwanCalendar();
      Console.WriteLine($"Current calendar: {zhTW.DateTimeFormat.Calendar}");
      Console.WriteLine(date1.ToString("d"));
   }
}
// The example displays the following output:
//    Current calendar: System.Globalization.GregorianCalendar
//    2011/1/16
//    Current calendar: System.Globalization.TaiwanCalendar
//    100/1/16
Imports System.Globalization
Imports System.Threading

Module Example
    Public Sub Main()
        ' Change the current culture to zh-TW.
        Dim zhTW As CultureInfo = CultureInfo.CreateSpecificCulture("zh-TW")
        Thread.CurrentThread.CurrentCulture = zhTW
        ' Define a date.
        Dim date1 As Date = #1/16/2011#

        ' Display the date using the default (Gregorian) calendar.
        Console.WriteLine("Current calendar: {0}",
                          zhTW.DateTimeFormat.Calendar)
        Console.WriteLine(date1.ToString("d"))

        ' Change the current calendar and display the date.
        zhTW.DateTimeFormat.Calendar = New TaiwanCalendar()
        Console.WriteLine("Current calendar: {0}",
                          zhTW.DateTimeFormat.Calendar)
        Console.WriteLine(date1.ToString("d"))
    End Sub
End Module
' The example displays the following output:
'    Current calendar: System.Globalization.GregorianCalendar
'    2011/1/16
'    Current calendar: System.Globalization.TaiwanCalendar
'    100/1/16

Reprezentace dat v jiných kalendářích než v současných kalendářích

Chcete-li reprezentovat datum pomocí kalendáře, který není aktuálním kalendářem určité kultury, je nutné volat metody tohoto objektu Calendar. Například metody Calendar.GetYear, Calendar.GetMontha Calendar.GetDayOfMonth převádějí rok, měsíc a den na hodnoty, které odrážejí určitý kalendář.

Varování

Některé kalendáře nejsou volitelnou součástí žádné kultury, takže při reprezentaci dat v těchto kalendářích je vždy nutné použít metody kalendáře. To platí pro všechny kalendáře, které jsou odvozeny od EastAsianLunisolarCalendar, JulianCalendara PersianCalendar třídy.

Následující příklad používá objekt JulianCalendar k vytvoření instance data 9. ledna 1905 v kalendáři Julian. Když se toto datum zobrazí pomocí výchozího kalendáře (gregoriánského), bude reprezentováno jako 22. ledna 1905. Volání jednotlivých metod JulianCalendar umožňuje reprezentovat datum v juliánském kalendáři.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      JulianCalendar julian = new JulianCalendar();
      DateTime date1 = new DateTime(1905, 1, 9, julian);

      Console.WriteLine("Date ({0}): {1:d}",
                        CultureInfo.CurrentCulture.Calendar,
                        date1);
      Console.WriteLine("Date in Julian calendar: {0:d2}/{1:d2}/{2:d4}",
                        julian.GetMonth(date1),
                        julian.GetDayOfMonth(date1),
                        julian.GetYear(date1));
   }
}
// The example displays the following output:
//    Date (System.Globalization.GregorianCalendar): 1/22/1905
//    Date in Julian calendar: 01/09/1905
Imports System.Globalization

Module Example
    Public Sub Main()
        Dim julian As New JulianCalendar()
        Dim date1 As New Date(1905, 1, 9, julian)

        Console.WriteLine("Date ({0}): {1:d}",
                          CultureInfo.CurrentCulture.Calendar,
                          date1)
        Console.WriteLine("Date in Julian calendar: {0:d2}/{1:d2}/{2:d4}",
                          julian.GetMonth(date1),
                          julian.GetDayOfMonth(date1),
                          julian.GetYear(date1))
    End Sub
End Module
' The example displays the following output:
'    Date (System.Globalization.GregorianCalendar): 1/22/1905
'    Date in Julian calendar: 01/09/1905

Kalendáře a rozsahy kalendářních dat

Nejstarší datum podporované kalendářem je označeno vlastností Calendar.MinSupportedDateTime kalendáře. Pro třídu GregorianCalendar je toto datum 1. ledna 0001 C.E. Většina ostatních kalendářů v .NET podporuje pozdější datum. Při pokusu o práci s hodnotou data a času, která předchází nejstaršímu podporovanému datu kalendáře, dojde k výjimce ArgumentOutOfRangeException.

Existuje však jedna důležitá výjimka. Výchozí (neinicializovaná) hodnota objektu DateTime a objekt DateTimeOffset je roven hodnotě GregorianCalendar.MinSupportedDateTime. Pokud se pokusíte naformátovat toto datum v kalendáři, který nepodporuje 1. ledna 0001 C.E. a nezadáte specifikátor formátu, použije metoda formátování specifikátor formátu "s" (seřaditelný vzor data a času) místo specifikátoru formátu G (obecný vzor data a času). V důsledku toho operace formátování nevyvolá výjimku ArgumentOutOfRangeException. Místo toho vrátí nepodporované datum. To je znázorněno v následujícím příkladu, který zobrazuje hodnotu DateTime.MinValue, když je aktuální jazyková verze nastavena na japonštinu (Japonsko) s japonským kalendářem a na arabštinu (Egypt) s kalendářem Um Al Qura. Nastaví také aktuální jazyk na angličtinu (Spojené státy) a volá metodu DateTime.ToString(IFormatProvider) na každý z těchto objektů CultureInfo. V každém případě se datum zobrazí pomocí seřaditelného vzoru data a času.

using System;
using System.Globalization;
using System.Threading;

public class Example
{
   public static void Main()
   {
      DateTime dat = DateTime.MinValue;

      // Change the current culture to ja-JP with the Japanese Calendar.
      CultureInfo jaJP = CultureInfo.CreateSpecificCulture("ja-JP");
      jaJP.DateTimeFormat.Calendar = new JapaneseCalendar();
      Thread.CurrentThread.CurrentCulture = jaJP;
      Console.WriteLine($"Earliest supported date by {GetCalendarName(jaJP)} calendar: {jaJP.DateTimeFormat.Calendar.MinSupportedDateTime:d}");
      // Attempt to display the date.
      Console.WriteLine(dat.ToString());
      Console.WriteLine();

      // Change the current culture to ar-EG with the Um Al Qura calendar.
      CultureInfo arEG = CultureInfo.CreateSpecificCulture("ar-EG");
      arEG.DateTimeFormat.Calendar = new UmAlQuraCalendar();
      Thread.CurrentThread.CurrentCulture = arEG;
      Console.WriteLine($"Earliest supported date by {GetCalendarName(arEG)} calendar: {arEG.DateTimeFormat.Calendar.MinSupportedDateTime:d}");
      // Attempt to display the date.
      Console.WriteLine(dat.ToString());
      Console.WriteLine();

      // Change the current culture to en-US.
      Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
      Console.WriteLine(dat.ToString(jaJP));
      Console.WriteLine(dat.ToString(arEG));
      Console.WriteLine(dat.ToString("d"));
   }

   private static string GetCalendarName(CultureInfo culture)
   {
      Calendar cal = culture.DateTimeFormat.Calendar;
      return cal.GetType().Name.Replace("System.Globalization.", "").Replace("Calendar", "");
   }
}
// The example displays the following output:
//       Earliest supported date by Japanese calendar: 明治 1/9/8
//       0001-01-01T00:00:00
//
//       Earliest supported date by UmAlQura calendar: 01/01/18
//       0001-01-01T00:00:00
//
//       0001-01-01T00:00:00
//       0001-01-01T00:00:00
//       1/1/0001
Imports System.Globalization
Imports System.Threading

Module Example
    Public Sub Main()
        Dim dat As Date = DateTime.MinValue

        ' Change the current culture to ja-JP with the Japanese Calendar.
        Dim jaJP As CultureInfo = CultureInfo.CreateSpecificCulture("ja-JP")
        jaJP.DateTimeFormat.Calendar = New JapaneseCalendar()
        Thread.CurrentThread.CurrentCulture = jaJP
        Console.WriteLine("Earliest supported date by {1} calendar: {0:d}",
                          jaJP.DateTimeFormat.Calendar.MinSupportedDateTime,
                          GetCalendarName(jaJP))
        ' Attempt to display the date.
        Console.WriteLine(dat.ToString())
        Console.WriteLine()

        ' Change the current culture to ar-EG with the Um Al Qura calendar.
        Dim arEG As CultureInfo = CultureInfo.CreateSpecificCulture("ar-EG")
        arEG.DateTimeFormat.Calendar = New UmAlQuraCalendar()
        Thread.CurrentThread.CurrentCulture = arEG
        Console.WriteLine("Earliest supported date by {1} calendar: {0:d}",
                          arEG.DateTimeFormat.Calendar.MinSupportedDateTime,
                          GetCalendarName(arEG))
        ' Attempt to display the date.
        Console.WRiteLine(dat.ToString())
        Console.WRiteLine()

        ' Change the current culture to en-US.
        Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US")
        Console.WriteLine(dat.ToString(jaJP))
        Console.WriteLine(dat.ToString(arEG))
        Console.WriteLine(dat.ToString("d"))
    End Sub

    Private Function GetCalendarName(culture As CultureInfo) As String
        Dim cal As Calendar = culture.DateTimeFormat.Calendar
        Return cal.GetType().Name.Replace("System.Globalization.", "").Replace("Calendar", "")
    End Function
End Module
' The example displays the following output:
'       Earliest supported date by Japanese calendar: 明治 1/9/8
'       0001-01-01T00:00:00
'       
'       Earliest supported date by UmAlQura calendar: 01/01/18
'       0001-01-01T00:00:00
'       
'       0001-01-01T00:00:00
'       0001-01-01T00:00:00
'       1/1/0001

Práce s érami

Kalendáře obvykle rozdělují kalendářní data na éry. Třídy Calendar v .NET však nepodporují každou éru definovanou kalendářem a většina tříd Calendar podporuje pouze jednu éru. Více období podporují pouze třídy JapaneseCalendar a JapaneseLunisolarCalendar.

Důležité

Éra Reiwa, nová éra v JapaneseCalendar a JapaneseLunisolarCalendar, začíná 1. května 2019. Tato změna má vliv na všechny aplikace, které tyto kalendáře používají. Další informace najdete v následujících článcích:

Éra ve většině kalendářů označuje extrémně dlouhé časové období. V gregoriánském kalendáři například aktuální období pokrývá více než dvě mileniály. U kalendářů JapaneseCalendar a JapaneseLunisolarCalendar, které podporují více období, to není tento případ. Éra odpovídá období císařovy vlády. Podpora více období, zejména pokud je horní mez současné éry neznámá, představuje zvláštní výzvy.

Éry a názvy era

V .NET jsou celá čísla, která představují éry podporované konkrétní implementací kalendáře, uloženy v obráceném pořadí v poli Calendar.Eras. Aktuální éra (což je éra s posledním časovým rozsahem) je na indexu nula a pro třídy Calendar, které podporují více éry, každý následný index odráží předchozí éru. Statická vlastnost Calendar.CurrentEra definuje index aktuální éry v poli Calendar.Eras; je to konstanta, jejíž hodnota je vždy nula. Jednotlivé třídy Calendar zahrnují také statická pole, která vracejí hodnotu aktuální éry. Jsou uvedeny v následující tabulce.

Kalendář - Třída Aktuální éra v oboru
ChineseLunisolarCalendar ChineseEra
GregorianCalendar ADEra
HebrewCalendar HebrewEra
HijriCalendar HijriEra
JapaneseLunisolarCalendar JapaneseEra
JulianCalendar JulianEra
KoreanCalendar KoreanEra
KoreanLunisolarCalendar GregorianEra
PersianCalendar PersianEra
ThaiBuddhistCalendar ThaiBuddhistEra
UmAlQuraCalendar UmAlQuraEra

Název odpovídající určitému číslu éry lze načíst předáním čísla éry do metody DateTimeFormatInfo.GetEraName nebo DateTimeFormatInfo.GetAbbreviatedEraName. Příklad níže ukazuje volání těchto metod k načtení informací o podpoře éry ve třídě GregorianCalendar. Zobrazuje datum gregoriánského kalendáře, které odpovídá 1. lednu druhého roku aktuální éry, a také gregoriánskému kalendářnímu datu, které odpovídá 1. lednu druhého roku každého podporovaného japonského kalendářního období.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      int year = 2;
      int month = 1;
      int day = 1;
      Calendar cal = new JapaneseCalendar();

      Console.WriteLine("\nDate instantiated without an era:");
      DateTime date1 = new DateTime(year, month, day, 0, 0, 0, 0, cal);
      Console.WriteLine("{0}/{1}/{2} in Japanese Calendar -> {3:d} in Gregorian",
                        cal.GetMonth(date1), cal.GetDayOfMonth(date1),
                        cal.GetYear(date1), date1);

      Console.WriteLine("\nDates instantiated with eras:");
      foreach (int era in cal.Eras) {
         DateTime date2 = cal.ToDateTime(year, month, day, 0, 0, 0, 0, era);
         Console.WriteLine("{0}/{1}/{2} era {3} in Japanese Calendar -> {4:d} in Gregorian",
                           cal.GetMonth(date2), cal.GetDayOfMonth(date2),
                           cal.GetYear(date2), cal.GetEra(date2), date2);
      }
   }
}
Imports System.Globalization

Module Example
    Public Sub Main()
        Dim year As Integer = 2
        Dim month As Integer = 1
        Dim day As Integer = 1
        Dim cal As New JapaneseCalendar()

        Console.WriteLine("Date instantiated without an era:")
        Dim date1 As New Date(year, month, day, 0, 0, 0, 0, cal)
        Console.WriteLine("{0}/{1}/{2} in Japanese Calendar -> {3:d} in Gregorian",
                          cal.GetMonth(date1), cal.GetDayOfMonth(date1),
                          cal.GetYear(date1), date1)
        Console.WriteLine()

        Console.WriteLine("Dates instantiated with eras:")
        For Each era As Integer In cal.Eras
            Dim date2 As Date = cal.ToDateTime(year, month, day, 0, 0, 0, 0, era)
            Console.WriteLine("{0}/{1}/{2} era {3} in Japanese Calendar -> {4:d} in Gregorian",
                              cal.GetMonth(date2), cal.GetDayOfMonth(date2),
                              cal.GetYear(date2), cal.GetEra(date2), date2)
        Next
    End Sub
End Module

Kromě toho řetězec vlastního formátu data a času "g" obsahuje název éry kalendáře v řetězcové reprezentaci data a času. Další informace naleznete v tématu řetězce formátu data a času.

Inicializujte datum s érou

Pro dvě třídy Calendar, které podporují více období, může být nejednoznačné datum, které se skládá z určitého roku, měsíce a dne v měsíci. Například všechna období podporovaná JapaneseCalendar mají roky, jejichž číslo je 1. Obvykle platí, že pokud není zadána éra, metody data a času i kalendáře předpokládají, že hodnoty patří do aktuální éry. Platí to pro konstruktory DateTime a DateTimeOffset, které zahrnují parametry typu Calendar, a také pro metody JapaneseCalendar.ToDateTime a JapaneseLunisolarCalendar.ToDateTime. Následující příklad vytvoří instanci data, která představuje 1. ledna druhého roku nezadané éry. Pokud spustíte příklad, když je éra Reiwa současnou érou, datum se interpretuje jako druhý rok éry Reiwa. Éra nazvaná 令和 předchází roku ve vráceném řetězci metodou DateTime.ToString(String, IFormatProvider) a odpovídá gregoriánskému datu 1. ledna 2020. (Reiwa era začíná v roce 2019 gregoriánského kalendáře.)

using System;
using System.Globalization;

public class Example
{
    public static void Main()
    {
        var japaneseCal = new JapaneseCalendar();
        var jaJp = new CultureInfo("ja-JP");
        jaJp.DateTimeFormat.Calendar = japaneseCal;

        var date = new DateTime(2, 1, 1, japaneseCal);
        Console.WriteLine($"Gregorian calendar date: {date:d}");
        Console.WriteLine($"Japanese calendar date: {date.ToString("d", jaJp)}");
    }
}
Imports System.Globalization

Public Module Example
    Public Sub Main()
        Dim japaneseCal = New JapaneseCalendar()
        Dim jaJp = New CultureInfo("ja-JP")
        jaJp.DateTimeFormat.Calendar = japaneseCal

        Dim dat = New DateTime(2, 1, 1, japaneseCal)
        Console.WriteLine($"Gregorian calendar dat: {dat:d}")
        Console.WriteLine($"Japanese calendar dat: {dat.ToString("d", jaJp)}")
    End Sub
End Module

Pokud se ale období změní, záměr tohoto kódu bude nejednoznačný. Je datum určené k vyjádření druhého roku aktuální éry, nebo má představovat druhý rok období Heisei? Existují dva způsoby, jak se této nejednoznačnosti vyhnout:

  • Vytvořte instanci hodnoty data a času pomocí výchozí třídy GregorianCalendar. Pak můžete použít japonský kalendář nebo japonský lunisolar kalendář pro řetězcovou reprezentaci kalendářních dat, jak ukazuje následující příklad.

    using System;
    using System.Globalization;
    
    public class Example
    {
        public static void Main()
        {
            var japaneseCal = new JapaneseCalendar();
            var jaJp = new CultureInfo("ja-JP");
            jaJp.DateTimeFormat.Calendar = japaneseCal;
    
            var date = new DateTime(1905, 2, 12);
            Console.WriteLine($"Gregorian calendar date: {date:d}");
    
            // Call the ToString(IFormatProvider) method.
            Console.WriteLine($"Japanese calendar date: {date.ToString("d", jaJp)}");
    
            // Use a FormattableString object.
            FormattableString fmt = $"{date:d}";
            Console.WriteLine($"Japanese calendar date: {fmt.ToString(jaJp)}");
    
            // Use the JapaneseCalendar object.
            Console.WriteLine($"Japanese calendar date: {jaJp.DateTimeFormat.GetEraName(japaneseCal.GetEra(date))}" +
                              $"{japaneseCal.GetYear(date)}/{japaneseCal.GetMonth(date)}/{japaneseCal.GetDayOfMonth(date)}");
    
            // Use the current culture.
            CultureInfo.CurrentCulture = jaJp;
            Console.WriteLine($"Japanese calendar date: {date:d}");
        }
    }
    // The example displays the following output:
    //   Gregorian calendar date: 2/12/1905
    //   Japanese calendar date: 明治38/2/12
    //   Japanese calendar date: 明治38/2/12
    //   Japanese calendar date: 明治38/2/12
    //   Japanese calendar date: 明治38/2/12
    
    Imports System.Globalization
    
    Public Module Example
        Public Sub Main()
            Dim japaneseCal = New JapaneseCalendar()
            Dim jaJp = New CultureInfo("ja-JP")
            jaJp.DateTimeFormat.Calendar = japaneseCal
    
            Dim dat = New DateTime(1905, 2, 12)
            Console.WriteLine($"Gregorian calendar date: {dat:d}")
    
            ' Call the ToString(IFormatProvider) method.
            Console.WriteLine($"Japanese calendar date: {dat.ToString("d", jaJp)}")
    
            ' Use a FormattableString object.
            Dim fmt As FormattableString = $"{dat:d}"
            Console.WriteLine($"Japanese calendar date: {fmt.ToString(jaJp)}")
    
            ' Use the JapaneseCalendar object.
            Console.WriteLine($"Japanese calendar date: {jaJp.DateTimeFormat.GetEraName(japaneseCal.GetEra(dat))}" +
                              $"{japaneseCal.GetYear(dat)}/{japaneseCal.GetMonth(dat)}/{japaneseCal.GetDayOfMonth(dat)}")
    
            ' Use the current culture.
            CultureInfo.CurrentCulture = jaJp
            Console.WriteLine($"Japanese calendar date: {dat:d}")
        End Sub
    End Module
    ' The example displays the following output:
    '   Gregorian calendar date: 2/12/1905
    '   Japanese calendar date: 明治38/2/12
    '   Japanese calendar date: 明治38/2/12
    '   Japanese calendar date: 明治38/2/12
    '   Japanese calendar date: 明治38/2/12
    
    
    
  • Zavolejte funkci data a času, která explicitně určuje éru. To zahrnuje následující metody:

    Následující příklad používá tři z těchto metod k vytvoření instance data a času v období Meiji, který začal 8. září 1868 a skončil 29. července 1912.

    using System;
    using System.Globalization;
    
    public class Example
    {
        public static void Main()
        {
            var japaneseCal = new JapaneseCalendar();
            var jaJp = new CultureInfo("ja-JP");
            jaJp.DateTimeFormat.Calendar = japaneseCal;
    
            // We can get the era index by calling DateTimeFormatInfo.GetEraName.
            int eraIndex = 0;
    
            for (int ctr = 0; ctr < jaJp.DateTimeFormat.Calendar.Eras.Length; ctr++)
               if (jaJp.DateTimeFormat.GetEraName(ctr) == "明治")
                  eraIndex = ctr;
            var date1 = japaneseCal.ToDateTime(23, 9, 8, 0, 0, 0, 0, eraIndex);
            Console.WriteLine($"{date1.ToString("d", jaJp)} (Gregorian {date1:d})");
    
            try {
                var date2 = DateTime.Parse("明治23/9/8", jaJp);
                Console.WriteLine($"{date2.ToString("d", jaJp)} (Gregorian {date2:d})");
            }
            catch (FormatException)
            {
                Console.WriteLine("The parsing operation failed.");
            }
    
            try {
                var date3 = DateTime.ParseExact("明治23/9/8", "gyy/M/d", jaJp);
                Console.WriteLine($"{date3.ToString("d", jaJp)} (Gregorian {date3:d})");
            }
            catch (FormatException)
            {
                Console.WriteLine("The parsing operation failed.");
            }
        }
    }
    // The example displays the following output:
    //   明治23/9/8 (Gregorian 9/8/1890)
    //   明治23/9/8 (Gregorian 9/8/1890)
    //   明治23/9/8 (Gregorian 9/8/1890)
    
    Imports System.Globalization
    
    Public Module Example
        Public Sub Main()
            Dim japaneseCal = New JapaneseCalendar()
            Dim jaJp = New CultureInfo("ja-JP")
            jaJp.DateTimeFormat.Calendar = japaneseCal
    
            ' We can get the era index by calling DateTimeFormatInfo.GetEraName.
            Dim eraIndex As Integer = 0
    
            For ctr As Integer = 0 To jaJp.DateTimeFormat.Calendar.Eras.Length - 1
                If jaJp.DateTimeFormat.GetEraName(ctr) = "明治" Then eraIndex = ctr
            Next
            Dim date1 = japaneseCal.ToDateTime(23, 9, 8, 0, 0, 0, 0, eraIndex)
            Console.WriteLine($"{date1.ToString("d", jaJp)} (Gregorian {date1:d})")
    
            Try
                Dim date2 = DateTime.Parse("明治23/9/8", jaJp)
                Console.WriteLine($"{date2.ToString("d", jaJp)} (Gregorian {date2:d})")
            Catch e As FormatException
                Console.WriteLine("The parsing operation failed.")
            End Try
    
            Try
                Dim date3 = DateTime.ParseExact("明治23/9/8", "gyy/M/d", jaJp)
                Console.WriteLine($"{date3.ToString("d", jaJp)} (Gregorian {date3:d})")
            Catch e As FormatException
                Console.WriteLine("The parsing operation failed.")
            End Try
        End Sub
    End Module
    ' The example displays the following output:
    '   明治23/9/8 (Gregorian 9/8/1890)
    '   明治23/9/8 (Gregorian 9/8/1890)
    '   明治23/9/8 (Gregorian 9/8/1890)
    

Návod

Při práci s kalendáři, které podporují více ér, vždy použijte gregoriánské datum k vytvoření instance data nebo zadejte éru při vytvoření instance data a času na základě tohoto kalendáře.

Při zadání éry pro ToDateTime(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32) metodu zadáte index éry ve vlastnosti Eras kalendáře. Pro kalendáře, jejichž éry se však mohou změnit, nejsou tyto indexy konstantními hodnotami; aktuální éra je na indexu 0 a nejstarší éra je na indexu Eras.Length - 1. Když do kalendáře přidáte novou éru, indexy předchozích období se zvětší o jednu. Příslušné číslo epochy můžete zadat následujícím způsobem:

Kalendáře, éry a rozsahy dat: Uvolněné kontroly rozsahu

Velmi podobně jako jednotlivé kalendáře mají podporované rozsahy dat, mají i éry ve třídách JapaneseCalendar a JapaneseLunisolarCalendar podporované rozsahy. Rozhraní .NET dříve používalo přísné kontroly rozsahu období, aby zajistilo, že datum specifické pro éru bylo v rámci toho období. To znamená, že pokud datum je mimo rozsah zadané éry, metoda vyvolá ArgumentOutOfRangeException. V současné době používá .NET ve výchozím nastavení uvolněnou kontrolu rozsahu. Aktualizace všech verzí rozhraní .NET zavedly uvolněné kontroly rozsahu období; pokud se pokusíte vytvořit instanci data specifického pro éru, které je mimo rozsah zadané éry, přeteče do následující éry a není vyvolána žádná výjimka.

Následující příklad se pokusí vytvořit instanci data v 65. roce éry Showa, která začala 25. prosince 1926 a skončila 7. ledna 1989. Toto datum odpovídá 9. lednu 1990, který je mimo rozsah éry Šówa označený v JapaneseCalendar. Jak ukazuje výstup z příkladu, datum zobrazené v příkladu je 9. ledna 1990 v druhém roce heiseiové éry.

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      var jaJp = new CultureInfo("ja-JP");
      var cal = new JapaneseCalendar();
      jaJp.DateTimeFormat.Calendar = cal;
      string showaEra = "昭和";

      var dt = cal.ToDateTime(65, 1, 9, 15, 0, 0, 0, GetEraIndex(showaEra));
      FormattableString fmt = $"{dt:d}";

      Console.WriteLine($"Japanese calendar date: {fmt.ToString(jaJp)}");
      Console.WriteLine($"Gregorian calendar date: {fmt}");

      int GetEraIndex(string eraName)
      {
         foreach (var ctr in cal.Eras)
            if (jaJp.DateTimeFormat.GetEraName(ctr) == eraName)
               return ctr;

         return 0;
      }
   }
}
// The example displays the following output:
//   Japanese calendar date: 平成2/1/9
//   Gregorian calendar date: 1/9/1990
Imports System.Globalization

Public Module Example
    Dim jaJp As CultureInfo
    Dim cal As Calendar

    Public Sub Main()
        jaJp = New CultureInfo("ja-JP")
        cal = New JapaneseCalendar()
        jaJp.DateTimeFormat.Calendar = cal
        Dim showaEra = "昭和"

        Dim dt = cal.ToDateTime(65, 1, 9, 15, 0, 0, 0, GetEraIndex(showaEra))
        Dim fmt As FormattableString = $"{dt:d}"
        Console.WriteLine($"Japanese calendar date: {fmt.ToString(jaJp)}")
        Console.WriteLine($"Gregorian calendar date: {fmt}")
    End Sub

    Private Function GetEraIndex(eraName As String) As Integer
        For Each ctr As Integer In cal.Eras
            If jaJp.DateTimeFormat.GetEraName(ctr) = eraName Then Return ctr
        Next
        Return 0
    End Function
End Module
' The example displays the following output:
'   Japanese calendar date: 平成2/1/9
'   Gregorian calendar date: 1/9/1990

Pokud jsou uvolněné kontroly rozsahu nežádoucí, můžete v závislosti na verzi .NET, na které běží vaše aplikace, obnovit přísné kontroly rozsahu několika způsoby:

  • .NET Core: do konfiguračního souboru .netcore.runtime.json přidejte následující:

    "runtimeOptions": {
      "configProperties": {
          "Switch.System.Globalization.EnforceJapaneseEraYearRanges": true
      }
    }
    
  • rozhraní .NET Framework 4.6 nebo novější: v souboru app.config nastavte následující přepínač AppContext:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <runtime>
        <AppContextSwitchOverrides value="Switch.System.Globalization.EnforceJapaneseEraYearRanges=true" />
      </runtime>
    </configuration>
    
  • rozhraní .NET Framework 4.5.2 nebo starší: Nastavte následující hodnotu registru:

    Hodnota
    klíč HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AppContext
    Položka Přepnout.Systém.Globalizace.UplatnitRozsahyJaponskýchErRočních
    Typ REG_SZ
    Hodnota pravda

Při povolených kontrolách striktního rozsahu vyvolá předchozí příklad ArgumentOutOfRangeException a zobrazí následující výstup:

Unhandled Exception: System.ArgumentOutOfRangeException: Valid values are between 1 and 64, inclusive.
Parameter name: year
   at System.Globalization.GregorianCalendarHelper.GetYearOffset(Int32 year, Int32 era, Boolean throwOnError)
   at System.Globalization.GregorianCalendarHelper.ToDateTime(Int32 year, Int32 month, Int32 day, Int32 hour, Int32 minute, Int32 second, Int32 millisecond, Int32 era)
   at Example.Main()

Znázornění kalendářních dat v kalendářích s několika obdobími

Pokud objekt Calendar podporuje éry a je aktuálním kalendářem objektu CultureInfo, je éra zahrnuta v řetězcové reprezentaci hodnoty data a času pro úplné datum a čas, dlouhé datum a krátké vzorce kalendářních dat. Následující příklad zobrazí tyto vzory dat, když aktuální kultura je Japonsko (japonština) a aktuální kalendář je japonský.

using System;
using System.Globalization;
using System.IO;
using System.Threading;

public class Example
{
   public static void Main()
   {
      StreamWriter sw = new StreamWriter(@".\eras.txt");
      DateTime dt = new DateTime(2012, 5, 1);

      CultureInfo culture = CultureInfo.CreateSpecificCulture("ja-JP");
      DateTimeFormatInfo dtfi = culture.DateTimeFormat;
      dtfi.Calendar = new JapaneseCalendar();
      Thread.CurrentThread.CurrentCulture = culture;

      sw.WriteLine("\n{0,-43} {1}", "Full Date and Time Pattern:", dtfi.FullDateTimePattern);
      sw.WriteLine(dt.ToString("F"));
      sw.WriteLine();

      sw.WriteLine("\n{0,-43} {1}", "Long Date Pattern:", dtfi.LongDatePattern);
      sw.WriteLine(dt.ToString("D"));

      sw.WriteLine("\n{0,-43} {1}", "Short Date Pattern:", dtfi.ShortDatePattern);
      sw.WriteLine(dt.ToString("d"));
      sw.Close();
    }
}
// The example writes the following output to a file:
//    Full Date and Time Pattern:                 gg y'年'M'月'd'日' H:mm:ss
//    平成 24年5月1日 0:00:00
//
//    Long Date Pattern:                          gg y'年'M'月'd'日'
//    平成 24年5月1日
//
//    Short Date Pattern:                         gg y/M/d
//    平成 24/5/1
Imports System.Globalization
Imports System.IO
Imports System.Threading

Module Example
    Public Sub Main()
        Dim sw As New StreamWriter(".\eras.txt")
        Dim dt As Date = #05/01/2012#

        Dim culture As CultureInfo = CultureInfo.CreateSpecificCulture("ja-JP")
        Dim dtfi As DateTimeFormatInfo = culture.DateTimeFormat
        dtfi.Calendar = New JapaneseCalendar()
        Thread.CurrentThread.CurrentCulture = culture

        sw.WriteLine("{0,-43} {1}", "Full Date and Time Pattern:", dtfi.FullDateTimePattern)
        sw.WriteLine(dt.ToString("F"))
        sw.WriteLine()

        sw.WriteLine("{0,-43} {1}", "Long Date Pattern:", dtfi.LongDatePattern)
        sw.WriteLine(dt.ToString("D"))
        sw.WriteLine()

        sw.WriteLine("{0,-43} {1}", "Short Date Pattern:", dtfi.ShortDatePattern)
        sw.WriteLine(dt.ToString("d"))
        sw.WriteLine()
        sw.Close()
    End Sub
End Module
' The example writes the following output to a file:
'    Full Date and Time Pattern:                 gg y'年'M'月'd'日' H:mm:ss
'    平成 24年5月1日 0:00:00
'    
'    Long Date Pattern:                          gg y'年'M'月'd'日'
'    平成 24年5月1日
'    
'    Short Date Pattern:                         gg y/M/d
'    平成 24/5/1 

Varování

Třída JapaneseCalendar je jedinou třídou kalendáře v rozhraní .NET, která podporuje kalendářní data ve více než jedné éře a která může být aktuálním kalendářem objektu CultureInfo – konkrétně objektu CultureInfo, který představuje japonskou (Japonsko) kulturu.

Specifikátor vlastního formátu "g" pro všechny kalendáře obsahuje ve výsledném řetězci éru. Následující příklad používá řetězec vlastního formátu "MM-dd-yy g" k zahrnutí éry do výsledného řetězce, pokud je aktuálním kalendářem gregoriánský kalendář.

   DateTime dat = new DateTime(2012, 5, 1);
   Console.WriteLine($"{dat:MM-dd-yyyy g}");
// The example displays the following output:
//     05-01-2012 A.D.
Dim dat As Date = #05/01/2012#
Console.WriteLine("{0:MM-dd-yyyy g}", dat)
' The example displays the following output:
'     05-01-2012 A.D.      

V případech, kdy je řetězcové vyjádření data vyjádřeno v kalendáři, který není aktuálním kalendářem, obsahuje třída Calendar metodu Calendar.GetEra, kterou lze použít společně s Calendar.GetYear, Calendar.GetMontha Calendar.GetDayOfMonth metody, které jednoznačně označují datum a éru, do které patří. Následující příklad používá třídu JapaneseLunisolarCalendar k poskytnutí ilustrace. Všimněte si však, že zahrnutí smysluplného názvu nebo zkratky namísto celého čísla pro období ve výsledném řetězci vyžaduje vytvoření instance objektu DateTimeFormatInfo a vytvoření JapaneseCalendar jeho aktuálního kalendáře. (JapaneseLunisolarCalendar kalendář nemůže být současným kalendářem žádné kultury, ale v tomto případě oba kalendáře sdílejí stejná období.)

using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      DateTime date1 = new DateTime(2011, 8, 28);
      Calendar cal = new JapaneseLunisolarCalendar();

      Console.WriteLine("{0} {1:d4}/{2:d2}/{3:d2}",
                        cal.GetEra(date1),
                        cal.GetYear(date1),
                        cal.GetMonth(date1),
                        cal.GetDayOfMonth(date1));

      // Display eras
      CultureInfo culture = CultureInfo.CreateSpecificCulture("ja-JP");
      DateTimeFormatInfo dtfi = culture.DateTimeFormat;
      dtfi.Calendar = new JapaneseCalendar();

      Console.WriteLine("{0} {1:d4}/{2:d2}/{3:d2}",
                        dtfi.GetAbbreviatedEraName(cal.GetEra(date1)),
                        cal.GetYear(date1),
                        cal.GetMonth(date1),
                        cal.GetDayOfMonth(date1));
   }
}
// The example displays the following output:
//       4 0023/07/29
//       平 0023/07/29
Imports System.Globalization

Module Example
    Public Sub Main()
        Dim date1 As Date = #8/28/2011#
        Dim cal As New JapaneseLunisolarCalendar()
        Console.WriteLine("{0} {1:d4}/{2:d2}/{3:d2}",
                          cal.GetEra(date1),
                          cal.GetYear(date1),
                          cal.GetMonth(date1),
                          cal.GetDayOfMonth(date1))

        ' Display eras
        Dim culture As CultureInfo = CultureInfo.CreateSpecificCulture("ja-JP")
        Dim dtfi As DateTimeFormatInfo = culture.DateTimeFormat
        dtfi.Calendar = New JapaneseCalendar()

        Console.WriteLine("{0} {1:d4}/{2:d2}/{3:d2}",
                          dtfi.GetAbbreviatedEraName(cal.GetEra(date1)),
                          cal.GetYear(date1),
                          cal.GetMonth(date1),
                          cal.GetDayOfMonth(date1))
    End Sub
End Module
' The example displays the following output:
'       4 0023/07/29
'       平 0023/07/29

V japonských kalendářích se první rok éry nazývá Gannen (元年). Například místo Heisei 1 může být první rok éry Heisei popsán jako Heisei Gannen. .NET přijímá tuto konvenci při operacích formátování kalendářních dat a časů formátovaných pomocí následujících standardních nebo vlastních řetězců formátu data a času, když se používají s objektem CultureInfo, který představuje jazykovou verzi Japanese-Japan ("ja-JP") s JapaneseCalendar třídou:

Například následující příklad zobrazí datum v prvním roce období Heisei v JapaneseCalendar.

using System;
using System.Globalization;

public class Example
{
    public static void Main()
    {
         var enUs = new CultureInfo("en-US");
        var japaneseCal = new JapaneseCalendar();
        var jaJp = new CultureInfo("ja-JP");
        jaJp.DateTimeFormat.Calendar = japaneseCal;
        string heiseiEra = "平成";

        var date = japaneseCal.ToDateTime(1, 8, 18, 0, 0, 0, 0, GetEraIndex(heiseiEra));
        FormattableString fmt = $"{date:D}";
        Console.WriteLine($"Japanese calendar date: {fmt.ToString(jaJp)} (Gregorian: {fmt.ToString(enUs)})");

        int GetEraIndex(string eraName)
        {
           foreach (var ctr in japaneseCal.Eras)
              if (jaJp.DateTimeFormat.GetEraName(ctr) == eraName)
                 return ctr;

           return 0;
        }
    }
}
// The example displays the following output:
//    Japanese calendar date: 平成元年8月18日 (Gregorian: Friday, August 18, 1989)
Imports System.Globalization

Module Program
    Dim jaJp As CultureInfo
    Dim japaneseCal As Calendar

    Sub Main()
        Dim enUs = New CultureInfo("en-US")
        japaneseCal = New JapaneseCalendar()
        jaJp = New CultureInfo("ja-JP")
        jaJp.DateTimeFormat.Calendar = japaneseCal
        Dim heiseiEra = "平成"

        Dim dat = japaneseCal.ToDateTime(1, 8, 18, 0, 0, 0, 0, GetEraIndex(heiseiEra))
        Dim fmt As FormattableString = $"{dat:D}"
        Console.WriteLine($"Japanese calendar date: {fmt.ToString(jaJp)} (Gregorian: {fmt.ToString(enUs)})")
    End Sub

    Private Function GetEraIndex(eraName As String) As Integer
        For Each ctr In japaneseCal.Eras
            If jaJp.DateTimeFormat.GetEraName(ctr) = eraName Then
                Return ctr
            End If
        Next
        Return 0
    End Function
End Module
' The example displays the following output:
'    Japanese calendar date: 平成元年8月18日 (Gregorian: Friday, August 18, 1989)

Pokud je toto chování nežádoucí v operacích formátování, můžete obnovit předchozí chování, které vždy představuje první rok éry jako "1" místo "Gannen", a to v závislosti na verzi .NET:

  • .NET Core: do konfiguračního souboru .netcore.runtime.json přidejte následující:

    "runtimeOptions": {
      "configProperties": {
          "Switch.System.Globalization.FormatJapaneseFirstYearAsANumber": true
      }
    }
    
  • rozhraní .NET Framework 4.6 nebo novější: v souboru app.config nastavte následující přepínač AppContext:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <runtime>
        <AppContextSwitchOverrides value="Switch.System.Globalization.FormatJapaneseFirstYearAsANumber=true" />
      </runtime>
    </configuration>
    
  • rozhraní .NET Framework 4.5.2 nebo starší: Nastavte následující hodnotu registru:

    Hodnota
    klíč HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AppContext
    Položka Přepínač.System.Globalizace.FormátovatPrvníJaponskýRokJakoČíslo
    Typ REG_SZ
    Hodnota pravda

Při zakázané podpoře gannenu při operacích formátování se v předchozím příkladu zobrazí následující výstup:

Japanese calendar date: 平成1年8月18日 (Gregorian: Friday, August 18, 1989)

Rozhraní .NET bylo také aktualizováno, aby operace analýzy data a času podporovaly řetězce, které obsahují rok reprezentovaný jako "1" nebo Gannen. I když byste to neměli dělat, můžete předchozí chování obnovit, abyste jako první rok éry rozpoznali pouze "1". Můžete to provést následujícím způsobem v závislosti na verzi .NET:

  • .NET Core: do konfiguračního souboru .netcore.runtime.json přidejte následující:

    "runtimeOptions": {
      "configProperties": {
          "Switch.System.Globalization.EnforceLegacyJapaneseDateParsing": true
      }
    }
    
  • rozhraní .NET Framework 4.6 nebo novější: v souboru app.config nastavte následující přepínač AppContext:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <runtime>
        <AppContextSwitchOverrides value="Switch.System.Globalization.EnforceLegacyJapaneseDateParsing=true" />
      </runtime>
    </configuration>
    
  • rozhraní .NET Framework 4.5.2 nebo starší: Nastavte následující hodnotu registru:

    Hodnota
    klíč HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AppContext
    Položka Switch.System.Globalization.EnforceLegacyJapaneseDateParsing
    Typ REG_SZ
    Hodnota pravda

Viz také