Главная страница Visual 2000 · Общий список статей

Y2K: как вести календарь?
Похоже, в алгоритме Microsoft есть ошибка

Андрей Колесов

© 1999, Андрей Колесов
Авторский вариант. Статья была опубликована c незначительной литературной правкой в журнале "КомпьютерПресс" № 7/99. Это — вторая часть общей статьи "Проблема 2000 и технологии Microsoft".

До сведения широкой общественности уже доведена информация о том, что одна из ошибок "Проблемы Y2K" в неких приложениях связана с неверным определением 2000 года как високосного. (Правда, как это повелось в дискуссиях на данную тему, не было приведено никаких конкретных примеров.) Оказалось, что широкие массы как пользователей, так и разработчиков ПО даже не знали, что с детства известный алгоритм определения високосного года — деление на четыре без остатка — не совсем точен. Но потом программисты облегченно вздохнули, узнав, что он вполне подходит еще для ближайших ста лет: 2000 год действительно является високосным как исключение из ряда вековых лет (номера которых оканчиваются на два нуля).

Так или иначе, но корпорация Microsoft в своем критерии соответствия ПО проблеме Y2K (www.microsoft.com/techtet/year2k/criteria.htm) включила отдельный пункт: "Правильное определение високосного года". Но дело в том, что данная постановка вопроса явно недостаточна. Речь-то идет о проблеме правильного ведение календаря, в котором вопрос високосного года является частным. Ведь если кто-то решил убрать 29 февраля из календаря 2000 года (интересно — исходя из каких соображений?), то другой может с таким же успехом определить число дней в августе равным 30 (так было до 8 года до н.э.).

Рассматривая же вопрос именно с такой точки зрения, возникают очень серьезные сомнения в правильности алгоритма работы с датами, заложенного в средства разработки Microsoft. Те, кто имеют дело с бизнес-задачами, можете не волноваться — там, вроде бы, все в порядке. Но кто работает с историческими датами, тем следует прочитать эту статью до конца.

Средства разработки Microsoft (буду говорить на примере Visual Basic) обеспечивают поддержку специального формата данных для даты, которая может изменяться в диапазоне от 01.01.100 до 31.12.9999. Для работы с датами в VB имеется большой набор функций, хотя в принципе задача сводится к одной — определению даты и дня недели следующих и предыдущих суток по сравнению с текущими.

Вопрос: какой был день накануне пятницы 15 октября 1582 года? Скорее всего, каждый даст очевидный ответ (а программы Microsoft его дают однозначно): четверг 14 октября 1582 года. И будут неправы. Если считать по григорианскому календарю (новый стиль), то это действительно четверг, но 4 октября. Если же имеется в виду юлианский календарь (старый стиль), то 15 октября был понедельник, а накануне — 14 октября, воскресенье.

Здесь полезно вспомнить об истории календарей. Основа современного календаря была заложена реформой Юлия Цезаря в 46 до н.э. После ряда уточнений спустя 50 лет календарь принял современный вид. За исключением порядка определения високосного года. В юлианском календаре средняя длина года была принята 365,25 суток, поэтому високосным считался каждый четвертый год. Исследования астрономов еще в средние века позволили определить, что в этой величине имеется погрешность (солнечный года меньше на 11 мин 14 сек), из-за чего за каждые 128 лет накапливалась ошибка в 1 сутки.

В результате получилось, что к концу 16-го века дата весеннего равноденствия приходилась не на 21 марта (как это было в 325 году, когда христианская церковь приняла юлианский календарь в качестве официального), а на 11 марта. А день весеннего равноденствия издавна является ключевой точкой для счета времени в истории человечества.

Ошибка в календаре была исправлена папой римским Григорием XIII, который в 1582 год своей буллой передвинул счет дней на 10 дней вперед: день после четверга 4 октября предписывалось считать пятницей, но не 5, а 15 октября. Чтобы избежать накопления новой ошибки в будущем, был также изменен порядок вычисления високосных годов: из их числа исключаются вековые годы (с двумя нулями в конце) кроме тех, число сотен которых делится без остатка на четыре. Такими годами являются 1700, 1800, 1900, 2100 и пр. Но 2000 год — високосный, причем во всех календарях: и юлианском, и григорианском!

Вывод из этого можно сделать следующий: нельзя использовать алгоритм вычисления даты по григорианскому календарю по временной шкале вниз от 15 октября 1582 года. Но именно так делается в средствах разработки Microsoft (логической точкой отсчета алгоритма является 30.12.1899, суббота).

Простой пример — в григорианском календаре просто нет дат с 6 по 14 октября 1582 года, и вся информация об исторических событиях в предыдущий период приводится в старом стиле. С сегодняшней точки зрения разница в несколько дней, казалось бы, является пустяком, но для историка вопрос, предположим, привязки даты к дню недели может уже быть принципиально важной (Куликовская битва — 08.09.1380 — произошла до или после выходного дня?). Не говоря уже о том, что в истории человечества был, например, день 29 февраля 1500 года, который с точки зрения Visual Basic является недопустимой датой.

Но еще более внимательно нужно относиться к работе с датами с конца 16-го до начала 20 веков. Ведь переход разных стран со старого на новый стиль был не одновременным. Например, Франция, Италия и Испания перешли на григорианский календарь в 16-веке, Германия — в 17-м, Англия — в 18-м, Япония — в 19-м, Россия и Китай — в начале 20-го. Все это уже положило появлению огромного числа исторических мифов: о том, что граф Калиостро в один день мог прибывать и в Петербурге, и в Берлине; что парусники с фантастической скоростью переплывали Атлантику и пр.

Вывод из сказанного таков. При работе с историческими датами после 4 октября 1582 года просто необходима возможность работы с датами в новом и старом стиле. Но использование алгоритма григорианского календаря в обратную сторону от даты его введения, скорее всего, является ошибкой. Например, если мы будем использовать алгоритм Microsoft, то получим, что даты Рождества Христова (25 декабря), т.е. собственно момент рождения, совпадают в юлианском и григорианском календарях только в 3-м веке нашей эры, а не в первом, как это вроде бы должно быть.

В реальной жизни данная проблема, вряд ли, затронет кого-либо всерьез. Однако вспомним — знаменитая эпопея с заменой Pentium пять лет назад начиналась также с ошибки, вероятность которой исчислялась миллионным долями. И была она обнаружена при довольно экзотических астрономических расчетах.

В начало статьи