Это не полный ответ, но это какое-то объяснение.
Прежде всего
, если номер месяца меньше 3, год- = 1 и месяц + = 12
используется, чтобы эффективно начать год с марта, двигая крайне нерегулярный февраль к концу.На самом деле это то, как этот календарь был изначально разработан, который вы все еще можете увидеть в названиях некоторых месяцев, таких как октябрь или декабрь (вы, вероятно, слышали, что октябрь = 8 и декабрь = 10).
Удар 365*year + year/4 - year/100
просто обрабатывает високосные годы.
Часть day
также ясна.
Теперь давайте удалим биты, которые не имеют значения, когда мы вычитаемдва значения и получить это значение для month
30*month + (3*month - 2)/5
Я не знаю логики, как это было получено (у меня есть только предположение в конце), но я могу сказать, почему это работает.Бит 30*month
очевиден.И теперь, когда мы переместили февраль на его последнюю позицию, весь месяц в середине года имеет либо 30
, либо 31
день.Запишем их:
- Март - 31 - + 1
- Апр - 30 - + 0
- Май - 31 - + 1
- Июнь - 30 - + 0
- июль - 31 - + 1
- август - 31 - + 1
- сентябрь - 30 - + 0
- октябрь -31 - + 1
- ноя - 30 - + 0
- декабрь - 31 - + 1
- янв - 31 - + 1
Мыне волнует февраль, так как после него нет месяцев (мы заботились об этом раньше).Мы заботимся только об этом +1 дне, начиная со следующего месяца после этого!
Так что теперь нам нужна некоторая формула, которая бы соответствовала этому распределению +1
и +0
.И похоже, что значение
(3*month - 2)/5
с целочисленным делением делает именно это.Вы можете легко проверить это вручную.
Вероятно, чтобы придумать эту идею, было бы заметить, что год (кроме февраля) следует за следующим 5-месячным циклом
+ 1+0 +1 +0 + 1
Я имею в виду, что март-июль и август-декабрь точно совпадают, и затем январь снова +1, так что это похоже на первый элемент следующего цикла.