Partager via


Utiliser des calendriers

Bien qu’une valeur de date et d’heure représente un moment dans l’heure, sa représentation sous forme de chaîne respecte la culture et dépend des conventions utilisées pour afficher les valeurs de date et d’heure par une culture spécifique et sur le calendrier utilisé par cette culture. Cette rubrique explore la prise en charge des calendriers dans .NET et traite de l’utilisation des classes de calendrier lors de l’utilisation des valeurs de date.

Calendriers dans .NET

Tous les calendriers dans .NET dérivent de la System.Globalization.Calendar classe, qui fournit l’implémentation du calendrier de base. L’une des classes qui héritent de la Calendar classe est la EastAsianLunisolarCalendar classe, qui est la classe de base pour tous les calendriers lunisolar. .NET inclut les implémentations de calendrier suivantes :

Un calendrier peut être utilisé de deux façons :

  • En tant que calendrier utilisé par une culture spécifique. Chaque CultureInfo objet a un calendrier actuel, qui est le calendrier que l’objet utilise actuellement. Les représentations sous forme de chaîne de toutes les valeurs de date et d’heure reflètent automatiquement la culture actuelle et son calendrier actuel. En règle générale, le calendrier actuel est le calendrier par défaut de la culture. CultureInfo les objets ont également des calendriers facultatifs, qui incluent des calendriers supplémentaires que la culture peut utiliser.

  • En tant que calendrier autonome indépendant d’une culture spécifique. Dans ce cas, Calendar les méthodes sont utilisées pour exprimer des dates en tant que valeurs qui reflètent le calendrier.

Notez que six classes de calendrier – ChineseLunisolarCalendar, , JapaneseLunisolarCalendarJulianCalendar, KoreanLunisolarCalendar, PersianCalendaret TaiwanLunisolarCalendar – peuvent être utilisées uniquement comme calendriers autonomes. Ils ne sont utilisés par aucune culture comme calendrier par défaut ou comme calendrier facultatif.

Calendriers et cultures

Chaque culture a un calendrier par défaut, qui est défini par la CultureInfo.Calendar propriété. La CultureInfo.OptionalCalendars propriété retourne un tableau d’objets Calendar qui spécifie tous les calendriers pris en charge par une culture particulière, y compris le calendrier par défaut de cette culture.

L'exemple suivant illustre les propriétés CultureInfo.Calendar et CultureInfo.OptionalCalendars. Il crée des CultureInfo objets pour les cultures thaïlandaises (Thaïlande) et japonais (Japon) et affiche leurs calendriers par défaut et facultatifs. Notez que dans les deux cas, le calendrier par défaut de la culture est également inclus dans la CultureInfo.OptionalCalendars collection.

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)

Le calendrier actuellement utilisé par un objet particulier CultureInfo est défini par la propriété DateTimeFormatInfo.Calendar de la culture. Un objet DateTimeFormatInfo de la culture est retourné par la propriété CultureInfo.DateTimeFormat. Lorsqu’une culture est créée, sa valeur par défaut est identique à la valeur de la CultureInfo.Calendar propriété. Toutefois, vous pouvez remplacer le calendrier actuel de la culture par n’importe quel calendrier contenu dans le tableau retourné par la CultureInfo.OptionalCalendars propriété. Si vous essayez de définir le calendrier actuel à un calendrier qui n'est pas compris dans la valeur d'une propriété CultureInfo.OptionalCalendars, une ArgumentException est levée.

L’exemple suivant modifie le calendrier utilisé par la culture arabe (Arabie saoudite). Il instancie d’abord une DateTime valeur et l’affiche à l’aide de la culture actuelle , qui, dans ce cas, est l’anglais (États-Unis) et le calendrier de la culture actuelle (qui, dans ce cas, est le calendrier grégorien). Ensuite, il modifie la culture actuelle en arabe (Arabie saoudite) et affiche la date à l’aide de son calendrier par défaut Um Al-Qura. Il appelle ensuite la CalendarExists méthode pour déterminer si le calendrier Hijri est pris en charge par la culture arabe (Arabie saoudite). Étant donné que le calendrier est pris en charge, il modifie le calendrier actuel en Hijri et affiche à nouveau la date. Notez que dans chaque cas, la date s’affiche à l’aide du calendrier actuel de la culture actuelle.

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

Dates et calendriers

À l’exception des constructeurs qui incluent un paramètre de type Calendar et autorisent les éléments d’une date (c’est-à-dire le mois, le jour et l’année) à refléter les valeurs dans un calendrier désigné, les DateTime valeurs et DateTimeOffset les valeurs sont toujours basées sur le calendrier grégorien. Cela signifie, par exemple, que la propriété DateTime.Year retourne l’année dans le calendrier grégorien, et que la propriété DateTime.Day retourne le jour du mois dans le calendrier grégorien.

Importante

Il est important de se rappeler qu’il existe une différence entre une valeur de date et sa représentation sous forme de chaîne. L’ancien est basé sur le calendrier grégorien ; ce dernier est basé sur le calendrier actuel d’une culture spécifique.

L’exemple suivant illustre cette différence entre les propriétés DateTime et leurs méthodes correspondantes Calendar. Dans l’exemple, la culture actuelle est arabe (Égypte) et le calendrier actuel est Um Al-Qura. Une DateTime valeur est définie sur le quinzeième jour du septième mois de 2011. Il est clair que cela est interprété comme une date grégorienne, car ces mêmes valeurs sont retournées par la DateTime.ToString(String, IFormatProvider) méthode lorsqu’elle utilise les conventions de la culture invariante. La représentation sous forme de chaîne de la date mise en forme à l’aide des conventions de la culture actuelle est 14/08/32, qui est la date équivalente dans le calendrier Um Al Qura. Ensuite, les membres de DateTime et Calendar sont utilisés pour retourner le jour, le mois et l’année de la valeur DateTime. Dans chaque cas, les valeurs retournées par DateTime les membres reflètent les valeurs du calendrier grégorien, tandis que les valeurs retournées par UmAlQuraCalendar les membres reflètent les valeurs du calendrier 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

Instancier des dates en fonction d’un calendrier

Étant donné que DateTime les DateTimeOffset valeurs sont basées sur le calendrier grégorien, vous devez appeler un constructeur surchargé qui inclut un paramètre de type Calendar pour instancier une valeur de date si vous souhaitez utiliser les valeurs jour, mois ou année d’un autre calendrier. Vous pouvez également appeler l’une des surcharges de la méthode d’un calendrier spécifique Calendar.ToDateTime pour instancier un objet DateTime en fonction des valeurs d’un calendrier particulier.

L’exemple suivant instancie une valeur en passant un DateTime objet à un HebrewCalendar constructeur et instancie DateTime une deuxième DateTime valeur en appelant la HebrewCalendar.ToDateTime(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32) méthode. Étant donné que les deux valeurs sont créées avec des valeurs identiques à partir du calendrier hébreu, l’appel à la DateTime.Equals méthode indique que les deux DateTime valeurs sont égales.

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

Représenter des dates dans le calendrier actuel

Les méthodes de mise en forme de date et d’heure utilisent toujours le calendrier actuel lors de la conversion de dates en chaînes. Cela signifie que la représentation sous forme de chaîne de l’année, du mois et du jour du mois reflètent le calendrier actuel et ne reflètent pas nécessairement le calendrier grégorien.

L’exemple suivant montre comment le calendrier actuel affecte la représentation sous forme de chaîne d’une date. Il remplace la culture actuelle par le chinois (traditionnel, Taïwan) et instancie une valeur de date. Il affiche ensuite le calendrier actuel et la date, modifie le calendrier TaiwanCalendaractuel et affiche à nouveau le calendrier actuel et la date. La première fois que la date est affichée, elle est représentée sous forme de date dans le calendrier grégorien. La deuxième fois qu’elle est affichée, elle est représentée sous forme de date dans le calendrier taïwanais.

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

Représenter des dates dans un calendrier non actif

Pour représenter une date à l’aide d’un calendrier qui n’est pas le calendrier actuel d’une culture particulière, vous devez appeler des méthodes de cet Calendar objet. Par exemple, les méthodes Calendar.GetYear, Calendar.GetMonth et Calendar.GetDayOfMonth convertissent l'année, le mois et le jour en valeurs qui reflètent un calendrier particulier.

Avertissement

Étant donné que certains calendriers ne sont pas des calendriers facultatifs d’une culture, la représentation des dates dans ces calendriers nécessite toujours d’appeler des méthodes de calendrier. Cela est vrai de tous les calendriers qui dérivent des EastAsianLunisolarCalendarclasses , JulianCalendaret PersianCalendar .

L’exemple suivant utilise un JulianCalendar objet pour instancier une date, le 9 janvier 1905, dans le calendrier Julian. Lorsque cette date est affichée à l’aide du calendrier par défaut (grégorien), elle est représentée comme le 22 janvier 1905. Les appels à des méthodes individuelles JulianCalendar permettent de représenter la date dans le calendrier Julian.

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

Calendriers et plages de dates

La date la plus ancienne prise en charge par un calendrier est indiquée par la propriété de ce Calendar.MinSupportedDateTime calendrier. Pour la GregorianCalendar classe, cette date est le 1er janvier 0001 C.E. La plupart des autres calendriers dans .NET prennent en charge une date ultérieure. Le fait d'essayer d'utiliser une valeur de date et d'heure qui précède la première date prise en charge d'un calendrier lève une exception ArgumentOutOfRangeException.

Toutefois, il existe une exception importante. La valeur par défaut (non initialisée) d'un DateTime objet et d'un DateTimeOffset objet sont égaux à la valeur de GregorianCalendar.MinSupportedDateTime. Si vous essayez de mettre en forme cette date dans un calendrier qui ne prend pas en charge le 1er janvier 0001 C.E. et que vous ne fournissez pas de spécificateur de format, la méthode de mise en forme utilise le spécificateur de format « s » (modèle de date/heure triable) au lieu du spécificateur de format « G » (modèle de date/heure général). Par conséquent, l’opération de mise en forme ne lève pas d’exception ArgumentOutOfRangeException . Au lieu de cela, elle retourne la date non prise en charge. Ceci est illustré dans l’exemple suivant, qui affiche la valeur de DateTime.MinValue lorsque la culture actuelle est définie sur le japonais (Japon) avec le calendrier japonais, et sur l'arabe (Égypte) avec le calendrier Um Al Qura. Il définit également la culture actuelle sur Anglais (États-Unis) et appelle la méthode DateTime.ToString(IFormatProvider) à chacun de ces objets CultureInfo. Dans chaque cas, la date est affichée à l’aide du modèle date/heure triable.

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

Travailler avec les époques

Les calendriers divisent généralement les dates en ères. Toutefois, les Calendar classes dans .NET ne prennent pas en charge chaque ère définie par un calendrier, et la Calendar plupart des classes ne prennent en charge qu’une seule ère. Seules les JapaneseCalendar et les JapaneseLunisolarCalendar classes prennent en charge plusieurs ères.

Importante

L’ère Reiwa, une nouvelle ère dans les JapaneseCalendar et JapaneseLunisolarCalendar, commence le 1er mai 2019. Cette modification affecte toutes les applications qui utilisent ces calendriers. Pour plus d’informations, consultez les articles suivants :

Une ère dans la plupart des calendriers désigne une période extrêmement longue. Dans le calendrier grégorien, par exemple, l’ère actuelle s’étend sur plus de deux millénaires. Pour JapaneseCalendar et JapaneseLunisolarCalendar, les deux calendriers qui prennent en charge plusieurs ères, ce n’est pas le cas. Une ère correspond à la période du règne d’un empereur. La prise en charge de plusieurs ères, en particulier lorsque la limite supérieure de l’ère actuelle est inconnue, pose des défis particuliers.

Époques et noms d'époques

Dans .NET, les entiers qui représentent les ères prises en charge par une implémentation de calendrier particulière sont stockées dans l’ordre inverse dans le Calendar.Eras tableau. L’ère actuelle (qui est l’ère avec la dernière plage de temps) est à l’index zéro, et pour Calendar les classes qui prennent en charge plusieurs ères, chaque index successif reflète l’ère précédente. La propriété statique Calendar.CurrentEra définit l’index de l’ère actuelle dans le Calendar.Eras tableau ; il s’agit d’une constante dont la valeur est toujours égale à zéro. Les classes individuelles Calendar incluent également des champs statiques qui retournent la valeur de l’ère actuelle. Elles sont répertoriées dans le tableau suivant.

Classe de calendrier Champ d'ère actuelle
ChineseLunisolarCalendar ChineseEra
GregorianCalendar ADEra
HebrewCalendar HebrewEra
HijriCalendar HijriEra
JapaneseLunisolarCalendar JapaneseEra
JulianCalendar JulianEra
KoreanCalendar KoreanEra
KoreanLunisolarCalendar GregorianEra
PersianCalendar PersianEra
ThaiBuddhistCalendar ThaiBuddhistEra
UmAlQuraCalendar UmAlQuraEra

Le nom qui correspond à un numéro d'ère particulier peut être récupéré en passant le numéro d'ère à la méthode DateTimeFormatInfo.GetEraName ou DateTimeFormatInfo.GetAbbreviatedEraName. L'exemple suivant appelle ces méthodes pour extraire des informations sur la prise en charge de l'ère dans la classe GregorianCalendar. Il affiche la date de calendrier grégorien qui correspond au 1er janvier de la deuxième année de l’ère actuelle, ainsi que la date de calendrier grégorien qui correspond au 1er janvier de la deuxième année de chaque ère de calendrier japonaise prise en charge.

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

En outre, la chaîne de format de date et d’heure personnalisée « g » inclut le nom d’ère d’un calendrier dans la représentation sous forme de chaîne d’une date et d’une heure. Pour plus d’informations, consultez Chaînes de format de date et d’heure personnalisé.

Instancier une date avec une ère

Pour les deux Calendar classes qui prennent en charge plusieurs ères, une date qui se compose d’une année, d’un mois et d’un jour donnés de la valeur du mois peut être ambiguë. Par exemple, toutes les ères prises en charge par le JapaneseCalendar ont des années dont le numéro est 1. En règle générale, si une ère n’est pas spécifiée, les méthodes date et heure et calendrier supposent que les valeurs appartiennent à l’ère actuelle. Cela est vrai pour les constructeurs DateTime et DateTimeOffset qui incluent des paramètres de type Calendar, ainsi que pour les méthodes JapaneseCalendar.ToDateTime et JapaneseLunisolarCalendar.ToDateTime. L’exemple suivant instancie une date qui représente le 1er janvier de la deuxième année d’une ère non spécifiée. Si vous exécutez l’exemple lorsque l’ère Reiwa est l’ère actuelle, la date est interprétée comme la deuxième année de l’ère Reiwa. L’ère, 令和, précède l’année dans la chaîne retournée par la DateTime.ToString(String, IFormatProvider) méthode et correspond au 1er janvier 2020 dans le calendrier grégorien. (L’ère Reiwa commence en 2019 du calendrier grégorien.)

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

Toutefois, si l’ère change, l’intention de ce code devient ambiguë. La date est-elle destinée à représenter la deuxième année de l’ère actuelle, ou est-elle destinée à représenter la deuxième année de l’ère Heisei ? Il existe deux façons d’éviter cette ambiguïté :

  • Instanciez la valeur de date et d’heure à l’aide de la classe par défaut GregorianCalendar . Vous pouvez ensuite utiliser le calendrier japonais ou le calendrier lunisolar japonais pour la représentation sous forme de chaîne de dates, comme l’illustre l’exemple suivant.

    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
    
    
    
  • Appelez une méthode de date et d’heure qui spécifie explicitement une ère. Cela inclut les méthodes suivantes :

    L’exemple suivant utilise trois de ces méthodes pour instancier une date et une heure dans l’ère Meiji, qui a commencé le 8 septembre 1868 et s’est terminée le 29 juillet 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)
    

Conseil / Astuce

Lorsque vous utilisez des calendriers qui prennent en charge plusieurs ères, utilisez toujours la date grégorienne pour instancier une date ou spécifiez l’ère lorsque vous instanciez une date et une heure en fonction de ce calendrier.

En spécifiant une ère à la ToDateTime(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32) méthode, vous fournissez l’index de l’ère dans la propriété du Eras calendrier. Toutefois, pour les calendriers dont les ères sont sujettes à modification, ces index ne sont pas des valeurs constantes ; l’ère actuelle est à l’index 0, et l’ère la plus ancienne est à l’index Eras.Length - 1. Lorsqu’une nouvelle ère est ajoutée à un calendrier, les index des ères précédentes augmentent d’un. Vous pouvez fournir l’index d’ère approprié comme suit :

  • Pour les dates de l’ère actuelle, utilisez toujours la propriété du CurrentEra calendrier.

  • Pour les dates d’une ère spécifiée, utilisez la DateTimeFormatInfo.GetEraName méthode pour récupérer l’index correspondant à un nom d’ère spécifié. Cela nécessite que le JapaneseCalendar soit le calendrier actuel de l'objet CultureInfo qui représente la culture ja-JP. (Cette technique fonctionne également pour le JapaneseLunisolarCalendar , car elle prend en charge les mêmes ères que le JapaneseCalendar.) L’exemple précédent illustre cette approche.

Calendriers, époques et fourchettes de dates : Contrôles assouplis des intervalles

Tout comme les calendriers individuels ont des plages de dates prises en charge, les ères dans les classes JapaneseCalendar et JapaneseLunisolarCalendar ont également des plages prises en charge. Auparavant, .NET utilisait des contrôles de plage d’ère stricts pour s’assurer qu’une date spécifique à l’ère était comprise dans la plage de cette ère. Autrement dit, si une date est en dehors de la plage de l’ère spécifiée, la méthode lève un ArgumentOutOfRangeException. Actuellement, .NET utilise la vérification à intervalles souples par défaut. Les mises à jour apportées à toutes les versions de .NET ont introduit des vérifications assouplies des plages d’ère ; le fait d'essayer d’instancier une date propre à une ère qui dépasse la plage de l’ère spécifiée déborde vers l’ère suivante, et aucune exception n’est levée.

L’exemple suivant tente d’instancier une date de la 65e année de l’ère Showa, qui a commencé le 25 décembre 1926 et s’est terminée le 7 janvier 1989. Cette date correspond au 9 janvier 1990, ce qui est en dehors de la période de l'ère Showa dans le JapaneseCalendar Comme le montre la sortie de l’exemple, la date affichée par l’exemple est le 9 janvier 1990, dans la deuxième année de l’ère Heisei.

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

Si les vérifications de plage assouplies ne sont pas souhaitables, vous pouvez restaurer des contrôles de plage stricts de plusieurs façons, en fonction de la version de .NET sur laquelle votre application s’exécute :

  • .NET Core : Ajoutez les éléments suivants au fichier de configuration.netcore.runtime.json :

    "runtimeOptions": {
      "configProperties": {
          "Switch.System.Globalization.EnforceJapaneseEraYearRanges": true
      }
    }
    
  • .NET Framework 4.6 ou version ultérieure : Définissez le commutateur AppContext suivant dans le fichier app.config :

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <runtime>
        <AppContextSwitchOverrides value="Switch.System.Globalization.EnforceJapaneseEraYearRanges=true" />
      </runtime>
    </configuration>
    
  • .NET Framework 4.5.2 ou version antérieure : Définissez la valeur de Registre suivante :

    Valeur
    Clé HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AppContext
    Entrée Switch.System.Globalization.EnforceJapaneseEraYearRanges
    Type REG_SZ
    Valeur vrai

Avec les vérifications de plage strictes activées, l’exemple précédent lève un ArgumentOutOfRangeException et affiche la sortie suivante :

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

Représenter des dates dans des calendriers avec plusieurs ères

Si un Calendar objet prend en charge les ères et est le calendrier actuel d’un CultureInfo objet, l’ère est incluse dans la représentation sous forme de chaîne d’une valeur de date et d’heure pour la date et l’heure complètes, les dates longues et les modèles de dates courtes. L’exemple suivant affiche ces modèles de date lorsque la culture actuelle est japon (japonais) et que le calendrier actuel est le calendrier japonais.

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 

Avertissement

La JapaneseCalendar classe est la seule classe de calendrier dans .NET qui prend en charge les dates dans plusieurs ères et qui peut être le calendrier actuel d’un CultureInfo objet , en particulier d’un CultureInfo objet qui représente la culture japonaise (Japon).

Pour tous les calendriers, le spécificateur de format personnalisé « g » inclut l’ère dans la chaîne de résultat. L’exemple suivant utilise la chaîne de format personnalisé « MM-dd-aaaa g » pour inclure l’ère dans la chaîne de résultat lorsque le calendrier actuel est le calendrier grégorien.

   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.      

Dans les cas où la représentation sous forme de chaîne d’une date est exprimée dans un calendrier qui n’est pas le calendrier actuel, la Calendar classe inclut une Calendar.GetEra méthode qui peut être utilisée avec le Calendar.GetYear, Calendar.GetMonthet Calendar.GetDayOfMonth les méthodes pour indiquer sans ambiguïté une date ainsi que l’ère à laquelle elle appartient. L’exemple suivant utilise la JapaneseLunisolarCalendar classe pour fournir une illustration. Toutefois, notez que l’inclusion d’un nom ou d’une abréviation explicite au lieu d’un entier pour l’ère dans la chaîne de résultat nécessite d’instancier un DateTimeFormatInfo objet et de rendre JapaneseCalendar son calendrier actuel. (Le JapaneseLunisolarCalendar calendrier ne peut pas être le calendrier actuel d’une culture, mais dans ce cas, les deux calendriers partagent les mêmes ères.)

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

Dans les calendriers japonais, la première année d’une ère est appelée Gannen (元年). Par exemple, au lieu d’Heisei 1, la première année de l’ère Heisei peut être décrite comme Heisei Gannen. .NET adopte cette convention dans les opérations de mise en forme pour les dates et heures mises en forme avec les chaînes de format de date et d’heure standard ou personnalisées suivantes lorsqu’elles sont utilisées avec un CultureInfo objet qui représente la culture Japanese-Japan ( »ja-JP« ) avec la JapaneseCalendar classe :

Par exemple, l’exemple suivant affiche une date dans la première année de l’ère Heisei dans le 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)

Si ce comportement n’est pas souhaitable dans les opérations de mise en forme, vous pouvez restaurer le comportement précédent, qui représente toujours la première année d’une ère comme « 1 » plutôt que « Gannen », en procédant comme suit, en fonction de la version de .NET :

  • .NET Core : Ajoutez les éléments suivants au fichier de configuration.netcore.runtime.json :

    "runtimeOptions": {
      "configProperties": {
          "Switch.System.Globalization.FormatJapaneseFirstYearAsANumber": true
      }
    }
    
  • .NET Framework 4.6 ou version ultérieure : Définissez le commutateur AppContext suivant dans le fichier app.config :

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <runtime>
        <AppContextSwitchOverrides value="Switch.System.Globalization.FormatJapaneseFirstYearAsANumber=true" />
      </runtime>
    </configuration>
    
  • .NET Framework 4.5.2 ou version antérieure : Définissez la valeur de Registre suivante :

    Valeur
    Clé HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AppContext
    Entrée Switch.System.Globalization.FormatJapaneseFirstYearAsANumber
    Type REG_SZ
    Valeur vrai

Avec la prise en charge du gannen dans les opérations de mise en forme désactivées, l’exemple précédent affiche la sortie suivante :

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

.NET a également été mis à jour afin que les opérations d’analyse de date et d’heure prennent en charge les chaînes qui contiennent l’année représentée comme « 1 » ou Gannen. Bien que vous n’ayez pas besoin de le faire, vous pouvez restaurer le comportement précédent pour reconnaître uniquement « 1 » comme la première année d’une ère. Vous pouvez le faire comme suit, en fonction de la version de .NET :

  • .NET Core : Ajoutez les éléments suivants au fichier de configuration.netcore.runtime.json :

    "runtimeOptions": {
      "configProperties": {
          "Switch.System.Globalization.EnforceLegacyJapaneseDateParsing": true
      }
    }
    
  • .NET Framework 4.6 ou version ultérieure : Définissez le commutateur AppContext suivant dans le fichier app.config :

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <runtime>
        <AppContextSwitchOverrides value="Switch.System.Globalization.EnforceLegacyJapaneseDateParsing=true" />
      </runtime>
    </configuration>
    
  • .NET Framework 4.5.2 ou version antérieure : Définissez la valeur de Registre suivante :

    Valeur
    Clé HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AppContext
    Entrée Switch.System.Globalization.EnforceLegacyJapaneseDateParsing
    Type REG_SZ
    Valeur vrai

Voir aussi