Сравнение данных с февралем високосного года (проблема 29 февраля)
Думаю, в практике многим приходится неоднократно сталкиваться с необходимостью разработки отчёта типа LFL (like for like), сравнивающего аналогичные периоды разных лет, например, текущего выбранного периода с аналогичным периодом прошлого года.
В новых конфигурациях такой отчёт есть в составе конфигурации (см. «Сравнение продаж аналогичных периодов»), а в старых обычно приходится добавлять.
Если не учесть нюанс сравнения с февралём високосного года, данные в отчёте за прошлый период могут быть некорректными.
- Описание
- Подробнее
Описание
В моём случае требовалось сравнивать данные периода с данными именно такого же периода, поэтому возможность выбора прошлого периода для пользователей была закрыта — прошлый период высчитывался просто как -12 месяцев от текущего выбранного периода.
При этом период можно выбирать с точностью до дней — это принципиально в данном случае, т.к. для полных месяцев эта проблема не актуальна.
Всё работало прекрасно до текущего года, когда данные за февраль пришлось сравнивать с данными февраля прошлого — високосного — года.
Отчёт разрабатывался на СКД, и для расчёта значения параметра КонецПрошлогоПериода использовалось следующее выражение СКД:
ДобавитьКДате(КонецПериода(&КонецПериода, "День"), "Месяц", -12)
Как легко догадаться, 28 февраля 2021 — 12 месяцев = 28 февраля 2020, явно не совсем то, что ожидает увидеть в отчёте пользователь.
Проблема решается простым способом: вначале добавляем к концу периода 1 секунду, потом вычитаем 12 месяцев, потом обратно вычитаем 1 секунду.
В итоге выражение принимает такой вид:
ДобавитьКДате(ДобавитьКДате(ДобавитьКДате(КонецПериода(&КонецПериода, "День"), "Секунда", 1), "Месяц", -12), "Секунда", -1)
На примере 28 февраля 2021:
- добавив 1 секунду к концу дня, получаем начало дня 01 марта 2021;
- вычтя 12 месяцев, получаем начало дня 01 марта 2020;
- вычтя 1 секунду, получаем конец дня 29 февраля 2020.