Алгоритм расчета дня недели
Сравнение Целлера — это алгоритм, разработанный Кристианом Целлером в 19 веке для вычисления дня недели для любой даты юлианского или григорианского календаря . Можно считать, что он основан на преобразовании между юлианским днем и календарной датой.
Формула
Для григорианского календаря соответствие Целлера равно
для юлианского календаря это
где
- h — день недели (0 = суббота, 1 = воскресенье, 2 = понедельник, ..., 6 = пятница)
- q — день месяца
- m — месяц (3 = март, 4 = апрель, 5 = май, ..., 14 = февраль)
- К год столетия ( ).
- J — это век , отсчитываемый от нуля (фактически ). Например, века, отсчитываемые от нуля, для 1995 и 2000 годов — это 19 и 20 соответственно (не путать с общепринятой порядковой нумерацией веков, которая указывает на 20-е в обоих случаях).
- это функция пола или целая часть
- mod — операция по модулю или остаток от деления
Примечание: В этом алгоритме январь и февраль считаются как 13 и 14 месяцы предыдущего года. Например, если это 2 февраля 2010 года (02/02/2010 в формате ДД/ММ/ГГГГ), алгоритм считает дату вторым днем четырнадцатого месяца 2009 года (14/02/2009 в формате ДД/ММ/ГГГГ)
Для даты недели ISO День недели d (1 = понедельник, 7 = воскресенье) используйте
Анализ
Эти формулы основаны на наблюдении, что день недели развивается предсказуемым образом на основе каждой подчасти этой даты. Каждый член в формуле используется для расчета смещения, необходимого для получения правильного дня недели.
Таким образом, для григорианского календаря различные части этой формулы можно понимать следующим образом:
- представляет собой прогрессию дня недели на основе дня месяца, поскольку каждый последующий день приводит к дополнительному смещению дня недели на 1.
- представляет собой прогрессию дня недели на основе года. Предполагая, что каждый год длится 365 дней, та же дата в каждом последующем году будет смещена на значение .
- Поскольку в каждом високосном году 366 дней, это необходимо учитывать, добавляя еще один день к значению смещения дня недели. Это достигается путем прибавления к смещению. Этот термин вычисляется как целочисленный результат. Любой остаток отбрасывается.
- Используя аналогичную логику, можно рассчитать последовательность дней недели для каждого столетия, заметив, что в обычном столетии 36 524 дня, а в каждом столетии 36 525 дней, делящихся на 400. Поскольку и , термин учитывает это.
- Термин корректирует изменение дней месяца. Начиная с января, дни в месяце {31, 28/29, 31, 30, 31, 30, 31, 30, 31, 30, 31}. 28 или 29 дней февраля являются проблемой, поэтому формула переносит январь и февраль к концу, так что короткий счет февраля не вызовет проблем. Формула интересуется днями недели, поэтому числа в последовательности можно взять по модулю 7. Тогда количество дней в месяце по модулю 7 (все еще начиная с января) будет {3, 0/1, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3}. Начиная с марта, последовательность в основном чередуется 3, 2, 3, 2, 3, но каждые пять месяцев подряд идут два месяца по 31 день (июль–август и декабрь–январь). [1] Дробь 13/5 = 2,6 и функция пола имеют такой эффект; знаменатель 5 задает период в 5 месяцев.
- Общая функция нормализует результат так, чтобы он находился в диапазоне от 0 до 6, что дает индекс правильного дня недели для анализируемой даты.
Причина, по которой формула различается в разных календарях, заключается в том, что в юлианском календаре нет отдельного правила для високосных столетий, и он смещен относительно григорианского календаря на фиксированное количество дней в каждом столетии.
Поскольку григорианский календарь был принят в разное время в разных регионах мира, местоположение события имеет важное значение для определения правильного дня недели для даты, которая произошла в этот переходный период. Это требуется только до 1929 года, так как это был последний год, когда юлианский календарь все еще использовался какой-либо страной на земле, и, таким образом, не требуется для 1930 года или позже.
Формулы можно использовать пролептически, но «год 0» на самом деле является годом 1 до н. э. (см. астрономическую нумерацию лет ). Юлианский календарь на самом деле является пролептическим вплоть до 1 марта 4 г. н. э. из-за неправильного управления в Риме (но не в Египте) в период с момента введения календаря в действие 1 января 45 г. до н. э. (который не был високосным годом). Кроме того, оператор modulo может усекать целые числа в неправильном направлении (потолок вместо пола). Чтобы учесть это, можно добавить достаточное количество кратных 400 григорианских или 700 юлианских лет.
Примеры
Для 1 января 2000 года дата будет рассматриваться как 13-й месяц 1999 года, поэтому значения будут следующими:
Таким образом, формула оценивается как .
(36 получается из , усеченного до целого числа.)
Однако 1 марта 2000 года дата рассматривается как 3-й месяц 2000 года, поэтому значения становятся
поэтому формула оценивается как .
Реализации в программном обеспечении
Базовая модификация
Формулы основаны на математическом определении деления по модулю , что означает, что −2 mod 7 равно положительному числу 5. К сожалению, в усеченном способе, которым большинство компьютерных языков реализуют функцию остатка, −2 mod 7 возвращает результат −2. Таким образом, чтобы реализовать сравнение Целлера на компьютере, формулы следует немного изменить, чтобы обеспечить положительный числитель. Самый простой способ сделать это — заменить − 2 J на + 5 J и − J на + 6 J .
Для григорианского календаря соответствие Целлера становится
Для юлианского календаря сравнение Целлера принимает вид
Легко заметить, что в данном году последний день февраля и 1 марта являются хорошими датами проверки.
В качестве примечания, если у нас есть трехзначное число abc, где a, b и c — цифры, каждая из которых неположительна, если abc неположительна; мы имеем (abc) mod 7 = 9*a + 3*b + c. Повторите формулу до одной цифры. Если результат равен 7, 8 или 9, то вычтите 7. Если же результат отрицательный, то прибавьте 7. Если результат все еще отрицательный, то прибавьте 7 еще раз. Используя этот подход, мы можем избежать беспокойства о языковых различиях в оценках mod 7. Это также может улучшить технику устного счета.
Обычное упрощение
Целлер использовал десятичную арифметику и нашел удобным использовать J и K для представления года. Но при использовании компьютера проще оперировать измененным годом Y и месяцем m , которые равны Y - 1 и m + 12 в течение января и февраля:
Для григорианского календаря соответствие Целлера становится
В этом случае нет возможности возникновения недопополнения из-за единственного отрицательного члена, поскольку .
Для юлианского календаря сравнение Целлера принимает вид
Приведенный выше алгоритм упоминается для григорианского календаря в RFC 3339, Приложение B, хотя и в сокращенной форме, которая возвращает 0 для воскресенья.
Другие вариации
По крайней мере три других алгоритма разделяют общую структуру сравнения Целлера в его типе «общего упрощения», также используя m ∈ [3, 14] ∩ Z и конструкцию «модифицированного года».
- Майкл Кейт опубликовал фрагмент очень короткого кода на языке C в 1990 году для дат по григорианскому календарю. Компонент длины месяца ( ) заменен на . [2]
- JR Stockton предлагает версию Sunday-is-0 с , называя ее вариацией Zeller. [2]
- Клаус Тёндеринг описывает его как замену «воскресенья-0». [3]
Можно показать, что оба выражения изменяются таким образом, что отклоняются на единицу по сравнению с исходным компонентом длины месяца в требуемом диапазоне m , что приводит к начальному значению 0 для воскресенья.
Смотрите также
Ссылки
- ^ Правило «каждых пяти месяцев» применяется только к двенадцати месяцам года, начинающимся 1 марта и заканчивающимся в последний день следующего февраля.
- ^ ab Stockton, J R. "Material Related to Zeller's Congruence". "Merlyn", архивировано в NCTU Taiwan .
- ^ Тендеринг, Клаус. «Вопросы недели». www.tondering.dk .
Библиография
Каждая из этих четырех похожих иллюстрированных статей посвящена, во-первых, дню недели, а во-вторых, дате Пасхального воскресенья по юлианскому и григорианскому календарям. Страницы ссылаются на переводы на английский язык.
- Целлер, Кристиан (1882). «Die Grundaufgaben der Kalenderrechnung auf neue und vereinfachte Weise gelöst». Württembergische Vierteljahrshefte für Landesgeschichte (на немецком языке). В : 313–314. Архивировано из оригинала 11 января 2015 года.
- Целлер, Кристиан (1883). «Проблема дуплексного календаря». Бюллетень математического общества Франции (на латыни). 11 : 59–61. Архивировано из оригинала 11 января 2015 года.
- Целлер, Кристиан (1885). «Календер-Формельн». Mathematich-naturwissenschaftliche Mitteilungen des mathematich-naturwissenschaftlichen Vereins в Вюртемберге (на немецком языке). 1 (1): 54–58. Архивировано из оригинала 11 января 2015 года.
- Целлер, Кристиан (1886). «Календер-Формельн». Acta Mathematica (на немецком языке). 9 : 131–136. дои : 10.1007/BF02406733 .
Внешние ссылки
- Календарные работы ректора Хр. Целлера: Формулы дня недели и пасхи Дж. Р. Стоктона, недалеко от Лондона, Великобритания. На сайте размещены изображения и переводы четырех вышеупомянутых статей, а также справочная карточка Целлера "Das Ganze der Kalender-Rechnung".
- В этой статье использованы материалы, находящиеся в открытом доступе, от Пола Э. Блэка. "Конгруэнтность Целлера". Словарь алгоритмов и структур данных . NIST .