Вычисление количества дней в месяце

Автор: | 2018-09-13

При работе с датами в системах без RTC, например в простых часах на микроконтроллере, в обработчике прерывания от таймера инкрементируются переменная секунды и при её выходе за границу диапазона, увеличивается минута, при выходе минуты за границу — час и так далее. И если с секундами, минутами и часами всё просто, то при увеличении дней необходимо учитывать количество дней в месяце, которое мало того, что не регулярное, так ещё и зависит от года. Как-то раз, я задумался — а нет ли зависимости между номером месяца и его длиной?

Так как родная система счисления для вычислительных машин — двоичная, то переведём в неё номера месяцев и зададим соответствие с количеством дней:

Пока ничего не видно, но была уверенность, что что-то есть, праздник всё-таки.

Сгруппируем длинные и короткие месяцы:

Внимательно присмотревшись, можно заметить, что если результат выполнения операции исключающее или над первым и четвёртым битом номера месяца равен «1», то месяц длинный, иначе — короткий.
Осталось только проверить год на високосность, напомню, что правила следующие:

  • год, номер которого кратен 400, — високосный;
  • остальные годы, номер которых кратен 100, — невисокосные;
  • остальные годы, номер которых кратен 4, — високосные.

В коде, на языке Си, это выглядит так:

Как правило, если ты что-либо придумал, то скорее всего это уже придумали ещё в эпоху Возрождения ранее. Но беглый поиск в Интернете показал, что нет. Однако, на Хабре была найдена отличная статья, описывающая метод, решающий подобную задачу.
Ну и наконец проведём замеры объёма кода. Напишем абстрактный код для микроконтроллера AVR, где флеш и ОЗУ — ресурс крайне ценный, который будет делать инкремент даты, для простоты — только день и месяц, четырьмя разными способами:

  • по таблице;
  • непосредственным сравнением дат;
  • методом с Хабра;
  • «бинарным методом».

По очереди раскомментируем блоки кода, компиллируем и смотрим результаты:

Вывод: метод имеет право на существование. Всех с праздником!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *