← На главную

Ruby не признаёт 10 пропавших дней 1582 года, а Python и Perl признают

01.08.2026 17:18 · hackernews

В 1582 году католический мир по булле Inter gravissimas перешёл с юлианского календаря на григорианский. Новый календарь сократил год с 365.25 до 365.2425 дня — всего на 0.002%. Отсюда современная система високосных годов: високосный каждый четвёртый и каждый 400-й год, но не остальные кратные 100. Поэтому 1900 был обычным, 1904 — високосным, а 2000 — тоже високосным.

К 1582 году юлианский календарь накопил дрейф, и чтобы компенсировать его, из года убрали десять дней. Выбор промежутка занял почти 20 лет: церковь не хотела переносить праздники и хотела поправить дату Пасхи. Убрали отрезок с 5 по 14 октября. Люди легли спать 4 октября, а проснулись 15 октября. Этих десяти дней в григорианском календаре просто нет.

Ruby делает правильно: создать DateTime на 5 октября 1582 нельзя, DateTime.new(1582, 10, 5) выбрасывает ArgumentError: invalid date. Проверка живёт в datetime_s_civil из ext/date/date_core.c и использует valid_gregorian_p.

Python, хотя обещает дату в «текущем григорианском календаре», так не считает. date(1582, 10, 5) спокойно создаётся, ctime() возвращает 'Tue Oct 5 00:00:00 1582'. Это одинаково для Python 2 и Python 3.

В Perl стандартного аналога DateTime или date нет, поэтому проверили модуль DateTime с CPAN. Он невозможную дату пропускает: код с DateTime->new(year => 1582, month => 10, day => 5) отрабатывает без ошибки на Perl 5.18 с DateTime 1.19. Отсутствие ошибки и есть ошибка.

Итого два языка из трёх позволяют создавать «григорианские» даты, которых не существовало. Это не Y2K и не проблема Unix epoch, но хороший показатель того, как обстоят дела с простой корректностью в реализации дат.

Отдельно проверили ncal(1). Возможно, это самый корректный инструмент: через флаг -s он принимает код страны и показывает, когда эта страна реально перешла на новый календарь. Например, Италия в октябре 1582 теряет дни 5–14, Великобритания в сентябре 1752 — дни 3–13. В добавлении от 30 июня 2026 Джон Костелло заметил, что ncal(1) всё равно не идеальна: она не учитывает шведские календарные сдвиги в XVIII веке.

Читать оригинал →