Как проверить вхождение даты в диапазон дат в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Одной из типовых задач при разработке в платформе 1С:Предприятие является проверка попадания заданной даты в определенный временной интервал. Разберем различные способы решения этой задачи как во встроенном языке, так и в языке запросов, а также проанализируем важные нюансы, связанные с учетом времени и обработкой пустых значений.

Способ 1. Проверка во встроенном языке с помощью операторов сравнения

В простейшем случае для проверки вхождения даты в диапазон применяются стандартные операторы сравнения >= и <=. Однако в платформе 1С тип Дата всегда содержит составляющую времени (часы, минуты, секунды). Если правая граница диапазона передана без времени (по умолчанию 00:00:00), дата с ненулевым временем того же дня не войдет в интервал.

Чтобы избежать этой ошибки, правую границу диапазона приводят к концу суток с помощью функции КонецДня(). Рассмотрим пример:


ДатаПроверки = '20170416120000'; // 16.04.2017 12:00:00
ДатаНачала = '20160101000000';   // 01.01.2016 00:00:00
ДатаОкончания = '20171231000000';// 31.12.2017 00:00:00

Если ДатаПроверки >= ДатаНачала И ДатаПроверки <= КонецДня(ДатаОкончания) Тогда
    // Дата входит в диапазон
    ВходитВДиапазон = Истина;
Иначе
    ВходитВДиапазон = Ложь;
КонецЕсли;

Способ 2. Проверка через полуинтервал (строгое неравенство)

Проанализируем альтернативный подход во встроенном языке, исключающий возможные погрешности с миллисекундами на уровне СУБД. Вместо вызова КонецДня() можно проверить строгое неравенство со временем начала следующего дня:


Если ДатаПроверки >= ДатаНачала И ДатаПроверки < (НачалоДня(ДатаОкончания) + 86400) Тогда
    ВходитВДиапазон = Истина;
КонецЕсли;

Прибавив 86400 секунд к началу дня границы окончания, мы получаем ровно 00:00:00 следующего календарного дня.

Способ 3. Проверка в языке запросов (оператор МЕЖДУ)

В языке запросов 1С для проверки вхождения даты в интервал применяется оператор МЕЖДУ (или конструкция BETWEEN). Он эквивалентен условию Поле >= &Начало И Поле <= &Конец, включая обе границы.

Посмотрим на пример формирования запроса с функцией КОНЕЦПЕРИОДА для корректного включения всего дня окончания:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ВЫБОР
    |		КОГДА &ДатаПроверки МЕЖДУ &ДатаНачала И КОНЕЦПЕРИОДА(&ДатаОкончания, ДЕНЬ) ТОГДА ИСТИНА
    |		ИНАЧЕ ЛОЖЬ
    |	КОНЕЦ КАК ВходитВДиапазон";

Запрос.УстановитьПараметр("ДатаПроверки", ДатаПроверки);
Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала);
Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания);

Результат = Запрос.Выполнить().Выгрузить();

Важно: если значение параметра &ДатаНачала окажется строго больше параметра &ДатаОкончания, конструкция МЕЖДУ всегда возвратит результат ЛОЖЬ.

Способ 4. Использование объекта СтандартныйПериод

В типовых конфигурациях и формах отчетов для задания интервалов часто применяется объект СтандартныйПериод. Разберем его ключевое преимущество:

  1. При интерактивном выборе диапазона свойство ДатаОкончания автоматически устанавливается на 23:59:59 выбранного дня.
  2. Это избавляет разработчика от необходимости вручную вызывать КонецДня() или КОНЕЦПЕРИОДА перед передачей параметров в запрос.

Способ 5. Обработка пустых или незаполненных границ

На практике границы периода могут быть не заданы (например, если период бессрочный). В 1С пустая дата равна 0001-01-01T00:00:00 ('00010101'). Посмотрим, как корректно составить условие во встроенном языке с учетом возможных незаполненных значений:


УсловиеНачала = (НЕ ЗначениеЗаполнено(ДатаНачала)) ИЛИ (ДатаПроверки >= ДатаНачала);
УсловиеКонца  = (НЕ ЗначениеЗаполнено(ДатаОкончания)) ИЛИ (ДатаПроверки <= КонецДня(ДатаОкончания));

Если УсловиеНачала И УсловиеКонца Тогда
    // Дата удовлетворяет диапазону (в том числе открытому с одной из сторон)
КонецЕсли;

Способ 6. Проверка в Системе компоновки данных (СКД)

При построении отчетов на базе СКД нет необходимости прописывать сложные условия в тексте запроса. Достаточно в настройках отбора добавить поле даты и выбрать стандартный вид сравнения В интервале. СКД автоматически выполнит корректное позиционирование дат с учетом начала и окончания выбранных периодов.

← На главную