A1sCode библиотека 1С

Зачем нужны Now и DateOrEmpty

Базовая семантика


// Всегда «сейчас» — единая точка времени
Сейчас = A1sO.Now(); // аналог ТекущаяДата()

// Превращаем значение в дату или «пусто»
Д1 = A1sO.DateOrEmpty(Сейчас);     // → дата
Д2 = A1sO.DateOrEmpty(Неопределено); // → Неопределено

Если A1sO.Empty(Д2) Тогда
    A1sLog.Info("Day12", "Дата не задана");
КонецЕсли;
      

Идея в том, чтобы не писать вручную десятки проверок типов — используйте общие утилиты A1sO.

Нормализация периодов (guard-паттерны)

Частая задача — привести входные даты к корректному периоду и подставить «сегодня», если даты не заданы.

Период или «сегодня»


Функция PeriodOrToday(ДатаНач, ДатаКон) Экспорт
    Н = A1sO.DateOrEmpty(ДатаНач);
    К = A1sO.DateOrEmpty(ДатаКон);

    // Если обе пустые — используем сегодня
    Если A1sO.Empty(Н) И A1sO.Empty(К) Тогда
        Сегодня = A1sO.Now();
        Н = НачалоДня(Сегодня);
        К = КонецДня(Сегодня);
        Возврат Новый Структура("Начало,Конец", Н, К);
    КонецЕсли;

    // Если одна из дат пустая — считаем периодом один день
    Если A1sO.Empty(Н) Тогда Н = НачалоДня(К); КонецЕсли;
    Если A1sO.Empty(К) Тогда К = КонецДня(Н);  КонецЕсли;

    // Гарантируем Н ≤ К
    Если Н > К Тогда
        Буф = Н; Н = К; К = Буф;
    КонецЕсли;

    // Нормализуем к границам дня
    Н = НачалоДня(Н);
    К = КонецДня(К);

    Возврат Новый Структура("Начало,Конец", Н, К);
КонецФункции
      

Месяц или «текущий месяц»


Функция MonthOrCurrent(Точка) Экспорт
    Д = A1sO.DateOrEmpty(Точка);
    Если A1sO.Empty(Д) Тогда Д = A1sO.Now(); КонецЕсли;

    Возврат Новый Структура(
        "Начало,Конец",
        НачалоМесяца(Д),
        КонецМесяца(Д)
    );
КонецФункции
      

Применение с A1sQ: «документы за период»


Функция РеализацииЗаПериодБезопасно(ДатаНач = Неопределено, ДатаКон = Неопределено, Лимит = 200) Экспорт
    Период = PeriodOrToday(ДатаНач, ДатаКон);

    ТекстQ = "
    |ВЫБРАТЬ ПЕРВЫЕ &Лимит
    |    Док.Ссылка         КАК ID,
    |    Док.Дата           КАК Dt,
    |    Док.СуммаДокумента КАК Amount
    |ИЗ Документ.РеализацияТоваровУслуг КАК Док
    |ГДЕ Док.Дата МЕЖДУ &Начало И &Конец
    |УПОРЯДОЧИТЬ ПО Dt
    ";
    // Порядок: &Лимит, &Начало, &Конец
    Возврат A1sQ.Unload(ТекстQ, Лимит, Период.Начало, Период.Конец);
КонецФункции
      

Даже если входные даты не заданы или перепутаны — функция вернёт корректный результат за «сегодня» или за один нормализованный день.

Первая дата/время (coalesce)


Функция DateOrNow(X) Экспорт
    Д = A1sO.DateOrEmpty(X);
    Возврат ?(A1sO.Empty(Д), A1sO.Now(), Д);
КонецФункции

// Пример
ЗапретДо = Неопределено;
ФактическаяДата = DateOrNow(ЗапретДо); // если «пусто», берём сейчас
      

Частые сценарии

Вчера/сегодня/завтра одним вызовом


Функция PeriodToday() Экспорт
    Д = A1sO.Now();
    Возврат Новый Структура("Начало,Конец", НачалоДня(Д), КонецДня(Д));
КонецФункции

Функция PeriodYesterday() Экспорт
    Д = A1sO.Now() - 24*60*60; // минус сутки
    Возврат Новый Структура("Начало,Конец", НачалоДня(Д), КонецДня(Д));
КонецФункции

Функция PeriodTomorrow() Экспорт
    Д = A1sO.Now() + 24*60*60; // плюс сутки
    Возврат Новый Структура("Начало,Конец", НачалоДня(Д), КонецДня(Д));
КонецФункции
      

Безопасный «сдвиг периода»


Функция ShiftDays(Н, К, Дней) Экспорт
    П = PeriodOrToday(Н, К);
    Н = П.Начало + Дней*24*60*60;
    К = П.Конец  + Дней*24*60*60;
    Возврат Новый Структура("Начало,Конец", Н, К);
КонецФункции
      

Анти-паттерны с датами

Практика (15–30 минут)

  1. Реализуйте PeriodOrToday и подключите его к запросу «документы за период».
  2. Сделайте DateOrNow и замените прямые вызовы ТекущаяДата() там, где нужен «дефолт — сейчас».
  3. Добавьте функции PeriodYesterday/Today/Tomorrow для быстрых пресетов фильтра.
  4. Напишите ShiftDays и проверьте, что смещение корректно работает на границах дня.

Чек-лист

Что дальше

День 13: A1sO — Числа (NumOrZero, RoundNum) — безопасные числа, округления и агрегаты.