Как посчитать, сколько дней осталось до дня рождения в 1С?

Программист IT и автоматизация бизнеса
← На главную

Задача посчитать количество дней до дня рождения на первый взгляд кажется простой. Однако в ней есть важный нюанс, который часто упускают: что делать, если день рождения в текущем году уже прошел? В этом случае расчет нужно вести до дня рождения в следующем году. Давайте разберем несколько надежных способов решения этой задачи в среде 1С.

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

Способ 1: Процедурный расчет с проверкой года

Это самый фундаментальный и понятный способ, который позволяет полностью контролировать логику вычислений. Алгоритм состоит из нескольких шагов, которые мы сейчас подробно разберем.

  1. Определяем дату дня рождения в текущем году. Для этого нам нужна исходная дата рождения (например, сотрудника). Используя функции Год(), Месяц() и День(), мы "собираем" дату дня рождения, но уже с текущим годом.
  2. Сравниваем полученную дату с текущей. Здесь и кроется ключевая логика. Нам нужно понять, был ли уже день рождения в этом году или еще нет.
    • Если дата дня рождения в текущем году больше или равна текущей дате, значит, событие еще впереди.
    • Если она меньше текущей даты, значит, день рождения уже прошел, и ждать его нужно в следующем году.
  3. Вычисляем количество дней. В зависимости от результата сравнения, мы находим разницу между текущей датой и датой "следующего" дня рождения. Важно помнить, что при вычитании дат в 1С мы получаем разницу в секундах. Чтобы получить дни, результат нужно разделить на 86400 (24 часа * 60 минут * 60 секунд).

Посмотрим на пример кода, который реализует этот алгоритм. Создадим процедуру, которая принимает на вход дату рождения и сообщает, сколько дней до нее осталось.


Процедура РассчитатьДниДоДР(ДатаРождения)
    
    Перем КоличествоДней;
    
    // 1. Получаем дату дня рождения в текущем году
    ДатаДРВТекущемГоду = Дата(Год(ТекущаяДата()), Месяц(ДатаРождения), День(ДатаРождения));
    
    // 2. Сравниваем с текущей датой
    Если НачалоДня(ДатаДРВТекущемГоду) >= НачалоДня(ТекущаяДата()) Тогда
        // Если день рождения в этом году еще не наступил (или сегодня)
        // Вычисляем разницу до этой даты
        РазницаВСекундах = ДатаДРВТекущемГоду - ТекущаяДата();
        КоличествоДней = Цел(РазницаВСекундах / 86400);
    Иначе
        // Если день рождения уже прошел, то считаем до следующего года
        // Формируем дату дня рождения в следующем году
        ДатаДРВСледующемГоду = Дата(Год(ТекущаяДата()) + 1, Месяц(ДатаРождения), День(ДатаРождения));
        РазницаВСекундах = ДатаДРВСледующемГоду - ТекущаяДата();
        КоличествоДней = Цел(РазницаВСекундах / 86400);
    КонецЕсли;
    
    Сообщить("До дня рождения осталось: " + КоличествоДней + " дн.");
    
КонецПроцедуры

Важные моменты в этом коде:

Способ 2: Использование запроса и функции РАЗНОСТЬДАТ

Платформа 1С предоставляет мощный инструмент — язык запросов, который часто позволяет решать задачи более элегантно и производительно. Для нашей цели отлично подходит функция языка запросов РАЗНОСТЬДАТ().

Основная логика остается прежней: нам все равно нужно сначала определить дату следующего дня рождения. Но само вычисление разницы мы передаем системе.

Порядок действий:

  1. Сначала, как и в первом способе, определяем, прошла ли дата дня рождения в текущем году.
  2. На основе этой проверки формируем переменную ДатаСледующегоДР.
  3. Создаем новый запрос, в котором используем функцию РАЗНОСТЬДАТ(&Дата1, &Дата2, ДЕНЬ). Она принимает две даты и тип интервала (ДЕНЬ, МЕСЯЦ, ГОД и т.д.) и возвращает разницу в указанных единицах.
  4. Передаем в запрос текущую дату и вычисленную дату следующего дня рождения в качестве параметров.

Рассмотрим, как это выглядит в коде. Этот подход особенно удобен, если нужно рассчитать данные сразу для нескольких сотрудников.


// Предположим, в переменной ДатаРождения хранится нужная дата
Перем ДатаСледующегоДР;

// Шаг 1: Определяем дату следующего дня рождения
ДатаДРВТекущемГоду = Дата(Год(ТекущаяДата()), Месяц(ДатаРождения), День(ДатаРождения));

Если НачалоДня(ДатаДРВТекущемГоду) < НачалоДня(ТекущаяДата()) Тогда
    // Если ДР уже прошел, берем следующий год.
    // Функция ДобавитьМесяц(Дата, 12) надежно добавляет ровно один год.
    ДатаСледующегоДР = ДобавитьМесяц(ДатаДРВТекущемГоду, 12); 
Иначе
    // Если ДР еще будет в этом году
    ДатаСледующегоДР = ДатаДРВТекущемГоду;
КонецЕсли;

// Шаг 2: Выполняем запрос
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |    РАЗНОСТЬДАТ(&ТекущаяДата, &СледующийДеньРождения, ДЕНЬ) КАК ОсталосьДней";

Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДата());
Запрос.УстановитьПараметр("СледующийДеньРождения", ДатаСледующегоДР);

РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
    Выборка = РезультатЗапроса.Выбрать();
    Выборка.Следующий();
    Сообщить("До дня рождения осталось: " + Выборка.ОсталосьДней + " дн.");
КонецЕсли;

Этот метод считается более предпочтительным в "стиле 1С", так как он более декларативный (мы описываем, что хотим получить, а не как) и часто работает быстрее, особенно на больших объемах данных. Функция ДобавитьМесяц() здесь используется для корректного добавления года, что особенно важно для високосных лет и даты 29 февраля.

Таким образом, мы рассмотрели два надежных способа для расчета дней до дня рождения. Первый способ — процедурный — отлично подходит для понимания логики, а второй — с использованием запроса — является более современным и эффективным решением для реальных задач.

← На главную