次の方法で共有


暦の操作

日付と時刻の値は一瞬の時間を表しますが、文字列表現はカルチャに依存し、特定のカルチャで日付と時刻の値を表示するために使用される規則と、そのカルチャで使用されるカレンダーの両方に依存します。 このトピックでは、.NET での予定表のサポートについて説明し、日付値を操作するときの予定表クラスの使用について説明します。

.NET の予定表

.NET のすべてのカレンダーは、基本カレンダーの実装を提供する System.Globalization.Calendar クラスから派生します。 Calendar クラスから継承するクラスの 1 つは EastAsianLunisolarCalendar クラスです。これは、すべての lunisolar カレンダーの基底クラスです。 .NET には、次のカレンダー実装が含まれています。

予定表は、次の 2 つの方法のいずれかで使用できます。

  • 特定のカルチャで使用されるカレンダーとして。 各 CultureInfo オブジェクトには、現在の予定表があります。これは、オブジェクトが現在使用している予定表です。 すべての日付と時刻の値の文字列表現は、現在のカルチャとその現在のカレンダーを自動的に反映します。 通常、現在の予定表はカルチャの既定の予定表です。 CultureInfoオブジェクトには、文化が使用できる追加のカレンダーを含むオプションのカレンダーもあります。

  • 特定のカルチャに依存しないスタンドアロンの予定表として。 この場合、Calendar メソッドは、カレンダーを反映する値として日付を表すために使用されます。

ChineseLunisolarCalendarJapaneseLunisolarCalendarJulianCalendarKoreanLunisolarCalendarPersianCalendarTaiwanLunisolarCalendar の 6 つの予定表クラスは、スタンドアロンの予定表としてのみ使用できることに注意してください。 いかなる文化においても、標準の暦やオプションの暦として使用されることはありません。

暦と文化

各カルチャには、CultureInfo.Calendar プロパティによって定義される既定のカレンダーがあります。 CultureInfo.OptionalCalendars プロパティは、特定のカルチャでサポートされているすべてのカレンダー (そのカルチャの既定のカレンダーを含む) を指定する Calendar オブジェクトの配列を返します。

次の例は、CultureInfo.Calendar プロパティと CultureInfo.OptionalCalendars プロパティを示しています。 タイ語 (タイ) カルチャおよび日本語 (日本) カルチャのCultureInfoオブジェクトを作成し、既定のカレンダーと任意のカレンダーを表示します。 どちらの場合も、カルチャの既定の予定表も CultureInfo.OptionalCalendars コレクションに含まれていることに注意してください。

using System;
using System.Globalization;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

特定の CultureInfo オブジェクトで現在使用されているカレンダーは、カルチャの DateTimeFormatInfo.Calendar プロパティによって定義されます。 文化の DateTimeFormatInfo オブジェクトは、CultureInfo.DateTimeFormat プロパティによって返却されます。 カルチャが作成されると、その既定値は CultureInfo.Calendar プロパティの値と同じです。 ただし、カルチャの現在の予定表を、CultureInfo.OptionalCalendars プロパティによって返される配列に含まれる任意の予定表に変更できます。 現在の暦を CultureInfo.OptionalCalendars プロパティの値に含まれない暦に設定しようとすると、ArgumentException がスローされます。

次の例では、アラビア語 (サウジアラビア) カルチャで使用されるカレンダーを変更します。 最初に DateTime 値をインスタンス化し、現在のカルチャ (この場合は英語 (米国)) と現在のカルチャのカレンダー (この場合はグレゴリオ暦) を使用して表示します。 次に、現在のカルチャをアラビア語 (サウジアラビア) に変更し、既定の Um Al-Qura カレンダーを使用して日付を表示します。 次に、CalendarExists メソッドを呼び出して、イスラム暦がアラビア語 (サウジアラビア) 文化でサポートされているかどうかを判断します。 カレンダーはサポートされているため、現在のカレンダーをイスラム暦に変更し、再度日付を表示します。 いずれの場合も、日付は現在のカルチャの現在のカレンダーを使用して表示されることに注意してください。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

日付とカレンダー

Calendar 型のパラメーターを含み、日付の要素 (つまり、月、日、および年) が指定されたカレンダーの値を反映できるようにするコンストラクターを除き、DateTimeDateTimeOffset の両方の値は常にグレゴリオ暦に基づいています。 つまり、たとえば、DateTime.Year プロパティはグレゴリオ暦の年を返し、DateTime.Day プロパティはグレゴリオ暦の月の日を返します。

重要

日付値とその文字列表現には違いがあることに注意してください。 前者はグレゴリオ暦に基づいています。後者は、特定のカルチャの現在のカレンダーに基づいています。

次の例は、DateTime プロパティとそれに対応する Calendar メソッドの違いを示しています。 この例では、現在のカルチャはアラビア語 (エジプト) で、現在のカレンダーは Um Al Qura です。 DateTime 値は、2011 年 7 月 15 日に設定されます。 インバリアント カルチャの規則を使用すると、これらの同じ値が DateTime.ToString(String, IFormatProvider) メソッドによって返されるため、グレゴリオ暦の日付として解釈されるのは明らかです。 現在のカルチャの規則を使用して書式設定された日付の文字列形式は 14/08/32 です。これは、Um Al Qura カレンダーの同等の日付です。 次に、DateTimeCalendar のメンバーを使用して、DateTime 値の日、月、年を返します。 いずれの場合も、DateTime メンバーによって返される値はグレゴリオ暦の値を反映し、UmAlQuraCalendar メンバーによって返される値は Uum al-Qura カレンダーの値を反映します。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

カレンダーに基づいて日付をインスタンス化する

DateTime 値と DateTimeOffset 値はグレゴリオ暦に基づいているため、別のカレンダーの日、月、または年の値を使用する場合は、日付値をインスタンス化するために Calendar 型のパラメーターを含むオーバーロードされたコンストラクターを呼び出す必要があります。 また、特定のカレンダーの Calendar.ToDateTime メソッドのいずれかのオーバーロードを呼び出して、特定のカレンダーの値に基づいて DateTime オブジェクトをインスタンス化することもできます。

次の例では、DateTime コンストラクターに HebrewCalendar オブジェクトを渡して 1 つの DateTime 値をインスタンス化し、DateTime メソッドを呼び出して 2 つ目の HebrewCalendar.ToDateTime(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32) 値をインスタンス化します。 2 つの値はヘブライ暦と同じ値で作成されるため、DateTime.Equals メソッドの呼び出しは、2 つの DateTime 値が等しいことを示しています。

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

現在のカレンダーの日付を表す

日付と時刻の書式設定メソッドは、日付を文字列に変換するときに常に現在のカレンダーを使用します。 つまり、年、月、および月の日の文字列表現は現在のカレンダーを反映しており、必ずしもグレゴリオ暦を反映しているとは限りません。

次の例は、現在のカレンダーが日付の文字列形式にどのように影響するかを示しています。 この例では、現在のカルチャを中国語 (繁体字、台湾) に変更し、日付の値をインスタンス化します。 その後、現在の予定表と日付が表示され、現在の予定表が TaiwanCalendarに変更され、現在の予定表と日付が再び表示されます。 日付が初めて表示されるときは、グレゴリオ暦の日付として表されます。 2 回目の表示時は、台湾暦の日付として表されます。

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

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

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

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

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

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

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

現在以外の予定表の日付を表す

特定のカルチャの現在のカレンダーではないカレンダーを使用して日付を表すには、その Calendar オブジェクトのメソッドを呼び出す必要があります。 たとえば、Calendar.GetYearCalendar.GetMonth、および Calendar.GetDayOfMonth メソッドは、年、月、日を、特定のカレンダーを反映する値に変換します。

警告

一部の暦は特定の文化の省略可能な暦ではないため、これらの暦の日付を表現する場合は、常にカレンダーのメソッドを呼び出す必要があります。 これは、EastAsianLunisolarCalendarJulianCalendar、および PersianCalendar クラスから派生するすべてのカレンダーに当てはまります。

次の例では、JulianCalendar オブジェクトを使用して、ユリウス暦の日付 (1905 年 1 月 9 日) をインスタンス化します。 この日付が既定の (グレゴリオ暦) カレンダーを使用して表示される場合、1905 年 1 月 22 日として表されます。 個々の JulianCalendar メソッドを呼び出して、ユリウス暦で日付を表すことができます。

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

予定表と日付範囲

カレンダーでサポートされている最も古い日付は、そのカレンダーの Calendar.MinSupportedDateTime プロパティによって示されます。 GregorianCalendar クラスの場合、その日付は紀元 0001 年 1 月 1 日です。.NET の他のカレンダーのほとんどは、それ以降の日付をサポートしています。 カレンダーのサポートされている最も早い日付より前の日付と時刻の値を操作を試みると、ArgumentOutOfRangeException 例外が発生します。

ただし、重要な例外が 1 つあります。 DateTime オブジェクトと DateTimeOffset オブジェクトの既定の (初期化されていない) 値は、GregorianCalendar.MinSupportedDateTime 値と等しくなります。 0001 年 1 月 1 日をサポートしていないカレンダーでこの日付を書式設定しようとして、書式指定子を指定しない場合、書式設定方法では、"G" (一般的な日付/時刻パターン) 書式指定子の代わりに "s" (並べ替え可能な日付/時刻パターン) 書式指定子が使用されます。 その結果、書式設定操作は ArgumentOutOfRangeException 例外をスローしません。 代わりに、サポートされていない日付が返されます。 この問題を、次の例で説明します。この例は、現在のカルチャが日本語 (日本) に設定されていれば和暦で、アラビア語 (エジプト) に設定されていればウムアルクラ暦で、DateTime.MinValue の値を表示します。 また、現在のカルチャを英語 (米国) に設定し、これらの各 DateTime.ToString(IFormatProvider) オブジェクトで CultureInfo メソッドを呼び出します。 いずれの場合も、日付は並べ替え可能な日付/時刻パターンを使用して表示されます。

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

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

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

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

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

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

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

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

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

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

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

時代 (年号) の使用

カレンダーは通常、日付を時代 (年号) に分割します。 ただし、.NET の Calendar クラスでは、カレンダーによって定義されたすべての時代 (年号) がサポートされるわけではありません。また、ほとんどの Calendar クラスでは 1 つの時代 (年号) のみがサポートされます。 複数の時代 (年号) をサポートするのは、JapaneseCalendar クラスと JapaneseLunisolarCalendar クラスだけです。

重要

JapaneseCalendarJapaneseLunisolarCalendarの新しい時代であるレイワ時代は、2019年5月1日に始まります。 この変更は、これらのカレンダーを使用するすべてのアプリケーションに影響します。 詳細については、次の記事を参照してください。

  • .NETの日本語カレンダーで新しい年号を処理します。.NET に追加された機能を文書化して、複数の時代 (年号) を持つカレンダーをサポートし、複数の時代 (年号) の予定表を処理する際に使用するベスト プラクティスについて説明します。
  • 日本の時代 (年号) の変更に備えてアプリケーションを準備します。これにより、Windows でのアプリケーションのテストに関する情報が提供され、時代 (年号) の変更に対する準備が整います。
  • .NET Frameworkの新しい日本の年号更新に関する概要では、新しい年号に関連する個々の Windows バージョンの .NET Framework 更新を一覧表示し、複数の年号に対応するための新機能を紹介します。また、アプリケーションをテストする際に注意すべき点が含まれています。

ほとんどのカレンダーの時代 (年号) は、非常に長い期間を表します。 たとえば、グレゴリオ暦では、現在の時代 (年号) は 2 千年以上に及びます。 JapaneseCalendarJapaneseLunisolarCalendarでは、複数の時代 (年号) をサポートする 2 つのカレンダーでは、これは当てはまるわけではありません。 時代は天皇の治世の時代に相当します。 複数の時代 (特に現在の時代 (年号) の上限が不明な場合) のサポートには、特別な課題があります。

時代と年号名

.NET では、特定のカレンダー実装でサポートされている時代 (年号) を表す整数が、Calendar.Eras 配列に逆順に格納されます。 現在の時代 (最新の時間範囲の時代号) はインデックス 0 にあり、複数の時代 (年号) をサポートする Calendar クラスの場合、連続する各インデックスには前の時代 (年号) が反映されます。 静的 Calendar.CurrentEra プロパティは、Calendar.Eras 配列内の現在の時代 (年号) のインデックスを定義します。値が常に 0 である定数です。 個々の Calendar クラスには、現在の時代 (年号) の値を返す静的フィールドも含まれます。 これらは次の表に示されています。

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 クラスでの時代 (年号) のサポートに関する情報を取得します。 現在の時代 (年号) の 2 年目の 1 月 1 日に対応するグレゴリオ暦の日付と、サポートされている各暦年の 2 年目の 1 月 1 日に対応するグレゴリオ暦の暦日が表示されます。

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

さらに、"g" カスタム日時書式指定文字列には、日付と時刻の文字列表現にカレンダーの時代 (年号) の名前が含まれます。 詳しくは、「カスタム日時形式文字列」をご覧ください。

時代 (年号) を使用して日付をインスタンス化する

複数の時代 (年号) をサポートする 2 つの Calendar クラスでは、特定の年、月、および月の日の値で構成される日付があいまいになる可能性があります。 たとえば、JapaneseCalendar でサポートされるすべての時代 (年号) には、その数値が 1 の年が含まれます。 通常、年号が指定されていない場合、日付と時刻とカレンダーの両方のメソッドは、値が現在の時代 (年号) に属していると見なします。 これは、DateTime型のパラメーターを含む DateTimeOffset および Calendar のコンストラクター、および JapaneseCalendar.ToDateTime および JapaneseLunisolarCalendar.ToDateTime メソッドに当てはまります。 次の例では、指定されていない時代 (年号) の 2 年目の 1 月 1 日を表す日付をインスタンス化します。 令和が現在の元号のときにこの例を実行すると、日付は令和2年と解釈されます。 時代 (令和) は、DateTime.ToString(String, IFormatProvider) メソッドによって返される文字列の年の前にあり、グレゴリオ暦の 2020 年 1 月 1 日に対応します。 (レワ時代はグレゴリオ暦の2019年に始まります。

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

ただし、時代 (年号) が変わると、このコードの意図があいまいになります。 日付は現在の時代の2年目を表すものですか、それとも平成の2年目を表すものですか? このあいまいさを回避するには、次の 2 つの方法があります。

  • 既定の GregorianCalendar クラスを使用して、日付と時刻の値をインスタンス化します。 次の例に示すように、日付の文字列表現には日本語カレンダーまたは日本語の Lunisolar カレンダーを使用できます。

    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
    
    
    
  • 時代 (年号) を明示的に指定する日付と時刻のメソッドを呼び出します。 これには、次のメソッドが含まれます。

    次の例では、1868 年 9 月 8 日に始まり、1912 年 7 月 29 日に終了した明治時代の日付と時刻をインスタンス化するために、これらの 3 つの方法を使用します。

    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)
    

ヒント

複数の時代 (年号) をサポートするカレンダーを使用する場合、常にグレゴリオ暦の日付を使用して日付をインスタンス化するか、そのカレンダーに基づいて日付と時刻をインスタンス化するときに時代 (年号) を指定

ToDateTime(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Int32) メソッドに時代 (年号) を指定する場合は、カレンダーの Eras プロパティに時代 (年号) のインデックスを指定します。 ただし、時代 (年号) が変更される可能性があるカレンダーの場合、これらのインデックスは定数値ではありません。現在の時代 (年号) はインデックス 0 で、最も古い時代 (年号) はインデックス Eras.Length - 1です。 新しい時代 (年号) がカレンダーに追加されると、前の時代 (年号) のインデックスが 1 つ増加します。 適切な時代 (年号) インデックスは次のように指定できます。

  • 現在の時代 (年号) の日付については、常にカレンダーの CurrentEra プロパティを使用します。

  • 指定した時代 (年号) の日付の場合は、DateTimeFormatInfo.GetEraName メソッドを使用して、指定した時代 (年号) の名前に対応するインデックスを取得します。 そのためには、JapaneseCalendar が、ja-JP カルチャを表す CultureInfo オブジェクトの現在のカレンダーである必要があります。 (この手法は、JapaneseLunisolarCalendarと同じ時代をサポートしているため、JapaneseCalendar にも有効です)。前の例は、この方法を示しています。

カレンダー、時代 (年号)、日付範囲: 緩やかな範囲チェック

個々のカレンダーで日付範囲がサポートされているのとよく似ていますが、JapaneseCalendar の時代 (年号) や JapaneseLunisolarCalendar クラスでも範囲がサポートされています。 以前は、.NET では厳密な時代 (年号) 範囲チェックを使用して、時代 (年号) 固有の日付がその時代 (年号) の範囲内にあることを確認していました。 つまり、日付が指定した時代 (年号) の範囲外の場合、メソッドは ArgumentOutOfRangeExceptionをスローします。 現在、.NET では既定で緩やかな範囲チェックが使用されています。 .NET のすべてのバージョンに対する更新プログラムにより、緩やかな時代 (年号) の範囲チェックが導入されました。指定された時代 (年号) の範囲外にある時代 (年号) に固有の日付をインスタンス化しようとすると、次の時代 (年号) に "オーバーフロー" し、例外はスローされません。

次の例では、1926 年 12 月 25 日に始まり、1989 年 1 月 7 日に終了した昭和 65 年の日付をインスタンス化しようとします。 この日は1990年1月9日に相当し、JapaneseCalendarの昭和の範囲外です。 この例の出力が示すように、この例で表示される日付は平成 2 年の 1990 年 1 月 9 日です。

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

緩やかな範囲チェックが望ましくない場合は、アプリケーションが実行されている .NET のバージョンに応じて、さまざまな方法で厳密な範囲チェックを復元できます。

  • .NET Core:.netcore.runtime.json 構成ファイルに次のコードを追加します。

    "runtimeOptions": {
      "configProperties": {
          "Switch.System.Globalization.EnforceJapaneseEraYearRanges": true
      }
    }
    
  • .NET Framework 4.6 以降:app.config ファイルに次の AppContext スイッチを設定します。

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <runtime>
        <AppContextSwitchOverrides value="Switch.System.Globalization.EnforceJapaneseEraYearRanges=true" />
      </runtime>
    </configuration>
    
  • .NET Framework 4.5.2 以前: 次のレジストリ値を設定します。

    価値
    キー HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AppContext
    エントリ Switch.System.Globalization.EnforceJapaneseEraYearRanges
    タイプ REG_SZ
    価値 ほんとう

厳密な範囲チェックを有効にすると、前の例では ArgumentOutOfRangeException が発生し、以下の出力が表示されます。

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

複数の時代 (年号) を持つカレンダーの日付を表す

Calendar オブジェクトが時代 (年号) をサポートし、CultureInfo オブジェクトの現在のカレンダーである場合、完全な日付と時刻、長い日付、および短い日付パターンの日付と時刻の値の文字列表現に時代 (年号) が含まれます。 次の使用例は、現在のカルチャが日本 (日本語) で、現在のカレンダーが日本語カレンダーである場合に、これらの日付パターンを表示します。

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 

警告

JapaneseCalendar クラスは、.NET の唯一のカレンダー クラスであり、両方とも複数の時代 (年号) の日付をサポートし、CultureInfo オブジェクトの現在のカレンダー (具体的には、日本語 (日本) カルチャを表す CultureInfo オブジェクト) にすることができます。

すべてのカレンダーについて、"g" カスタム書式指定子には、結果文字列に時代 (年号) が含まれます。 次の例では、"MM-dd-yyyy g" カスタム書式指定文字列を使用して、現在のカレンダーがグレゴリオ暦の場合に、結果文字列に時代 (年号) を含めます。

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

現在のカレンダー以外のカレンダーで日付の文字列表現が表現されている場合、Calendar クラスには、Calendar.GetEraCalendar.GetYear、および Calendar.GetMonth メソッドと共に使用できる Calendar.GetDayOfMonth メソッドが含まれ、日付とそれが属する時代 (年号) を明確に示すことができます。 次の例では、JapaneseLunisolarCalendar クラスを使用して図を示します。 ただし、結果文字列に時代 (年号) の整数の代わりにわかりやすい名前または省略形を含める場合は、DateTimeFormatInfo オブジェクトをインスタンス化し、現在のカレンダー JapaneseCalendar する必要があることに注意してください。 (JapaneseLunisolarCalendar カレンダーはカルチャの現在のカレンダーにすることはできませんが、この場合、2 つのカレンダーは同じ時代 (年号) を共有します)。

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

日本の暦では、元号の最初の年は元年 (元年) と呼ばれます。 例えば、平成1年の代わりに平成元年と表現できます。 .NET では、CultureInfo クラスを持つ Japanese-Japan ("ja-JP") カルチャを表す JapaneseCalendar オブジェクトで使用する場合、次の標準またはカスタムの日時書式指定文字列で書式設定された日付と時刻の書式設定操作で、この規則が採用されています。

たとえば、次の例では、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)

書式設定操作でこの動作が望ましくない場合は、.NET のバージョンに応じて次の手順を実行することで、元号の最初の年を "Gannen" ではなく "1" として常に表す以前の動作を復元できます。

  • .NET Core:.netcore.runtime.json 構成ファイルに次のコードを追加します。

    "runtimeOptions": {
      "configProperties": {
          "Switch.System.Globalization.FormatJapaneseFirstYearAsANumber": true
      }
    }
    
  • .NET Framework 4.6 以降:app.config ファイルに次の AppContext スイッチを設定します。

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <runtime>
        <AppContextSwitchOverrides value="Switch.System.Globalization.FormatJapaneseFirstYearAsANumber=true" />
      </runtime>
    </configuration>
    
  • .NET Framework 4.5.2 以前: 次のレジストリ値を設定します。

    価値
    キー HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AppContext
    エントリ Switch.System.Globalization.日本語初年度を数字で表示
    タイプ REG_SZ
    価値 ほんとう

書式設定操作で gannen のサポートが無効になっている場合、前の例では次の出力が表示されます。

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

.NET も更新され、日付と時刻の解析操作で、"1" または Gannen として表される年を含む文字列がサポートされます。 これを行う必要はありませんが、元号の最初の年として "1" のみを認識するように以前の動作を復元できます。 これは、.NET のバージョンに応じて、次のように実行できます。

  • .NET Core:.netcore.runtime.json 構成ファイルに次のコードを追加します。

    "runtimeOptions": {
      "configProperties": {
          "Switch.System.Globalization.EnforceLegacyJapaneseDateParsing": true
      }
    }
    
  • .NET Framework 4.6 以降:app.config ファイルに次の AppContext スイッチを設定します。

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <runtime>
        <AppContextSwitchOverrides value="Switch.System.Globalization.EnforceLegacyJapaneseDateParsing=true" />
      </runtime>
    </configuration>
    
  • .NET Framework 4.5.2 以前: 次のレジストリ値を設定します。

    価値
    キー HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\AppContext
    エントリ Switch.System.Globalization.EnforceLegacy JapaneseDateParsing
    タイプ REG_SZ
    価値 ほんとう

こちらもご覧ください