我们先看看以下 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: }
其运行结果如下:
这么看来,一五八二年十月四日是星期一。
真的如此吗?我们来看看以下 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 操作系统下进行编译和运行:
注意,java.util.GregorianCalendar 类的构造函数中月份是从 0 起始的,因此 9 表示十月。
可以看出以下两点:
- 一五八二年十月四日是星期四。
- 一五八二年十月四日的下一天是:一五八二年十月十五日,星期五。
到底谁是正确的呢?
我们来看看 java.util.GregorianCalendar 类的说明吧:
这样就清楚了,Java 平台是正确的,而 .NET Framework Base Class Library 中的 DateTime 是有问题的。
Gregorian calendar 也就是我国现行的公历。
在 Ubuntu 10.04 操作系统下运行以下命令:
可以看到一五八二年十月四日的确是星期四,而且其下一天是一五八二年十月十五日星期五,因此一五八二年十月只有二十一天。
如果下载了 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 。这个程序的运行结果如下:
可以看出,一五八二年十月四日的确是星期四。但是,其下一天怎么变成了一五八二年九月二十五日星期二了?看来微软的 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