为什么从公元 1 年到 2001 年 1 月 1 日的历日总和与回归日相差 3?
Why does the sum of calendar days from 1. AD to 1.1.2001 differ from tropical days by 3?
作为一个小背景:1582 年 10 月,Gregorian calendar 被引入以纠正 Julian 日历的问题,该日历一直沿用至今。公历更精确地指定一年的长度,添加新的闰年计算并在过渡时从儒略历中删除 10 天(从 4.Oct.1582 移动到 15.Oct.1582)
// Julian leap year calculation
((year % 4) == 0)
// Gregorian leap year calculation
((year % 4) == 0 && (year % 100) != 0) || (year % 400) == 0)
为了总结从公元 1 年到 2001 年的所有日历日,我使用:
#include <stdio.h>
int main( void)
{
int year;
int daysInYear;
int total;
total = 0;
for( year = 1; year <= 2001; year++)
{
//
daysInYear = 365;
if( year < 1582)
daysInYear += ((year % 4) == 0);
else
if( year > 1582)
daysInYear += ((year % 4) == 0 && (year % 100) != 0) || ((year % 400) == 0);
else
daysInYear -= 10; // 1582 exactly
total += daysInYear;
printf( "%d: +%d = %d\n", year, daysInYear, total);
}
return( 0);
}
现在 运行 从 1 到 2000 年的所有年份都详尽地给出了这个 pastebin:https://pastebin.com/bR7hwNr1
最有趣的位表明闰年和跳日计算是正确的,并且还产生了结果:
1: +365 = 365
2: +365 = 730
3: +365 = 1095
4: +366 = 1461
...
100: +366 = 36525
...
400: +366 = 146100
...
1581: +365 = 577460
1582: +355 = 577815
1583: +365 = 578180
...
1900: +365 = 693962
...
1996: +366 = 729026
1997: +365 = 729391
1998: +365 = 729756
1999: +365 = 730121
2000: +366 = 730487
现在的问题是:1.1.2001 已过去 730487 个日历日。鉴于公历定义的一年长度为 365.2425,我希望看到 2000*365.2425 = 730485 天。如果使用 tropical days 或太阳日,则为 730484。但 740487 显然超出范围。
假设没有人算错公历范围内的任何日子,则儒略历中有一些额外的日子,与热带日子不匹配。但是公历是为了纠正儒略历而创建的,我认为他们不会在 1582 年犯那么大的错误。
我猜这可能是一个历史问题,而不是编程问题。
公历改革的目标是将北半球春分的日期重置为 3 月 21 日,并保持在那里。之所以选择这个日期,是因为那是公元 325 年尼西亚会议召开时的平均春分日期。在会议召开时,春分日期已从公元 1 年的 3 月 25 日左右下滑。
有关详细信息,请阅读 Gregorian Reform of the Calendar 这本书,该书是梵蒂冈天文台于 1983 年出版的会议记录。
澄清一下,在将公历与儒略历进行比较时,混合使用儒略历和公历日期包含对 10 天的 one-time 校正,该校正旨在校正从大约 AD 开始的累积超额闰年325 年到公元 1582 年。如果希望使用公元 325 年以外的某个开始日期,则整个计算应仅使用公历日期或儒略日期。
作为一个小背景:1582 年 10 月,Gregorian calendar 被引入以纠正 Julian 日历的问题,该日历一直沿用至今。公历更精确地指定一年的长度,添加新的闰年计算并在过渡时从儒略历中删除 10 天(从 4.Oct.1582 移动到 15.Oct.1582)
// Julian leap year calculation
((year % 4) == 0)
// Gregorian leap year calculation
((year % 4) == 0 && (year % 100) != 0) || (year % 400) == 0)
为了总结从公元 1 年到 2001 年的所有日历日,我使用:
#include <stdio.h>
int main( void)
{
int year;
int daysInYear;
int total;
total = 0;
for( year = 1; year <= 2001; year++)
{
//
daysInYear = 365;
if( year < 1582)
daysInYear += ((year % 4) == 0);
else
if( year > 1582)
daysInYear += ((year % 4) == 0 && (year % 100) != 0) || ((year % 400) == 0);
else
daysInYear -= 10; // 1582 exactly
total += daysInYear;
printf( "%d: +%d = %d\n", year, daysInYear, total);
}
return( 0);
}
现在 运行 从 1 到 2000 年的所有年份都详尽地给出了这个 pastebin:https://pastebin.com/bR7hwNr1
最有趣的位表明闰年和跳日计算是正确的,并且还产生了结果:
1: +365 = 365
2: +365 = 730
3: +365 = 1095
4: +366 = 1461
...
100: +366 = 36525
...
400: +366 = 146100
...
1581: +365 = 577460
1582: +355 = 577815
1583: +365 = 578180
...
1900: +365 = 693962
...
1996: +366 = 729026
1997: +365 = 729391
1998: +365 = 729756
1999: +365 = 730121
2000: +366 = 730487
现在的问题是:1.1.2001 已过去 730487 个日历日。鉴于公历定义的一年长度为 365.2425,我希望看到 2000*365.2425 = 730485 天。如果使用 tropical days 或太阳日,则为 730484。但 740487 显然超出范围。
假设没有人算错公历范围内的任何日子,则儒略历中有一些额外的日子,与热带日子不匹配。但是公历是为了纠正儒略历而创建的,我认为他们不会在 1582 年犯那么大的错误。
我猜这可能是一个历史问题,而不是编程问题。
公历改革的目标是将北半球春分的日期重置为 3 月 21 日,并保持在那里。之所以选择这个日期,是因为那是公元 325 年尼西亚会议召开时的平均春分日期。在会议召开时,春分日期已从公元 1 年的 3 月 25 日左右下滑。
有关详细信息,请阅读 Gregorian Reform of the Calendar 这本书,该书是梵蒂冈天文台于 1983 年出版的会议记录。
澄清一下,在将公历与儒略历进行比较时,混合使用儒略历和公历日期包含对 10 天的 one-time 校正,该校正旨在校正从大约 AD 开始的累积超额闰年325 年到公元 1582 年。如果希望使用公元 325 年以外的某个开始日期,则整个计算应仅使用公历日期或儒略日期。