読者です 読者をやめる 読者になる 読者になる

いろんな言語で1582年10月5日を扱ってみる(VB.NET 版)

1582年10月5日〜1582年10月14日までの10日間は、何らかの自然現象(ゴゴゴゴゴ)によって時間が消し去れてた期間として知られています。プログラミング言語を使ってこの日を取り扱おうとすると、いろんな結果が出力されます。

今日はそんな素敵な日付である1582年10月5日と戯れて、貴重な1日を無駄にしてみたいと思います。

いろんなプログラミング言語で1582年10月5日を扱ってみる| mwSoft

VB.NET でもやってみた。

        Dim dt1 As New DateTime(1582, 10, 5)
        Console.WriteLine("dt1 = {0}", dt1.ToString)

        Dim dt2 As New DateTime(1582, 10, 4)
        Console.WriteLine("dt2 = {0}", dt2.ToString)

        Dim dt3 As New DateTime(1582, 10, 4)
        dt3 = dt3.AddDays(1)
        Console.WriteLine("dt3 = {0}", dt3.ToString)

結果:

dt1 = 1582/10/05 0:00:00
dt2 = 1582/10/04 0:00:00
dt3 = 1582/10/05 0:00:00

何も面白いことは起こらない。

暦でサポートされている最も古い日付は、暦の Calendar.MinSupportedDateTime プロパティによって示されます。 GregorianCalendar クラスでは、その日付は西暦 0001 年 1 月 1 日 です。
カレンダーの使用

VB.NET は先発グレゴリオ暦を扱えるようだ。
(というより、ここでいう DateTime はグレゴレオ歴でしかない)

というわけでユリウス暦へ変換してみる。

        Dim jd As New System.Globalization.JulianCalendar()

        Dim dt1 As New DateTime(1582, 10, 15, New System.Globalization.GregorianCalendar)
        Console.WriteLine("dt1 = {0}/{1}/{2}", jd.GetYear(dt1), jd.GetMonth(dt1), jd.GetDayOfMonth(dt1))

        Dim dt2 As New DateTime(1582, 10, 14, New System.Globalization.GregorianCalendar)
        Console.WriteLine("dt2 = {0}/{1}/{2}", jd.GetYear(dt2), jd.GetMonth(dt2), jd.GetDayOfMonth(dt2))

        Dim dt3 As New DateTime(1582, 10, 14, New System.Globalization.GregorianCalendar)
        dt3 = dt3.AddDays(1)
        Console.WriteLine("dt3 = {0}/{1}/{2}", jd.GetYear(dt3), jd.GetMonth(dt3), jd.GetDayOfMonth(dt3))

結果:

dt1 = 1582/10/5
dt2 = 1582/10/4
dt3 = 1582/10/5

あれ?ユリウス暦は 10/4 までで、それ以降はグレゴリオ暦(というかエラー)になるのでは?
というわけでユリウス暦の取りうる範囲を確認してみると

System.Threading.Thread.CurrentThread.CurrentCulture = New System.Globalization.CultureInfo("ja-JP")
Console.WriteLine(New System.Globalization.JulianCalendar().MinSupportedDateTime)
Console.WriteLine(New System.Globalization.JulianCalendar().MaxSupportedDateTime)

結果:

0001/01/01 0:00:00
9999/12/31 23:59:59

となった。うーむ。

The Gregorian calendar was developed as a replacement for the Julian calendar (which is represented by the JulianCalendar class) and was first introduced in a small number of cultures on October 15, 1582. When working with historic dates that precede a culture's adoption of the Gregorian calendar, you should use the original calendar if it is available in the .NET Framework. For example, Denmark changed from the Julian calendar to the Gregorian calendar on February 19 (in the Julian calendar) or March 1 (in the Gregorian calendar) of 1700. In this case, for dates before the adoption of the Gregorian calendar, you should use the Julian calendar. However, note that no culture offers intrinsic support for the JulianCalendar class. You must use the JulianCalendar class as a standalone calendar. For more information, see Working with Calendars.
GregorianCalendar クラス (System.Globalization)

地域によっては 10/5 以降もユリウス暦が使われていたため、ユリウス暦の終端を一意に決められないということだろうか。

カルチャごとに Min/MaxSupportedDateTime があるのかとも思ったけれど違った。

        System.Threading.Thread.CurrentThread.CurrentCulture = New System.Globalization.CultureInfo("en-US")
        Console.WriteLine(New System.Globalization.JulianCalendar().MinSupportedDateTime)
        Console.WriteLine(New System.Globalization.JulianCalendar().MaxSupportedDateTime)
        Console.WriteLine()

        System.Threading.Thread.CurrentThread.CurrentCulture = New System.Globalization.CultureInfo("it-IT")
        Console.WriteLine(New System.Globalization.JulianCalendar().MinSupportedDateTime)
        Console.WriteLine(New System.Globalization.JulianCalendar().MaxSupportedDateTime)
        Console.WriteLine()

        System.Threading.Thread.CurrentThread.CurrentCulture = New System.Globalization.CultureInfo("ja-JP")
        Console.WriteLine(New System.Globalization.JulianCalendar().MinSupportedDateTime)
        Console.WriteLine(New System.Globalization.JulianCalendar().MaxSupportedDateTime)
        Console.WriteLine()

結果:

1/1/0001 12:00:00 AM
12/31/9999 11:59:59 PM

01/01/0001 00:00:00
31/12/9999 23:59:59

0001/01/01 0:00:00
9999/12/31 23:59:59

「歴史的経緯」を踏まえた実装をしだすと「カルチャ」というのも一筋縄ではいかなくなりそうでなかなか頭の痛い話ではあるけれど、実務的には暦の相互変換ができれば良いという意味ではこの実装はリーズナブルだと思う。

ちなみに和暦は明治からサポートされている。
JapaneseCalendar クラス (System.Globalization)

今回のコードはこちら
グレゴリオ暦、ユリウス暦の表示