Работа с календарями

Несмотря на то что значение даты и времени обозначает момент во времени, его строковое представление зависит от конкретного языка и региональных параметров. На него влияют как принятые стандарты обозначения даты и времени, так и используемый календарь. В этом разделе описывается поддержка календарей в .NET Framework и обсуждается использование классов календарей при работе со значениями дат.

Календари в .NET Framework

В .NET Framework все календари наследуются от класса System.Globalization.Calendar, предоставляющего базовую реализацию календаря. Одним из классов, наследующих от класса Calendar, является класс EastAsianLunisolarCalendar — базовый класс для всех лунно-солнечных календарей. Платформа .NET Framework содержит следующие реализации календарей.

  • ChineseLunisolarCalendar. Представляет китайский лунно-солнечный календарь.

  • GregorianCalendar. Представляет григорианский календарь. Этот календарь, в свою очередь, разделяется на подтипы (такие как арабский и ближневосточный французский), определяемые перечислением System.Globalization.GregorianCalendarTypes. Свойство GregorianCalendar.CalendarType определяет подтип григорианского календаря.

  • HebrewCalendar. Представляет еврейский календарь.

  • HijriCalendar. Представляет календарь Хиджра.

  • JapaneseCalendar. Представляет японский календарь.

  • JapaneseLunisolarCalendar. Представляет японский лунно-солнечный календарь.

  • JulianCalendarПредставляет юлианский календарь.

  • KoreanCalendar. Представляет корейский календарь.

  • KoreanLunisolarCalendar. Представляет корейский лунно-солнечный календарь.

  • PersianCalendar. Представляет персидский календарь.

  • TaiwanCalendar. Представляет тайваньский календарь.

  • TaiwanLunisolarCalendar. Представляет тайваньский лунно-солнечный календарь.

  • ThaiBuddhistCalendar. Представляет тай-буддистский календарь.

  • UmAlQuraCalendar. Представляет саудовский календарь.

Календарь можно использовать одним из двух способов:

  • Как календарь, используемый для конкретных языка и региональных параметров. Каждый объект CultureInfo имеет текущий календарь, то есть календарь, который объект использует в настоящий момент. Строковое представление значений даты и времени автоматически отражает используемые язык и региональные параметры и текущий календарь. Обычно текущий календарь является календарем по умолчанию для языка и региональных параметров. Объекты CultureInfo также имеют дополнительные календари, которые могут использоваться для языка и региональных параметров.

  • Как самостоятельный календарь, не зависящий от конкретных языка и региональных параметров. В таком случае методы Calendar используются для выражения дат и значений календаря.

Обратите внимание, что шесть классов календаря (ChineseLunisolarCalendar, JapaneseLunisolarCalendar, JulianCalendar, KoreanLunisolarCalendar, PersianCalendar и TaiwanLunisolarCalendar) можно использовать только как самостоятельные календари. Никакие языки и региональные параметры не используют их как календари по умолчанию или как дополнительные календари.

Календари и языки и региональные параметры

Для любого языка и региональных параметров есть календарь по умолчанию, определенный свойством CultureInfo.Calendar. Свойство CultureInfo.OptionalCalendars возвращает массив объектов Calendar, содержащий все календари, поддерживаемые конкретным языком и региональными параметрами, включая календарь по умолчанию для этого языка и региональных параметров.

Следующий пример иллюстрирует свойства CultureInfo.Calendar и CultureInfo.OptionalCalendars. В нем создаются объекты CultureInfo для языков и региональных параметров "Тайский (Таиланд)" и "Японский (Япония)", а также выводятся их календари по умолчанию и дополнительные календари. Обратите внимание, что в обоих случаях календарь по умолчанию для языка и региональных параметров также включается в коллекцию CultureInfo.OptionalCalendars.

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)
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 {0} culture:", ci.Name);

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

      if (defaultCalendar is GregorianCalendar)
         Console.WriteLine(" ({0})", 
                           ((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)

Календарь, используемый в настоящий момент каким-либо конкретным объектом CultureInfo, определяется свойством DateTimeFormatInfo.Calendar языка и региональных параметров. Объект DateTimeFormatInfo языка и региональных параметров возвращается свойством CultureInfo.DateTimeFormat. При создании языка и региональных параметров значение по умолчанию совпадает со значением свойства CultureInfo.Calendar. Однако текущий календарь языка и региональных параметров можно изменить на любой календарь из массива, возвращаемого свойством CultureInfo.OptionalCalendars. Если попытаться изменить текущий календарь на календарь, не входящий в значение свойства CultureInfo.OptionalCalendars, будет создано исключение ArgumentException.

В следующем примере изменяется календарь, используемый для языка и региональных параметров "Арабский (Саудовская Аравия)". Сперва создается значение DateTime и отображается с использованием текущего языка и региональных параметров (в данном случае "Английский (США)") и текущего календаря для языка и региональных параметров (в данном случае григорианского календаря). Затем текущий язык и региональные параметры изменяются на "Арабский (Саудовская Аравия)" и дата отображается с использованием календаря по умолчанию — саудовского календаря. Затем вызывается метод CalendarExists, чтобы определить, поддерживается ли календарь Хиджра языком и региональными параметрами "Арабский (Саудовская Аравия)". Поскольку этот календарь поддерживается, текущий календарь изменяется на календарь Хиджра и дата отображается снова. Обратите внимание, что в обоих случаях дата отображается с использованием текущего календаря текущего языка и региональных параметров.

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
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: {0}", 
                        CultureInfo.CurrentCulture.Name);
      Console.WriteLine("Current Calendar: {0}", 
                        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

Даты и календари

За исключением конструкторов, содержащих параметры типа Calendar и допускающих отображение элементов даты (месяц, день, год) по указанному календарю, значения DateTime и DateTimeOffset всегда приводятся по григорианскому календарю. Это означает, например, что свойство DateTime.Year возвращает год по григорианскому календарю, а свойство DateTime.Day возвращает день месяца по григорианскому календарю.

Важное примечаниеВажно

Важно помнить, что есть разница между значением даты и его строковым представлением.Первое основывается на григорианском календаре, а последнее — на текущем календаре конкретного языка и региональных параметров.

Следующий пример иллюстрирует разницу между свойствами DateTime и их соответствующими методами Calendar. В этом примере текущий язык и региональные параметры — "Арабский (Египет)", а текущий календарь — саудовский. Задано значение DateTime, обозначающее пятнадцатый день седьмого месяца 2011 года. Очевидно, что это значение интерпретируется как дата григорианского календаря, поскольку именно эти значения возвращаются методом DateTime.ToString(String, IFormatProvider) при использовании стандартов инвариантного языка и региональных параметров. Строковое представление даты форматируется по стандартам текущего языка и региональных параметров и выглядит как 14/08/32, указывая соответствующую дату по саудовскому календарю. Затем члены DateTime и Calendar используются для возврата дня, месяца и года значения DateTime. В любом случае, значения, возвращаемые членами DateTime, отражают значения по григорианскому календарю, а значения, возвращаемые членами UmAlQuraCalendar отражают значения по саудовскому календарю.

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
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: {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();
   }

   private static void DisplayCurrentInfo()
   {
      Console.WriteLine("Current Culture: {0}", 
                        CultureInfo.CurrentCulture.Name);
      Console.WriteLine("Current Calendar: {0}", 
                        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

Создание дат на основе календаря

Поскольку значения DateTime и DateTimeOffset основываются на григорианском календаре, необходимо вызвать перегруженный конструктор, включающий параметр типа Calendar, для создания значения даты, если требуется использовать значение дня, месяца или года по другому календарю. Можно также вызвать одну из перегрузок метода Calendar.ToDateTime конкретного календаря для создания объекта DateTime на основе значений конкретного календаря.

В следующем примере первое значение DateTime создается путем передачи объекта HebrewCalendar конструктору DateTime, а второе значение DateTime создается путем вызова метода HebrewCalendar.ToDateTime(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32). Поскольку эти два значения создаются с одинаковыми значениями еврейского календаря, вызов метода DateTime.Equals показывает, что два значения DateTime совпадают.

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

Представление дат текущего календаря

Методы форматирования даты и времени при преобразовании дат в строки всегда используют текущий календарь. Это значит, что строковое представление года, месяца и дня месяца отражают текущий календарь, а не обязательно григорианский календарь.

В следующем примере показано, как текущий календарь влияет на строковое представление даты. Текущий язык и региональные параметры изменяются на "Китайский (традиционное письмо, Тайвань)", затем создается значение даты. Затем отображается текущий календарь и дата, текущий календарь изменяется на TaiwanCalendar, текущий календарь и дата отображаются снова. При первом отображении даты она представляется как дата григорианского календаря. При отображении даты во второй раз она представляется как дата тайваньского календаря.

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
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: {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"));
   }
}
// The example displays the following output:
//    Current calendar: System.Globalization.GregorianCalendar
//    2011/1/16
//    Current calendar: System.Globalization.TaiwanCalendar
//    100/1/16

Представление дат не текущего календаря

Чтобы представить дату с помощью календаря, который не является текущим для языка и региональных параметров, необходимо вызвать методы нужного объекта Calendar. Например, методы Calendar.GetYear, Calendar.GetMonth и Calendar.GetDayOfMonth преобразуют значения года, месяца и дня в значения, соответствующие определенному календарю.

Предупреждающее замечаниеВнимание

Поскольку некоторые календари не являются дополнительными календарями ни для какого языка и региональных параметров, указание дат по этим календарям всегда требует вызова методов календаря.Это верно для всех календарей, унаследованных от классов EastAsianLunisolarCalendar, JulianCalendar и PersianCalendar.

В следующем примере используется объект JulianCalendar для создания даты 9 января 1905 года по юлианскому календарю. При отображении этой даты по календарю по умолчанию (григорианскому), она представляется как 22 января 1905 года. Вызов отдельных методов JulianCalendar позволяет отобразить дату по юлианскому календарю.

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

Работа с эрами

В календарях даты обычно разделены на эры. Однако классы Calendar в .NET Framework не поддерживают все определенные календарем эры, а большинство классов Calendar поддерживает только одну эру. Только классы JapaneseCalendar и JapaneseLunisolarCalendar поддерживают несколько эр.

Эры и названия эр

В .NET Framework целые числа, обозначающие эры, поддерживаемые реализацией конкретного календаря, хранятся в обратном порядке в массиве Calendar.Eras. Текущая эра хранится с индексом 0, а для классов Calendar, поддерживающих несколько эр, каждый последующий индекс обозначает предыдущую эру. Статическое свойство Calendar.CurrentEra определяет индекс текущей эры в массиве Calendar.Eras; это константа, значение которой всегда ноль. Отдельные классы Calendar также включают статические поля, возвращающие значение текущей эры. Они перечислены в следующей таблице.

Класс календаря

Поле текущей эры

ChineseLunisolarCalendar

ChineseEra

GregorianCalendar

ADEra

HebrewCalendar

HebrewEra

HijriCalendar

HijriEra

JapaneseLunisolarCalendar

JapaneseEra

JulianCalendar

JulianEra

KoreanCalendar

KoreanEra

KoreanLunisolarCalendar

GregorianEra

PersianCalendar

PersianEra

ThaiBuddhistCalendar

ThaiBuddhistEra

UmAlQuraCalendar

UmAlQuraEra

Имя, соответствующее номеру конкретной эры, которое можно получить, передав номер эры методу DateTimeFormatInfo.GetEraName или DateTimeFormatInfo.GetAbbreviatedEraName. В следующем примере эти методы вызываются для получения информации о поддержке эр в классе GregorianCalendar.

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
' The example displays the following output:
'    Date instantiated without an era:
'    1/1/2 in Japanese Calendar -> 1/1/1990 in Gregorian
'    
'    Dates instantiated with eras:
'    1/1/2 era 4 in Japanese Calendar -> 1/1/1990 in Gregorian
'    1/1/2 era 3 in Japanese Calendar -> 1/1/1927 in Gregorian
'    1/1/2 era 2 in Japanese Calendar -> 1/1/1913 in Gregorian
'    1/1/2 era 1 in Japanese Calendar -> 1/1/1869 in Gregorian
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);
      }                        
   }
}
// The example displays the following output:
//    Date instantiated without an era:
//    1/1/2 in Japanese Calendar -> 1/1/1990 in Gregorian
//    
//    Dates instantiated with eras:
//    1/1/2 era 4 in Japanese Calendar -> 1/1/1990 in Gregorian
//    1/1/2 era 3 in Japanese Calendar -> 1/1/1927 in Gregorian
//    1/1/2 era 2 in Japanese Calendar -> 1/1/1913 in Gregorian
//    1/1/2 era 1 in Japanese Calendar -> 1/1/1869 in Gregorian

Кроме того, строка пользовательского формата даты и времени "g" включает имя эры календаря в строковое представлении даты и времени. Дополнительные сведения см. в разделе Строки настраиваемых форматов даты и времени.

Создание даты с указанием эры

Для двух классов Calendar, поддерживающих несколько эр, дата, состоящая из указания года, месяца и дня месяца может быть неоднозначной. Например, во всех четырех эрах календаря JapaneseCalendar годы нумеруются от 1 до 15. Обычно если эра не указана, методы даты и времени и календаря предполагают, что значения относятся к текущей эре. Чтобы явно указать эру при создании даты для класса Calendar, поддерживающего несколько эр, можно вызвать метод Calendar.ToDateTime(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32). Этот метод позволяет явным образом указать эру вместе с календарным годом, месяцем, днем, часом, минутой, секундой и миллисекундой.

В следующем примере используется метод Calendar.ToDateTime(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32) для создания даты вида "первый день первого месяца второго года" в каждой эре, поддерживаемой классом JapaneseCalendar. Затем дата отображается в соответствии с японским и григорианским календарями. Также вызывается конструктор DateTime, чтобы продемонстрировать, что методы, создающие значения дат без указания эры, создают даты в текущей эре.

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
' The example displays the following output:
'    Date instantiated without an era:
'    1/1/2 in Japanese Calendar -> 1/1/1990 in Gregorian
'    
'    Dates instantiated with eras:
'    1/1/2 era 4 in Japanese Calendar -> 1/1/1990 in Gregorian
'    1/1/2 era 3 in Japanese Calendar -> 1/1/1927 in Gregorian
'    1/1/2 era 2 in Japanese Calendar -> 1/1/1913 in Gregorian
'    1/1/2 era 1 in Japanese Calendar -> 1/1/1869 in Gregorian
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);
      }                        
   }
}
// The example displays the following output:
//    Date instantiated without an era:
//    1/1/2 in Japanese Calendar -> 1/1/1990 in Gregorian
//    
//    Dates instantiated with eras:
//    1/1/2 era 4 in Japanese Calendar -> 1/1/1990 in Gregorian
//    1/1/2 era 3 in Japanese Calendar -> 1/1/1927 in Gregorian
//    1/1/2 era 2 in Japanese Calendar -> 1/1/1913 in Gregorian
//    1/1/2 era 1 in Japanese Calendar -> 1/1/1869 in Gregorian

Представление календарных дат с указанием эры

Если объект Calendar поддерживает эры и является текущим календарем объекта CultureInfo, эра включается в строковое представление даты и времени для полной даты, длинной даты и шаблонов короткой даты. В следующем примере показаны эти шаблоны даты при текущем языке и региональных параметрах "Японский (Япония)" и японском текущем календаре.

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 
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
Предупреждающее замечаниеВнимание

Класс JapaneseCalendar — единственный класс календаря в .NET Framework, который поддерживает даты в нескольких эрах и при этом может быть текущим календарем для объекта CultureInfo, а именно объекта CultureInfo, представляющего японский язык и региональные параметры.

Для всех календарей описатель пользовательского формата "g" добавляет эру в результирующую строку. В следующем примере используется строка пользовательского формата "мм-дд-гггг g", где в дату включается эра, при том что текущим является григорианский календарь.

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.      
   DateTime dat = new DateTime(2012, 5, 1);
   Console.WriteLine("{0:MM-dd-yyyy g}", dat);
// The example displays the following output:
//     05-01-2012 A.D.      

В случае когда строковое представление даты связано с календарем, который не является текущим, класс Calendar включает метод Calendar.GetEra, который можно использовать с методами Calendar.GetYear, Calendar.GetMonth и Calendar.GetDayOfMonth для однозначного указания даты и эры. В следующем примере для демонстрации используется класс JapaneseLunisolarCalendar. Однако следует учесть, что если требуется включить в результирующую строку понятное имя или сокращенное имя вместо целого числа для эры, необходимо создать объект DateTimeFormatInfo и сделать календарь JapaneseCalendar его текущим календарем. (Календарь JapaneseLunisolarCalendar не может быть текущим календарем для какого-либо языка и региональных параметров, но в данном случае эры этих двух календарей совпадают.)

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

См. также

Задачи

Практическое руководство. Отображение дат в календарях, отличных от григорианского

Журнал изменений

Дата

Журнал

Причина

Сентябрь 2010

Значительно пересмотрено.

Улучшение информации.