В платформе 1С:Предприятие существуют удобные встроенные функции для работы с датами, такие как КонецМесяца(), КонецКвартала() и КонецГода(). Однако разработчики часто сталкиваются с тем, что стандартной функции КонецПолугодия() не предусмотрено. В рамках данной статьи мы подробно разберем несколько способов решения этой задачи: от простых логических условий до изящных математических формул, а также рассмотрим возможности использования системных объектов платформы.
Разберем самый понятный и легко читаемый способ. Логика проста: в календарном году всего два полугодия. Первое заканчивается 30 июня, второе — 31 декабря. Нам достаточно проверить номер месяца исходной даты, чтобы определить, к какому полугодию она относится.
Рассмотрим пример функции, которую можно разместить в общем модуле:
Функция КонецПолугодия(Знач ВходящаяДата) Экспорт
МесяцДаты = Месяц(ВходящаяДата);
ГодДаты = Год(ВходящаяДата);
Если МесяцДаты <= 6 Тогда
// Первое полугодие заканчивается в июне
Возврат КонецДня(Дата(ГодДаты, 6, 30));
Иначе
// Второе полугодие — это конец года
Возврат КонецГода(ВходящаяДата);
КонецЕсли;
КонецФункции
Преимущества этого подхода:
КонецДня() гарантирует, что время будет установлено в 23:59:59, что критично для запросов и отчетов.Проанализируем ситуацию, когда нам нужно написать максимально короткий код, например, для вычисляемого поля или внутри сложного выражения. Существует изящный способ вычислить количество месяцев, которое нужно добавить к текущей дате, используя операцию получения остатка от деления.
Посмотрим на формулу, предложенную опытными разработчиками:
КонецПолугодия = КонецМесяца(ДобавитьМесяц(Дата, (12 - Месяц(Дата)) % 6));
Разберем по шагам, как это работает:
Месяц(Дата) — получаем порядковый номер месяца.12 - Месяц(Дата) — вычисляем остаток месяцев до конца года.% 6 — ключевой момент. Операция «остаток от деления на 6» позволяет нам найти смещение до ближайшей границы полугодия (либо до 6-го, либо до 12-го месяца).ДобавитьМесяц() — сдвигаем дату на нужное количество месяцев вперед.КонецМесяца() — устанавливаем последний день и время 23:59:59.Этот метод считается наиболее производительным, так как в нем отсутствуют ветвления (инструкции Если), что может быть полезно при обработке массивов данных в сотни тысяч строк.
Выясним, как решить задачу, используя возможности встроенных объектов платформы. В 1С существует объект СтандартныйПериод, который активно используется в СКД и формах отчетов. Он умеет автоматически определять границы периодов на основе системного перечисления.
Проанализируем пример кода:
Период = Новый СтандартныйПериод;
Период.Вариант = ТипСтандартногоПериода.Полугодие;
Период.ДатаНачала = ТекущаяДата(); // Платформа сама определит границы
ДатаОкончанияПолугодия = Период.ДатаОкончания;
Этот способ удобен тем, что он опирается на внутренние алгоритмы платформы. Если в будущем в 1С изменятся правила определения периодов (что маловероятно, но возможно), этот код останется актуальным.
Рассмотрим еще один вариант, который часто встречается в типовых конфигурациях. Он сочетает в себе использование функции КонецГода() и вычитание месяцев.
Функция КонецПолугодияТиповой(Дата)
КонецТекущегоГода = КонецГода(Дата);
Если Месяц(Дата) > 6 Тогда
Возврат КонецТекущегоГода;
Иначе
Возврат ДобавитьМесяц(КонецТекущегоГода, -6);
КонецЕсли;
КонецФункции
Здесь мы сначала получаем конец года, а если дата относится к первому полугодию — просто «отматываем» 6 месяцев назад. Это гарантирует сохранение времени 23:59:59 и корректную работу с високосными годами.
При реализации собственных функций получения периодов всегда следует помнить о нескольких правилах 1С:
Дата(Год, Месяц, День), время установится в 00:00:00, что может привести к потере данных за последний день периода при использовании условий «Меньше или равно» в запросах. Всегда оборачивайте результат в КонецДня().ДобавитьМесяц в чистом виде (используется ДОБАВИТЬКДАТЕ) и нет оператора % (остаток от деления). В запросах лучше использовать конструкцию ВЫБОР.РаботаСДатамиКлиентСервер) соответствующую функцию. Это избавит вас от дублирования «кракозябр» (сложных формул) по всему тексту программы.Таким образом, мы разобрали основные подходы к получению конца полугодия. Выбор конкретного метода зависит от ваших приоритетов: нужна ли вам максимальная читаемость кода для будущих разработчиков или же вы стремитесь к лаконичности и производительности.