Как преобразовать дату в секунды и реализовать систему уведомлений по договорам в 1С

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

В практике разработчика 1С часто возникают задачи, связанные с манипуляцией временем. Это может быть как простая передача данных во внешние системы в формате Unix Time, так и создание сложных механизмов оповещения, которые должны срабатывать за определенное количество дней до наступления события. В данной статье мы подробно разберем, как работать с типом Дата, как переводить его в числовые значения и как правильно организовать мониторинг сроков действия контрактов.

Основы преобразования даты в число (секунды)

Прежде всего, важно понимать, что в платформе «1С:Предприятие» тип Дата внутренне уже представляет собой число, а именно — количество секунд, прошедших с начала нашей эры (0001-01-01 00:00:00). Рассмотрим самый простой способ получения числа из даты через обычное вычитание.

Если нам нужно получить количество секунд от начала эпохи Unix (1 января 1970 года), мы можем использовать следующий программный код:


НужнаяДата = ТекущаяДата();
НачалоОтсчета = Дата(1970, 1, 1);
КоличествоСекунд = НужнаяДата - НачалоОтсчета;
Сообщить(КоличествоСекунд);

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


Функция ДатаВЧислоСекунд(ВыбраннаяДата) Экспорт
    // Вычисляем количество секунд от начала времен платформы
    Возврат ВыбраннаяДата - Дата(1, 1, 1);
КонецФункции

Функция ЧислоВДату(ЧислоСекунд) Экспорт
    // Возвращаем дату, прибавляя секунды к пустой дате
    Возврат Дата(1, 1, 1) + ЧислоСекунд;
КонецФункции

Реализация бизнес-логики уведомлений за определенный период

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

Для начала рассмотрим математический подход прямо в коде. В сутках содержится 86 400 секунд (24 часа * 60 минут * 60 секунд). Чтобы вычислить дату уведомления, нужно из даты окончания вычесть произведение количества дней на число секунд в сутках.

Посмотрим на пример логического условия:


// Предположим, у нас есть ДатаКонтракта и СрокУведомленияДней (число)
ДатаОповещения = ДатаКонтракта - (86400 * СрокУведомленияДней);

Если ТекущаяДата() >= НачалоДня(ДатаОповещения) Тогда
    // Выводим уведомление пользователю
    Сообщить("Внимание! Контракт истекает через " + СрокУведомленияДней + " дней!");
КонецЕсли;

Оптимальный способ работы через запросы

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

Для этого в языке запросов предусмотрена функция ДОБАВИТЬКДАТЕ. Мы можем выбрать все договоры, срок оповещения по которым уже наступил:


ВЫБРАТЬ
    Договоры.Ссылка КАК Договор,
    Договоры.ДатаОкончания КАК ДатаОкончания,
    Договоры.КоличествоДнейДляУведомления КАК Срок
ИЗ
    Справочник.ДоговорыКонтрагентов КАК Договоры
ГДЕ
    ДОБАВИТЬКДАТЕ(Договоры.ДатаОкончания, ДЕНЬ, -Договоры.КоличествоДнейДляУведомления) <= &ТекущаяДата

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

Современные возможности платформы (версии 8.3.20 и выше)

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

Этот метод возвращает число миллисекунд, начиная с 01.01.0001 00:00:00 в формате UTC. Это критически важно по следующим причинам:

  1. Производительность: Метод обращается напрямую к системному времени ОС, минуя лишние преобразования типов.
  2. Универсальность: Время возвращается в UTC (универсальное координированное время), что исключает ошибки, связанные с часовыми поясами сервера и клиента.
  3. Точность: Позволяет фиксировать события с точностью до 1/1000 секунды.

Важные технические нюансы и "подводные камни"

Рассмотрим несколько моментов, которые часто упускают начинающие программисты при работе с расчетами времени в секундах:

1. Работа с пустыми датами. Всегда проверяйте дату на значение '00010101'. Если вы попытаетесь вычесть из текущей даты пустую, вы получите огромное число секунд, которое может сломать дальнейшую логику расчетов.

2. Часовые пояса. Помните, что ТекущаяДата() возвращает время сеанса (локальное). Если ваша компания работает в разных регионах, используйте УниверсальноеВремя() для всех математических расчетов в секундах, чтобы избежать путаницы.

3. Использование Регламентных заданий. Чтобы уведомления из нашего примера с контрактами (Сообщение №9 и №10) приходили автоматически, лучше всего создать регламентное задание. Оно будет запускаться, например, каждое утро в 08:00, выполнять запрос и рассылать электронные письма или создавать задачи ответственным менеджерам.

4. Разность дат в запросах. Если вам нужно в отчете или динамическом списке вывести именно количество оставшихся секунд, используйте РАЗНОСТЬДАТ(ДатаНачала, ДатаОкончания, СЕКУНДА). Это стандартный и наиболее быстрый способ получения числовой разницы внутри SQL-запроса.

Используя предложенные методы, вы сможете гибко управлять временными данными в 1С, обеспечивая точность расчетов и удобство работы пользователей.

← На главную