расчет високосного года - PullRequest
46 голосов
/ 07 апреля 2009

Чтобы найти високосные годы, почему год должен делиться на 100 и делиться на 400? Я понимаю, почему он должен делиться на 4. Пожалуйста, объясните алгоритм.

Ответы [ 24 ]

100 голосов
/ 07 апреля 2009

Продолжительность года составляет (более или менее) 365,242196 дней. Таким образом, мы должны вычесть, более или менее, четверть дня, чтобы привести его в соответствие:

365.242196 - 0,25 = 364.992196 (добавив 1 день в 4 года): но, к сожалению, теперь это слишком мало !! давайте добавим сотню дней (не добавляя этот день раз в сто лет: -))

364.992196 + 0,01 = 365.002196 (упс, немного больше, давайте добавим этот день в любом случае один раз за 400 лет)

365.002196 - 1/400 = 364.999696

Почти сейчас, просто время от времени играйте с прыжковыми секундами, и все готово.

(Примечание: причина, по которой больше не вносятся исправления после этого шага, заключается в том, что год также ИЗМЕНЕНА В ДЛИНУ !!

Вот почему я думаю

74 голосов
/ 07 апреля 2009

В википедии есть алгоритм для определения високосных лет:

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

На странице Википедии много информации о високосных годах , включая информацию о различных календарях.

14 голосов
/ 07 апреля 2009

В общих чертах алгоритм расчета високосного года выглядит следующим образом ...

Год будет високосным, если он делится на 4, но не на 100. Если год делится на 4 и 100, это не високосный год, если он также не делится на 400.

Таким образом, такие годы, как 1996, 1992, 1988 и т. Д. Являются високосными, потому что они делятся на 4, а не на 100. Для вековых лет важно правило 400. Таким образом, столетние годы 1900, 1800 и 1700, хотя все они еще делятся на 4, также делятся точно на 100. Поскольку они не делятся далее на 400, они не являются високосными годами

9 голосов
/ 30 августа 2014

этого достаточно, чтобы проверить, является ли год високосным.

if( (year%400==0 || year%100!=0) &&(year%4==0))
    cout<<"It is a leap year";
else
    cout<<"It is not a leap year";
9 голосов
/ 09 августа 2015

а) Год составляет 365,242199 дней.

б) Если бы каждый год был 365 дней, то через 100 лет мы потеряли бы 24,2199 дней. Вот почему мы добавляем 24 дня в столетие (каждые 4 года, КРОМЕ, когда делится на 100)

в) Но мы все равно теряем 0,21299 дней / век. Таким образом, за 4 века мы теряем 0,8796 дней. Вот почему мы добавляем 1 день за 4 века (каждый четвертый век мы считаем високосным годом).

г) Но это означает, что мы теряем -0,1204 дня (мы идем вперед) за четырехлетие (4 века). Таким образом, в 8 четырехлетии (3200 лет) мы НЕ считаем високосный год.

д) Но это означает, что мы теряем 0,0368 дней на 3200 лет. Таким образом, за 24x3200 лет (= 76800 лет) мы теряем 0,8832 дня. Вот почему мы считаем високосный год.

и так далее ... (к тому времени мы уничтожим планету, так что это не имеет значения)

Однако я не могу понять, почему мы не считаем високосный год каждые 500 лет вместо 400. Таким образом, мы быстрее сходимся к правильному времени (мы потеряли бы 2,3 часа / 500 лет ).

6 голосов
/ 07 апреля 2009

Я уверен, Википедия может объяснить это лучше, чем я, но это в основном связано с тем фактом, что если вы добавляете дополнительный день каждые четыре года, мы опередим солнце время его обращения вокруг Солнца составляет менее 365,25 дней, поэтому мы компенсируем это, не добавляя високосных дней в годы, которые не делятся на 400, например, 1900.

Надеюсь, что поможет

5 голосов
/ 18 октября 2016

Вот простая реализация алгоритма википедии с использованием троичного оператора javascript:

isLeapYear = (year % 100 === 0) ? (year % 400 === 0) : (year % 4 === 0);
4 голосов
/ 12 марта 2014

Возвращает 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

Сегодняшнее правило началось в 1582 году нашей эры. Правило юлианского календаря с каждым 4-м годом начиналось с 46 г. до н.э., но оно не является последовательным до 10 г. н.э., как заявил Цезарь. Тем не менее, они добавляли несколько високосных лет каждый третий год, а затем и в предыдущие годы: Таким образом, високосные годы были 45 г. до н.э., 42 г. до н.э., 39 г. до н.э., 33 г. до н.э., 30 г. до н.э., 27 г. до н.э., 24 г. до н.э., 18 г. до н.э., 15 г. до н.э., 12 г. до н.э. До года 45BC високосный год не добавлялся. http://www.wwu.edu/depts/skywise/leapyear.html

Год 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;
2 голосов
/ 07 апреля 2009

Вы действительно должны сначала попробовать Google.

В Википедии есть объяснение високосных лет . Алгоритм , который вы описываете, предназначен для Григорианского календаря .

.

Подробнее о математике можно найти в статье Алгоритмы календаря .

1 голос
/ 04 марта 2017

PHP:

// is number of days in the year 366?  (php days of year is 0 based)
return ((int)date('z', strtotime('Dec 31')) === 365);
...