一五八二年十月四日は何曜日ですか.

11112 ワード

まず、次のC#プログラムを見てみましょう.
01:  using System;

02:  using System.Globalization;

03:  

04:  class Program

05: {

06:    static void Main()

07:    {

08:      Console.WriteLine(CultureInfo.CurrentCulture.Calendar);

09:      for (var dt = new DateTime(1582, 10, 4); dt <= new DateTime(1582, 10, 15); dt = dt.AddDays(1))

10:        Console.WriteLine(dt.ToString("dddd yyyy-MM-dd"));

11:    }

12:  }

実行結果は次のとおりです.
System.Globalization.GregorianCalendar

  1582-10-04

  1582-10-05

  1582-10-06

  1582-10-07

  1582-10-08

  1582-10-09

  1582-10-10

  1582-10-11

  1582-10-12

  1582-10-13

  1582-10-14

  1582-10-15


このように見ると、一五八二年十月四日は月曜日です.
 
本当にそうなの?次のJavaプログラムを見てみましょう.
import java.util.*;



public class GregorianTest

{

  public static void main(String[] args)

  {

    for (

      GregorianCalendar dt = new GregorianCalendar(1582, 9, 4);

      dt.compareTo(new GregorianCalendar(1582, 9, 15)) <= 0;

      dt.add(Calendar.DAY_OF_MONTH, 1)

    )

      System.out.println(dt.getTime());

  }

}


Ubuntu 10.04オペレーティングシステムでコンパイルおよび実行:
ben@ben-1520:~/work$ javac GregorianTest.java

ben@ben-1520:~/work$ java GregorianTest

Thu Oct 04 00:00:00 CST 1582

Fri Oct 15 00:00:00 CST 1582

ben@ben-1520:~/work$ 


注意java.util.GregorianCalendarクラスのコンストラクション関数は、月が0から始まるため、9は10月を表します.
次の2点がわかります.
  • 一五八二年十月四日は木曜日です.
  • 一五八二年十月四日の次の日は:一五八二年十月十五日、金曜日です. 

  • 果たして誰が正しいのか. 
     
    java.util.GregorianCalendarの説明を見てみましょう.
    GregorianCalendarはCalendarの特定のサブクラスであり、世界の多くの国で使用されている標準カレンダーシステムを提供しています.
    GregorianCalendarは、単一の断続的なサポートの下で儒略暦とグリゴリ暦システムを同時にサポートするハイブリッドカレンダーで、デフォルトではグリゴリ暦の創設時のグリゴリ暦の日付に対応しています(一部の国/地域は1582年10月15日に創設され、他の国/地域では遅くなります).開始日は、呼び出し元がsetGregorianChange()を呼び出して変更できます.
    歴史上、まずグリコ暦を採用した国/地域では、1582年10月4日(儒略暦)に次いで1582年10月15日(グリコ暦)である.このカレンダーは、これらの変化を正しくシミュレートします.グレゴリオ暦が始まる前に、グレゴリオ暦が実現したのはユリウス暦です.グリゴリ暦と儒略暦の唯一の違いは閏年規則である.ユリウス暦は4年ごとに閏年を指定し、グリゴリウス暦は400で除かれない世紀を無視した.
    GregorianCalendarは、予想されるグリコ暦と儒略暦を実現することができます.すなわち、現在のルールを時間的に無限に後方または前方に押し出すことによって日付を計算することができる.したがって,すべての年に対してGregorianCalendarを用いて有意義で一貫した結果を生成することができる.しかし、現代の儒略暦のルールを採用する場合、GregorianCalendarを使って得られた日付は、西暦4年3月1日以降が正確である.この日付までは閏年ルールの適用は規則性がなく,45 BCまでは儒略暦さえ存在しなかった.
    これでJavaプラットフォームが正しいことが明らかになった.NET Framework Base Class LibraryのDateTimeに問題があります.
    Gregorian calendarは、わが国の現行の西暦である.
     
    Ubuntu 10.04オペレーティングシステムで次のコマンドを実行します.
    ben@ben-1520:~/work$ ncal -3 -s IT 10 1582
    
            1582                 1582                 1582        
    
                                                    
    
                       1      1  2  3  4 15 16      1  2  3  4  5  6
    
     2  3  4  5  6  7  8  17 18 19 20 21 22 23   7  8  9 10 11 12 13
    
     9 10 11 12 13 14 15  24 25 26 27 28 29 30  14 15 16 17 18 19 20
    
    16 17 18 19 20 21 22  31                    21 22 23 24 25 26 27
    
    23 24 25 26 27 28 29                        28 29 30
    
    30                                          
    
    ben@ben-1520:~/work$ 
    
    

    一五八二年十月四日は確かに木曜日で、その次の日は一五八二年十月十五日金曜日なので、一五八二年十月二十一日しかありません.
     
    Visual J# Redistributable Packagesをダウンロードすると、C#言語でもjavaを使用することができる.util.GregorianCalendarクラス:
    01:  using System;
    
    02:  using java.util;
    
    03:  
    
    04:  class Program
    
    05: {
    
    06:    static void Main()
    
    07:    {
    
    08:      var dt = new GregorianCalendar(1582, 9, 4);
    
    09:      for (var i = 0; i < 12; i++)
    
    10:      {
    
    11:        Console.WriteLine(dt.getTime());
    
    12:        dt.add(Calendar.DAY_OF_MONTH, 1);
    
    13:      }
    
    14:    }
    
    15:  }

    なお、このプログラムはvjslibを参照する必要がある.dll .このプログラムの実行結果は次のとおりです.
    Thu Oct 04 00:00:00 GMT+08:00 1582
    
    Tue Sep 25 00:00:00 GMT+08:00 1582
    
    Wed Sep 26 00:00:00 GMT+08:00 1582
    
    Thu Sep 27 00:00:00 GMT+08:00 1582
    
    Fri Sep 28 00:00:00 GMT+08:00 1582
    
    Sat Sep 29 00:00:00 GMT+08:00 1582
    
    Sun Sep 30 00:00:00 GMT+08:00 1582
    
    Mon Oct 01 00:00:00 GMT+08:00 1582
    
    Tue Oct 02 00:00:00 GMT+08:00 1582
    
    Wed Oct 03 00:00:00 GMT+08:00 1582
    
    Thu Oct 04 00:00:00 GMT+08:00 1582
    
    Tue Sep 25 00:00:00 GMT+08:00 1582
    
    

    一五八二年十月四日は確かに木曜日であることがわかります.しかし、その次の日はどうして一五八二年九月二十五日火曜になったのだろうか.マイクロソフトのvjslib.dllに問題があります. 
     
    .NET Framework Base Class LibraryにはSystem.Globalization.GregorianCalendarクラスがありますが、このクラスは一五八二年十月四日を正しく処理できません.
    (ユーザーズ自身がユリウス暦かグレゴリオ暦かを指定した場合、.NETプラットフォームのSystem.Globalization.GregorianCalendarに関連するクラスは正常に動作します.「Ubuntuでのプログラミング言語(上)」の論述を参照してください.----13階からのコメントを参照)
     
    C言語では,日時に関するデータ構造や関数がtime.hにあり,1900年からであるため,1582年の日付を表すことができない.
    C++言語とその標準ライブラリではGregorian calendarに関する内容は見つかりませんでした.しかし、有名なC++boostライブラリにはGregorian Date Systemが含まれています.
    Ruby言語では、date.rb - date and time libraryはGregorian calendarを正しく処理することができる.
    Python言語では、datetime — Basic date and time typesはGregorian calendarを正しく処理することができる.
    Perl言語では、Date::Calc - Gregorian calendar date calculationsはGregorian calendarを正しく処理することができる.
     

    参考資料

  • Gregorian calendar
  • Julian calendar
  • .NET Framework Class Library: Calendar Class
  • .NET Framework Class Library: GregorianCalendar Class
  • .NET Framework Class Library: JulianCalendar Class
  • .NET Framework Class Library: ChineseLunisolarCalendar Class
  • Visual J# Redistributable Packages
  • java.util.GregorianCalendar
  • java.util.GregorianCalendar(中国語)
  • C Library: ctime (time.h)
  • C Library: ctime (time.h): struct tm  
  • boost: Gregorian
  • Ruby: date.rb - date and time library
  • Python: datetime — Basic date and time types
  • Perl: Date::Calc - Gregorian calendar date calculations