Bekerja dengan kalender

Meskipun nilai tanggal dan waktu mewakili momen dalam waktu, representasi string-nya sensitif terhadap kultur dan tergantung pada konvensi yang digunakan untuk menampilkan nilai tanggal dan waktu oleh kultur tertentu dan pada kalender yang digunakan oleh kultur itu. Topik ini mengeksplorasi dukungan untuk kalender di .NET dan membahas penggunaan kelas kalender saat bekerja dengan nilai tanggal.

Kalender di .NET

Semua kalender di .NET berasal dari kelas System.Globalization.Calendar, yang menyediakan implementasi kalender dasar. Salah satu kelas yang mewarisi dari kelas Calendar adalah kelas EastAsianLunisolarCalendar, yang merupakan kelas dasar untuk semua kalender lunisolar. .NET mencakup implementasi kalender berikut:

Kalender dapat digunakan dalam salah satu dari dua cara:

  • Seperti kalender yang digunakan oleh budaya tertentu. Setiap objek CultureInfo memiliki kalender saat ini, yang merupakan kalender yang saat ini digunakan objek. Representasi string dari semua nilai tanggal dan waktu secara otomatis mencerminkan budaya saat ini dan kalendernya saat ini. Biasanya, kalender saat ini adalah kalender default budaya. CultureInfo objek juga memiliki kalender opsional, yang mencakup kalender tambahan yang dapat digunakan budaya.

  • Sebagai kalender mandiri yang independen dari budaya tertentu. Dalam hal ini, metode Calendar digunakan untuk mengekspresikan tanggal sebagai nilai yang mencerminkan kalender.

Perhatikan bahwa enam kelas kalender – ChineseLunisolarCalendar, JapaneseLunisolarCalendar, JulianCalendar, KoreanLunisolarCalendar, PersianCalendardan TaiwanLunisolarCalendar – hanya dapat digunakan sebagai kalender mandiri. Mereka tidak digunakan oleh budaya apa pun baik sebagai kalender default atau sebagai kalender opsional.

Kalender dan budaya

Setiap budaya memiliki kalender default, yang ditentukan oleh properti CultureInfo.Calendar. Properti CultureInfo.OptionalCalendars mengembalikan larik objek Calendar yang menentukan semua kalender yang didukung oleh budaya tertentu, termasuk kalender default budaya tersebut.

Contoh berikut mengilustrasikan properti CultureInfo.Calendar dan CultureInfo.OptionalCalendars. Ini menciptakan objek CultureInfo untuk budaya Thailand dan Jepang dan menampilkan kalender default dan opsional mereka. Perhatikan bahwa dalam kedua kasus, kalender default budaya juga disertakan dalam koleksi CultureInfo.OptionalCalendars.

using System;
using System.Globalization;

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

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

   static void DisplayCalendars(CultureInfo ci)
   {
      Console.WriteLine("Calendars for the {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)
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)

Kalender yang saat ini digunakan oleh objek CultureInfo tertentu ditentukan oleh properti DateTimeFormatInfo.Calendar budaya tersebut. Objek DateTimeFormatInfo budaya dikembalikan oleh properti CultureInfo.DateTimeFormat. Ketika suatu budaya dibuat, nilai defaultnya sama dengan nilai properti CultureInfo.Calendar. Namun, Anda dapat mengubah kalender budaya saat ini ke kalender apa pun yang terkandung dalam larik yang dikembalikan oleh properti CultureInfo.OptionalCalendars. Jika Anda mencoba mengatur kalender saat ini ke kalender yang tidak disertakan dalam nilai properti CultureInfo.OptionalCalendars, ArgumentException akan dilemparkan.

Contoh berikut mengubah kalender yang digunakan oleh budaya Arab (Arab Saudi). Pertama-tama ini membuat instans nilai DateTime dan menampilkannya menggunakan budaya saat ini - yang, dalam hal ini, adalah bahasa Inggris (Amerika Serikat) - dan kalender budaya saat ini (yang, dalam hal ini, adalah kalender Gregorian). Selanjutnya, itu mengubah budaya saat ini menjadi Arab (Arab Saudi) dan menampilkan tanggal menggunakan kalender Al-Qura Um default-nya. Kemudian memanggil metode CalendarExists untuk menentukan apakah kalender Hijriah didukung oleh budaya Arab (Arab Saudi). Karena kalender didukung, itu mengubah kalender saat ini menjadi Hijriah dan menampilkan kembali tanggal. Perhatikan bahwa dalam setiap kasus, tanggal ditampilkan menggunakan kalender budaya saat ini.

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

Tanggal dan kalender

Dengan pengecualian konstruktor yang menyertakan parameter jenis Calendar dan memungkinkan elemen tanggal (yaitu, bulan, hari, dan tahun) untuk mencerminkan nilai dalam kalender yang ditunjuk, baik nilai DateTime dan DateTimeOffset selalu didasarkan pada kalender Gregorian. Ini berarti, misalnya, bahwa properti DateTime.Year mengembalikan tahun dalam kalender Gregorian, dan properti DateTime.Day mengembalikan hari dalam sebulan dalam kalender Gregorian.

Penting

Penting untuk diingat bahwa ada perbedaan antara nilai tanggal dan representasi string-nya. Yang pertama didasarkan pada kalender Gregorian; yang selanjutnya didasarkan pada kalender saat ini budaya tertentu.

Contoh berikut mengilustrasikan perbedaan ini antara properti DateTime dan metode Calendar yang sesuai. Dalam contoh, budaya saat ini adalah Arab (Mesir), dan kalender saat ini adalah Um Al Qura. Nilai DateTime diatur ke hari kelima belas pada bulan ketujuh tahun 2011. Jelas bahwa ini ditafsirkan sebagai tanggal Gregorian, karena nilai yang sama ini dikembalikan oleh metode DateTime.ToString(String, IFormatProvider) ketika menggunakan konvensi budaya invarian. Representasi string dari tanggal yang diformat menggunakan konvensi budaya saat ini adalah 14/08/32, yang merupakan ekuivalen dalam kalender Umm Al Qura. Selanjutnya, anggota DateTime dan Calendar digunakan untuk mengembalikan hari, bulan, dan tahun dari nilai DateTime. Dalam setiap kasus, nilai yang dikembalikan oleh anggota DateTime mencerminkan nilai dalam kalender Gregorian, sedangkan nilai yang dikembalikan oleh anggota UmAlQuraCalendar mencerminkan nilai dalam kalender 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: {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
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

Membuat instans tanggal berdasarkan kalender

Karena nilai DateTime dan DateTimeOffset didasarkan pada kalender Gregorian, Anda harus memanggil konstruktor yang kelebihan beban yang menyertakan parameter jenis Calendar untuk membuat instans nilai tanggal jika Anda ingin menggunakan nilai hari, bulan, atau tahun dari kalender yang berbeda. Anda juga dapat memanggil salah satu kelebihan beban metode Calendar.ToDateTime kalender tertentu untuk membuat instans objek DateTime berdasarkan nilai kalender tertentu.

Contoh berikut membuat instans satu nilai DateTime dengan meneruskan objek HebrewCalendar ke konstruktor DateTime, dan membuat instans nilai DateTime kedua dengan memanggil metode HebrewCalendar.ToDateTime(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32). Karena kedua nilai dibuat dengan nilai yang identik dari kalender Ibrani, panggilan ke metode DateTime.Equals menunjukkan bahwa kedua nilai DateTime tersebut setara.

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

Merepresentasikan tanggal dalam kalender saat ini

Metode pemformatan tanggal dan waktu selalu menggunakan kalender saat ini saat mengonversi tanggal menjadi string. Ini berarti bahwa representasi string tahun, bulan, dan hari dalam sebulan mencerminkan kalender saat ini, dan tidak selalu mencerminkan kalender Gregorian.

Contoh berikut menunjukkan bagaimana kalender saat ini memengaruhi representasi string tanggal. Ini mengubah budaya saat ini menjadi Cina (Tradisional, Taiwan), dan membuat instans nilai tanggal. Kemudian menampilkan kalender saat ini dan tanggal, mengubah kalender saat ini menjadi TaiwanCalendar, dan menampilkan kalender dan tanggal saat ini sekali lagi. Pertama kali tanggal ditampilkan, itu direpresentasikan sebagai tanggal dalam kalender Gregorian. Kedua kalinya ditampilkan, itu direpresentasikan sebagai tanggal dalam kalender Taiwan.

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

Merepresentasikan tanggal dalam kalender yang bukan saat ini

Untuk merepresentasikan tanggal menggunakan kalender yang bukan kalender saat ini dari budaya tertentu, Anda harus memanggil metode objek Calendar tersebut. Misalnya, metode Calendar.GetYear, Calendar.GetMonth, dan Calendar.GetDayOfMonth mengonversi tahun, bulan, dan hari ke nilai yang mencerminkan kalender tertentu.

Peringatan

Karena beberapa kalender bukan kalender opsional dari budaya apa pun, merepresentasikan tanggal dalam kalender ini selalu mengharuskan Anda memanggil metode kalender. Ini berlaku untuk semua kalender yang berasal dari kelas EastAsianLunisolarCalendar, JulianCalendar, dan PersianCalendar.

Contoh berikut menggunakan objek JulianCalendar untuk membuat instans tanggal, 9 Januari 1905, dalam kalender Julian. Ketika tanggal ini ditampilkan menggunakan kalender default (Gregorian), itu direpresentasikan sebagai 22 Januari 1905. Panggilan ke metode JulianCalendar individual memungkinkan tanggal direpresentasikan dalam kalender 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

Kalender dan rentang tanggal

Tanggal paling awal yang didukung oleh kalender diindikasikan oleh properti Calendar.MinSupportedDateTime kalender tersebut. Untuk kelas GregorianCalendar, tanggal itu adalah 1 Januari 0001 C.E. Sebagian besar kalender lain di .NET mendukung tanggal setelahnya. Mencoba bekerja dengan nilai tanggal dan waktu yang mendahului tanggal paling awal kalender yang didukung memunculkan pengecualian ArgumentOutOfRangeException.

Namun, ada satu pengecualian penting. Nilai default (tidak diinisialisasi) objek DateTime dan objek DateTimeOffset setara dengan nilai GregorianCalendar.MinSupportedDateTime. Jika Anda mencoba memformat tanggal ini dalam kalender yang tidak mendukung 1 Januari 0001 C.E. dan Anda tidak menyediakan penentu format, metode pemformatan menggunakan penentu format "s" (pola tanggal/waktu yang dapat diurutkan) alih-alih penentu format "G" (pola tanggal/waktu umum). Akibatnya, operasi pemformatan tidak melemparkan pengecualian ArgumentOutOfRangeException. Sebaliknya, ia mengembalikan tanggal yang tidak didukung. Ini diilustrasikan dalam contoh berikut, yang menampilkan nilai DateTime.MinValue ketika budaya saat ini diatur ke Jepang dengan kalender Jepang, dan ke Arab (Mesir) dengan kalender Um Al Qura. Ini juga mengatur budaya saat ini ke bahasa Inggris (Amerika Serikat) dan memanggil metode DateTime.ToString(IFormatProvider) dengan masing-masing objek CultureInfo ini. Dalam setiap kasus, tanggal ditampilkan dengan menggunakan pola tanggal /waktu yang dapat diurutkan.

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 {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.
      CultureInfo arEG = 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"));
   }

   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

Bekerja dengan era

Kalender biasanya membagi tanggal menjadi era. Namun, kelas Calendar di .NET tidak mendukung setiap era yang ditentukan oleh kalender, dan sebagian besar kelas Calendar hanya mendukung satu era. Hanya kelas JapaneseCalendar dan JapaneseLunisolarCalendar yang mendukung beberapa era.

Penting

Era Reiwa, era baru dalam JapaneseCalendar dan JapaneseLunisolarCalendar, dimulai pada 1 Mei 2019. Perubahan ini memengaruhi semua aplikasi yang menggunakan kalender ini. Lihat artikel berikut untuk mengetahui informasi selengkapnya:

Sebuah era di sebagian besar kalender menandakan periode waktu yang sangat lama. Dalam kalender Gregorian, misalnya, era saat ini mencakup lebih dari dua milenium. Untuk JapaneseCalendar dan JapaneseLunisolarCalendar, dua kalender yang mendukung beberapa era, ini tidak berlaku. Sebuah era sesuai dengan periode pemerintahan seorang kaisar. Dukungan untuk beberapa era, terutama ketika batas atas era saat ini tidak diketahui, menimbulkan tantangan khusus.

Era dan nama era

Dalam .NET, bilangan bulat yang mewakili era yang didukung oleh implementasi kalender tertentu disimpan dalam urutan terbalik dalam larik Calendar.Eras. Era saat ini (yang merupakan era dengan rentang waktu terbaru) berada pada nol indeks, dan untuk kelas Calendar yang mendukung beberapa era, setiap indeks berturut-turut mencerminkan era sebelumnya. Properti Calendar.CurrentEra statik mendefinisikan indeks era saat ini dalam larik Calendar.Eras; ini adalah konstanta yang nilainya selalu nol. Masing-masing kelas Calendar juga menyertakan bidang statik yang mengembalikan nilai era saat ini. Mereka tercantum dalam tabel berikut.

Kelas kalender Bidang era saat ini
ChineseLunisolarCalendar ChineseEra
GregorianCalendar ADEra
HebrewCalendar HebrewEra
HijriCalendar HijriEra
JapaneseLunisolarCalendar JapaneseEra
JulianCalendar JulianEra
KoreanCalendar KoreanEra
KoreanLunisolarCalendar GregorianEra
PersianCalendar PersianEra
ThaiBuddhistCalendar ThaiBuddhistEra
UmAlQuraCalendar UmAlQuraEra

Nama yang sesuai dengan nomor era tertentu dapat diambil dengan meneruskan nomor era ke metode DateTimeFormatInfo.GetEraName atau DateTimeFormatInfo.GetAbbreviatedEraName. Contoh berikut memanggil metode ini untuk mengambil informasi tentang dukungan era di kelas GregorianCalendar. Ini menampilkan tanggal kalender Gregorian yang sesuai dengan 1 Januari tahun kedua era saat ini, serta tanggal kalender Gregorian yang sesuai dengan 1 Januari tahun kedua dari setiap era kalender Jepang yang didukung.

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

Selain itu, string format tanggal dan waktu kustom "g" menyertakan nama era kalender dalam representasi string tanggal dan waktu. Untuk informasi selengkapnya, lihat String format tanggal dan waktu kustom.

Membuat instans tanggal dengan era

Untuk dua kelas Calendar yang mendukung beberapa era, tanggal yang terdiri dari tahun, bulan, dan hari tertentu dari nilai bulan bisa jadi ambigu. Misalnya, semua era yang didukung oleh JapaneseCalendar memiliki tahun yang jumlahnya adalah 1. Biasanya, jika suatu era tidak ditentukan, baik tanggal dan waktu dan metode kalender mengasumsikan bahwa nilai milik era saat ini. Ini berlaku untuk konstruktor DateTime dan DateTimeOffset yang mencakup parameter jenis Calendar, serta metode JapaneseCalendar.ToDateTime dan JapaneseLunisolarCalendar.ToDateTime. Contoh berikut membuat instans tanggal yang merepresentasikan 1 Januari dari tahun kedua dari era yang tidak ditentukan. Jika Anda mengeksekusi contoh ketika era Reiwa adalah era saat ini, tanggal tersebut ditafsirkan sebagai tahun kedua era Reiwa. Era tersebut, 令和, mendahului tahun dalam string yang dikembalikan oleh metode DateTime.ToString(String, IFormatProvider) dan sesuai dengan 1 Januari 2020, dalam kalender Gregorian. (Era Reiwa dimulai pada tahun 2019 dari kalender Gregorian.)

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

Namun, jika era berubah, niat dari kode ini menjadi ambigu. Apakah tanggal tersebut dimaksudkan untuk merepresentasikan tahun kedua era saat ini, atau dimaksudkan untuk mewakili tahun kedua era Heisei? Ada dua cara untuk menghindari keambiguan ini:

  • Buat instans nilai tanggal dan waktu menggunakan kelas GregorianCalendar default. Anda kemudian dapat menggunakan kalender Jepang atau kalender Lunisolar Jepang untuk representasi string tanggal, seperti yang ditunjukkan contoh berikut.

    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
    
    
    
  • Panggil metode tanggal dan waktu yang secara eksplisit menentukan suatu era. Ini termasuk metode berikut:

    Contoh berikut menggunakan tiga metode ini untuk membuat instans tanggal dan waktu di era Meiji, yang dimulai pada tanggal 8 September 1868, dan berakhir pada tanggal 29 Juli 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)
    

Tip

Saat bekerja dengan kalender yang mendukung beberapa era, selalu gunakan tanggal Gregorian untuk membuat instans tanggal, atau tentukan era saat Anda membuat instans tanggal dan waktu berdasarkan kalender tersebut.

Dalam menentukan era ke metode ToDateTime(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32), Anda menyediakan indeks era di properti Eras kalender. Tapi untuk kalender yang eranya dapat berubah, indeks ini bukan nilai konstanta; era saat ini berada pada indeks 0, dan era terlama berada di indeks Eras.Length - 1. Ketika era baru ditambahkan ke kalender, indeks dari era sebelumnya meningkat satu. Anda dapat memberikan indeks era yang sesuai sebagai berikut:

Kalender, era, dan rentang tanggal: Pemeriksaan rentang santai

Sangat mirip dengan kalender individu yang memiliki dukungan rentang tanggal, era di kelas JapaneseCalendar dan JapaneseLunisolarCalendar juga memiliki rentang yang didukung. Sebelumnya, .NET menggunakan pemeriksaan rentang era yang ketat untuk memastikan bahwa tanggal khusus era berada dalam rentang era itu. Artinya, jika tanggal berada di luar rentang era yang ditentukan, metode akan melempar ArgumentOutOfRangeException. Saat ini, .NET menggunakan pemeriksaan rentang yang santai secara default. Pembaruan untuk semua versi .NET memperkenalkan pemeriksaan rentang era santai; upaya untuk membuat instans tanggal khusus era yang berada di luar rentang era yang ditentukan "meluap" ke era berikutnya, dan tidak ada pengecualian yang dilemparkan.

Contoh berikut mencoba untuk membuat instans tanggal di tahun ke-65 era Showa, yang dimulai pada tanggal 25 Desember 1926 dan berakhir pada tanggal 7 Januari 1989. Tanggal ini sesuai dengan 9 Januari 1990, yang berada di luar rentang era Showa dalam JapaneseCalendar. Seperti yang digambarkan oleh output dari contoh, tanggal yang ditampilkan oleh contoh adalah 9 Januari 1990, pada tahun kedua era 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

Jika pemeriksaan rentang santai tidak diinginkan, Anda dapat memulihkan pemeriksaan rentang yang ketat dengan beberapa cara, tergantung pada versi .NET tempat aplikasi Anda berjalan:

  • .NET Core: Tambahkan yang berikut ini ke file konfigurasi .netcore.runtime.json:

    "runtimeOptions": {
      "configProperties": {
          "Switch.System.Globalization.EnforceJapaneseEraYearRanges": true
      }
    }
    
  • .NET Framework 4.6 atau yang lebih baru: Atur pertukaran AppContext berikut dalam file 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 atau yang lebih lama: Atur nilai registri berikut:

    Nilai
    Kunci HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AppContext
    Catatan Switch.System.Globalization.EnforceJapaneseEraYearRanges
    Jenis REG_SZ
    Nilai benar

Dengan pemeriksaan rentang ketat diaktifkan, contoh sebelumnya melemparkan ArgumentOutOfRangeException dan menampilkan output berikut:

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

Merepresentasikan tanggal dalam kalender dengan beberapa era

Jika objek Calendar mendukung era dan merupakan kalender objek CultureInfo saat ini, era disertakan dalam representasi string nilai tanggal dan waktu untuk pola lengkap tanggal dan waktu, tanggal panjang, dan tanggal pendek. Contoh berikut menampilkan pola tanggal ini ketika budaya saat ini adalah Jepang dan kalender saat ini adalah kalender Jepang.

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 

Peringatan

Kelas JapaneseCalendar adalah satu-satunya kelas kalender di .NET yang mendukung tanggal di lebih dari satu era dan yang dapat menjadi kalender objek CultureInfo saat ini - khususnya, dari objek CultureInfo yang mewakili budaya Jepang.

Untuk semua kalender, penentu format kustom "g" menyertakan era dalam string hasil. Contoh berikut menggunakan string format kustom "MM-dd-yyyy g" untuk menyertakan era dalam string hasil saat kalender saat ini adalah kalender Gregorian.

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

Dalam kasus di mana representasi string tanggal dinyatakan dalam kalender yang bukan kalender saat ini, kelas Calendar menyertakan metode Calendar.GetEra yang dapat digunakan bersama dengan metode Calendar.GetYear, Calendar.GetMonth, dan Calendar.GetDayOfMonth untuk secara tidak ambigu mengindikasikan tanggal serta era tempatnya berada. Contoh berikut menggunakan kelas JapaneseLunisolarCalendar untuk memberikan ilustrasi. Namun, perhatikan bahwa menyertakan nama atau singkatan yang bermakna alih-alih bilangan bulat untuk era dalam string hasil mengharuskan Anda membuat instans objek DateTimeFormatInfo dan menjadikan JapaneseCalendar kalender saat ini. (Kalender JapaneseLunisolarCalendar tidak dapat menjadi kalender saat ini budaya apa pun, tetapi dalam hal ini kedua kalender berbagi era yang sama.)

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

Dalam kalender Jepang, tahun pertama suatu era disebut Gannen (元年). Misalnya, alih-alih Heisei 1, tahun pertama era Heisei dapat disebut sebagai Heisei Gannen. .NET mengadopsi konvensi ini dalam operasi pemformatan untuk tanggal dan waktu yang diformat dengan string format tanggal dan waktu standar atau kustom berikut ketika digunakan dengan objek CultureInfo yang merepresentasikan budaya Japanese-Japan ("ja-JP") dengan kelas JapaneseCalendar:

  • Pola tanggal panjang, diindikasikan oleh string format tanggal dan waktu standar "D".
  • Pola waktu lama tanggal penuh, diindikasikan oleh string format tanggal dan waktu standar "F".
  • Pola waktu pendek tanggal penuh, diindikasikan oleh string format tanggal dan waktu standar "f".
  • Pola tahun/bulan, ditunjukkan oleh string format tanggal dan waktu standar "Y" atau "y".
  • String format tanggal dan waktu kustom "ggy'年'" atau "ggy年 ".

Misalnya, contoh berikut menampilkan tanggal di tahun pertama era Heisei dalam 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)

Jika perilaku ini tidak diinginkan dalam operasi pemformatan, Anda dapat memulihkan perilaku sebelumnya, yang selalu mewakili tahun pertama era sebagai "1" daripada "Gannen", dengan melakukan hal berikut, tergantung pada versi .NET:

  • .NET Core: Tambahkan yang berikut ini ke file konfigurasi .netcore.runtime.json:

    "runtimeOptions": {
      "configProperties": {
          "Switch.System.Globalization.FormatJapaneseFirstYearAsANumber": true
      }
    }
    
  • .NET Framework 4.6 atau yang lebih baru: Atur pertukaran AppContext berikut dalam file 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 atau yang lebih lama: Atur nilai registri berikut:

    Nilai
    Kunci HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AppContext
    Catatan Switch.System.Globalization.FormatJapaneseFirstYearAsANumber
    Jenis REG_SZ
    Nilai benar

Dengan dukungan gannen dalam operasi pemformatan dinonaktifkan, contoh sebelumnya menampilkan output berikut:

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

.NET juga telah diperbarui sehingga operasi penguraian tanggal dan waktu mendukung string yang berisi tahun yang direpresentasikan sebagai "1" atau Gannen. Meskipun Anda tidak perlu melakukan ini, Anda dapat memulihkan perilaku sebelumnya untuk mengenali hanya "1" sebagai tahun pertama era. Anda dapat melakukan ini sebagai berikut, tergantung pada versi .NET:

  • .NET Core: Tambahkan yang berikut ini ke file konfigurasi .netcore.runtime.json:

    "runtimeOptions": {
      "configProperties": {
          "Switch.System.Globalization.EnforceLegacyJapaneseDateParsing": true
      }
    }
    
  • .NET Framework 4.6 atau yang lebih baru: Atur pertukaran AppContext berikut dalam file 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 atau yang lebih lama: Atur nilai registri berikut:

    Nilai
    Kunci HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AppContext
    Catatan Switch.System.Globalization.EnforceLegacyJapaneseDateParsing
    Jenis REG_SZ
    Nilai benar

Lihat juga