DateTime類型的一個Bug
先說一個歷史故事,關于我們現在的陽歷:
現行的公歷是格利戈里歷法,這個歷法的是1582年教皇格利戈里根據愷撒大帝引進的算法改進的。它采用的是閏年制也就是現行的制度,不過有一個需要注意的地方就是,這個歷法并不是連續的,中間缺少了11天。1752年9月2日之后的那一天并不是1752年9月3日,而是1752年9月14日。也就是說,從1752年9月3日到1752年9月13日的11天并不存在。抹掉這11天是由英國議會做出的決定。所以要計算某年每個月的天數的,除了要考慮是否是閏年以外,還要考慮1752年的9月
詳細的情況可以查wiki百科:http://en.wikipedia.org/wiki/Gregorian_calendar
網上也有很多文章說這個事情。
于是我寫了一段代碼,測試.net framework提供的api,看看里面的datetime類是不是按這個歷法寫的:
class Program
{
static void Main(string[] args)
{
DateTime t = new DateTime(1752, 9, 1);
int month = t.Month;
while (month == t.Month)
{
Console.WriteLine(t.Year + "-" + t.Month + "-" + t.Day);
t = t.AddDays(1);
}
Console.Read();
}
}
{
static void Main(string[] args)
{
DateTime t = new DateTime(1752, 9, 1);
int month = t.Month;
while (month == t.Month)
{
Console.WriteLine(t.Year + "-" + t.Month + "-" + t.Day);
t = t.AddDays(1);
}
Console.Read();
}
}
編譯運行之后,結果發現:
1752-9-1
1752-9-2
1752-9-3
1752-9-4
1752-9-5
1752-9-6
1752-9-7
1752-9-8
1752-9-9
1752-9-10
1752-9-11
1752-9-12
1752-9-13
1752-9-14
1752-9-15
1752-9-16
1752-9-17
1752-9-18
1752-9-19
1752-9-20
1752-9-21
1752-9-22
1752-9-23
1752-9-24
1752-9-25
1752-9-26
1752-9-27
1752-9-28
1752-9-29
1752-9-30
1752-9-2
1752-9-3
1752-9-4
1752-9-5
1752-9-6
1752-9-7
1752-9-8
1752-9-9
1752-9-10
1752-9-11
1752-9-12
1752-9-13
1752-9-14
1752-9-15
1752-9-16
1752-9-17
1752-9-18
1752-9-19
1752-9-20
1752-9-21
1752-9-22
1752-9-23
1752-9-24
1752-9-25
1752-9-26
1752-9-27
1752-9-28
1752-9-29
1752-9-30
從3號到13號的日期仍然是存在的,這是不符合實際歷法的。
既然測試了.net,就把java的sdk也試試吧,于是寫了一個java代碼:
import java.util.*;
public class CalendarTest
{
public static void main(String[] args)
{
Calendar ca = Calendar.getInstance();//get instance of GregorianCalendar
ca.set(Calendar.YEAR, 1752);
ca.set(Calendar.MONTH, 9);
ca.set(Calendar.DAY_OF_MONTH, 1);
int month = ca.get(Calendar.MONTH);
while (month == ca.get(Calendar.MONTH))
{
System.out.println(ca.get(Calendar.YEAR) + "-" + ca.get(Calendar.MONTH) + "-" + ca.get(Calendar.DAY_OF_MONTH));
ca.add(Calendar.DAY_OF_MONTH, 1);
}
}
}
public class CalendarTest
{
public static void main(String[] args)
{
Calendar ca = Calendar.getInstance();//get instance of GregorianCalendar
ca.set(Calendar.YEAR, 1752);
ca.set(Calendar.MONTH, 9);
ca.set(Calendar.DAY_OF_MONTH, 1);
int month = ca.get(Calendar.MONTH);
while (month == ca.get(Calendar.MONTH))
{
System.out.println(ca.get(Calendar.YEAR) + "-" + ca.get(Calendar.MONTH) + "-" + ca.get(Calendar.DAY_OF_MONTH));
ca.add(Calendar.DAY_OF_MONTH, 1);
}
}
}
編譯運行:
java提供的api也不對。
這就是說,假如我們要寫一段程序,計算乾隆皇帝登基當皇帝距今有多少天,無論是用java還是.net,都要自己寫一個新的Calendar類了。
![]()
浙公網安備 33010602011771號