闰年计算

46 algorithm calendar leap-year

为了找到闰年,为什么一年必须与100不可分割并被400整除?我理解为什么它必须被4整除.请解释算法.

Pet*_*ter 102

一年的长度是(或多或少)365.242196天.因此,我们必须或多或少地减去一天中的四分之一以使其适合:

365.242196 - 0.25 = 364.992196 (由4年增加1天):但是哎呀,现在是太小了!让我们添加一天中的一天(通过不在一百年内添加一天:-))

364.992196 + 0,01 = 365.002196(哎呀,有点太大了,让我们在400年左右的时间里添加一天)

365.002196 - 1/400 = 364.999696

现在几乎就在那里,偶尔玩一下leapseconds,你就定了.

(注意:在此步骤之后不再应用更正的原因是因为一年也改变了长度!!这就是为什么leapseconds是最灵活的解决方案,请参见此处)

这就是我猜的原因

  • 你可能想提一下,由于古老的朱利安历法没有这些修正,因此小差异确实很重要,到了16世纪,日历对于天文事件(如至日)和(更重要的是)复活节日期超过10天. (4认同)
  • 为了兴趣,目前的闰年计算系统的原始资料是教皇格雷戈里十三世于1582年发布的题为"格拉夫西奥"的文件. (4认同)

Geo*_*lly 78

维基百科上有一个算法来确定闰年:

function isLeapYear (year):
    if ((year modulo 4 is 0) and (year modulo 100 is not 0))
    or (year modulo 400 is 0)
        then true
    else false
Run Code Online (Sandbox Code Playgroud)

维基百科页面上有关于此主题的大量有关闰年的信息,包含有关不同日历的包含信息.


Iva*_*nov 14

一般而言,计算闰年的算法如下......

如果一年可以被4整除,那么一年将是闰年.如果一年可以被4和100整除,那么除非它可以被400整除,否则它不是闰年.

因此,如1996年,1992年,1988年等年份是闰年,因为它们可被4整除,但不能被100整除.对于世纪年来,400规则很重要.因此,1900年,1800年和1700年的世纪,虽然仍然被4整除,但也可以被100整除.因为它们不能被400整除,所以它们不是闰年


x0v*_*x0v 10

这足以检查一年是否是闰年.

if( (year%400==0 || year%100!=0) &&(year%4==0))
    cout<<"It is a leap year";
else
    cout<<"It is not a leap year";
Run Code Online (Sandbox Code Playgroud)


The*_*hos 8

a)年份为365.242199天.

b)如果每年是365天,那么在100年内我们将失去24.2199天.这就是为什么我们每个世纪增加24天(每4年除以100除外)

c)但我们仍然损失0.21299天/世纪.所以在4个世纪里我们失去了0.8796天.这就是为什么我们每4个世纪增加1天(每四个世纪我们算一个闰年).

d)但这意味着我们每四百年(4世纪)失去-0.1204天(我们前进).因此,在8年四百年(3200年)中,我们不计算闰年.

e)但这意味着我们每3200年损失0.0368天.因此,在24x3200年(= 76800年),我们失去了0.8832天.这就是我们算闰年的原因.

等......(到那时我们将摧毁这个星球,所以没关系)

但是我无法理解的是,为什么我们不计算每500年而不是400年的闰年.这样我们就会更快地收敛到正确的时间(我们将失去2.3小时/ 500年).


chi*_*ien 6

我确信维基百科能够比我能更好地解释它,但这基本上与这样一个事实有关:如果你每四年增加一天,我们就会超越太阳,因为它绕太阳公转的时间要少于365.25天,所以我们通过不添加闰天来补偿这一点,这些年份不能被400整除,例如1900年.

希望有所帮助


Esk*_*edt 5

如果输入年份是闰年,则返回 true

基本的现代代码:

  If year mod 4 = 0, then leap year
  if year mod 100 then normal year
  if year mod 400 then leap year
  else normal year
Run Code Online (Sandbox Code Playgroud)

今天的规则始于公元 1582 年儒略历规则,每四年开始于公元前 46 年,但在塞萨尔宣布的公元 10 年之前并不一致。然而,他们确实每隔三年添加一些闰年:因此,闰年是公元前 45 年、公元前 42 年、公元前 39 年、公元前 36 年、公元前 33 年、公元前 30 年、公元前 27 年、公元前 24 年、公元前 21 年、公元前 18 年BC、15 BC、12 BC、9 BC、8 AD、12 AD 45BC 之前不添加闰年。

0 年不存在,因为它是...2BC 1BC 1AD 2AD...对于某些计算来说这可能是一个问题。

function isLeapYear(year: Integer): Boolean;
begin
  result := false;
  if year > 1582 then // Todays calendar rule was started in year 1582 
    result := ((year mod 4 = 0) and (not(year mod 100 = 0))) or (year mod 400 = 0)
  else if year > 10 then // Between year 10 and year 1582 every 4th year was a leap year 
    result := year mod 4 = 0
  else //Between year -45 and year 10 only certain years was leap year, every 3rd year but the entire time
    case year of
      -45, -42, -39, -36, -33, -30, -27, -24, -21, -18, -15, -12, -9:
        result := true;
    end;
end;
Run Code Online (Sandbox Code Playgroud)


小智 5

这是使用javascript三元运算符的维基百科算法的简单实现:

isLeapYear = (year % 100 === 0) ? (year % 400 === 0) : (year % 4 === 0);
Run Code Online (Sandbox Code Playgroud)

  • 这比“if”语句效率低。即使一次就足够了,在每种情况下你都必须进行两次比较。对正态分布数据集执行的计算在 75% 的情况下将无法通过“%4”测试,因此您应该首先执行此操作,如果错误,请立即退出。 (2认同)