В системе 1С:Предприятие работа с временными метками является фундаментальной задачей для любого разработчика. Будь то формирование периодических отчетов, расчет зарплаты или складской учет, корректная обработка моментов времени критически важна для целостности данных. Ошибки в логике сравнения или неверное понимание структуры типа ДатаВремя могут привести к тому, что документы "потеряются" или попадут не в тот период отчетности.
Разработчикам необходимо понимать, что платформа использует единый внутренний формат для хранения как даты, так и времени. Это позволяет выполнять арифметические операции над временными интервалами с высокой точностью. Однако визуальное представление и способы задания значений в коде имеют свои специфические особенности, которые мы подробно рассмотрим в этой статье.
Существует несколько способов присвоения значения переменной типа Дата, и выбор конкретного метода зависит от контекста задачи. Часто возникает путаница между константами, вводимыми вручную, и датами, полученными динамически в момент выполнения программы. Понимание этих различий поможет вам писать более надежный и предсказуемый код.
Синтаксис констант даты и времени
Для жесткого задания конкретного момента времени непосредственно в тексте программы используется специальный синтаксис с апострофами. Это наиболее распространенный способ, когда вам нужно сравнить дату документа с фиксированным рубежом, например, с датой начала налогового периода.
МояДата = '25.12.2026 14:30:00';
Обратите внимание, что формат строки внутри апострофов строго регламентирован. Платформа 1С:Предприятие ожидает увидеть день, месяц и год, разделенные точками, а время — через пробел с двоеточиями. Если время не указано явно, оно автоматически принимается равным нулю, то есть началу суток.
⚠️ Внимание: При использовании констант даты убедитесь, что разделителем служит именно точка, а не дефис или слэш, иначе интерпретатор кода выдаст ошибку синтаксиса.
Важно помнить о различии между типами Дата и Время. Хотя визуально они часто выглядят похоже, внутри платформы это разные сущности. Тип "Время" хранит только временную часть суток без привязки к календарю, тогда как тип "Дата" (или более общий "ДатаВремя") содержит полную информацию.
Для получения текущей даты и времени в момент исполнения кода используется встроенная функция ТекущаяДата(). Это значение динамическое и будет меняться при каждом запуске алгоритма, в отличие от жестко заданной константы.
Используйте константы даты для тестирования логики на исторических данных, а функцию ТекущаяДата() — только для реальной рабочей среды.
Функции начала и конца периодов
Одной из самых частых задач в программировании на языке 1С является определение границ временных интервалов. Вам может потребоваться найти первый день месяца, начало квартала или конец года для формирования выборок из регистров сведений или накопления.
Платформа предоставляет набор удобных функций для этих целей, которые значительно упрощают код и делают его читаемым. Вместо ручного вычисления дней вам достаточно вызвать одну из стандартных процедур, передав в нее произвольную дату внутри интересующего периода.
- 📅 НачалоДня() — обнуляет время, оставляя дату неизменной.
- 📅 НачалоМесяца() — возвращает первое число месяца с временем 00:00:00.
- 📅 НачалоКвартала() — определяет первый день первого месяца соответствующего квартала.
- 📅 НачалоГода() — возвращает 1 января указанного года.
Аналогично существуют функции для определения конца периодов, такие как КонецМесяца() или КонецГода(). Эти функции критически важны при построении запросов, где условие отбора часто выглядит как "Между НачаломПериода И КонцомПериода".
Рассмотрим пример использования функции НачалоПериодаРегистрации в контексте работы с регистрами. Эта функция помогает найти самую раннюю дату, за которую в системе есть записи, что полезно для оптимизации тяжелых отчетов.
⚠️ Внимание: Функции начала и конца периодов возвращают значение типа ДатаВремя. Если вы сравниваете их с датой, у которой отсечено время, результат сравнения может быть неожиданным из-за временной составляющей.
Арифметические операции с датами
Язык запросов и встроенный язык 1С позволяют выполнять математические действия над датами, рассматривая их как числовые величины. Это открывает широкие возможности для расчета сроков, дней просрочки или планирования событий в будущем.
Основная единица измерения при сложении или вычитании — это одна секунда. Однако на практике разработчики редко оперируют секундами напрямую, используя вместо них специальные функции для добавления интервалов. Это делает код более понятным для сопровождения.
Для изменения даты на определенный интервал используется функция ДобавитьКДате(). Она позволяет гибко управлять сдвигом во времени, указывая тип интервала (секунда, минута, час, день, месяц, год) и количество единиц.
НоваяДата = ДобавитьКДате(ИсходнаяДата, ВидИнтервала.Месяц, 3);
В данном примере мы сдвигаем дату на три месяца вперед. Платформа автоматически корректно обрабатывает переходы через високосные годы и разное количество дней в месяцах. Если вы добавите месяц к 31 января, система правильно определит последний день февраля.
Особенности високосных лет
При добавлении года к дате 29.02.2026 результат будет 28.02.2026, так как 2026 год не является високосным. Платформа не выдает ошибку, а выбирает ближайшую валидную дату.
Также возможно прямое вычитание одной даты из другой. Результатом такой операции будет число, представляющее количество секунд между двумя моментами времени. Для перевода этого значения в дни необходимо разделить его на количество секунд в сутках (86400).
КоличествоДней часто используется для расчета пеней или скидок, зависящих от времени оплаты. Точность таких расчетов зависит от того, учитываете ли вы время суток или работаете только с датами, приведенными к началу дня.Извлечение компонентов даты
Часто возникает необходимость получить отдельную часть даты, например, только номер месяца или год, для группировки данных в отчете или для условной логики. Платформа 1С предоставляет набор функций-селекторов для извлечения этих компонентов.
Функции Год(), Месяц() и День() возвращают целочисленные значения соответствующих частей даты. Это позволяет легко фильтровать данные, например, отбирать все документы, созданные в декабре, независимо от года.
| Функция | Возвращаемое значение | Пример результата для '15.05.2023' |
|---|---|---|
| Год() | Число (год) | 2023 |
| Месяц() | Число (1-12) | 5 |
| День() | Число (1-31) | 15 |
| ДеньНедели() | Число (0-6, где 0 — Воскресенье) | 1 (Понедельник) |
Особого внимания заслуживает функция ДеньНедели(). Она возвращает число от 0 до 6, что может быть неочевидно для тех, кто привык считать неделю с понедельника как с единицы. Знание этой особенности важно при программировании графиков работы или расчетов, зависящих от выходных дней.
Функции извлечения компонентов возвращают числа, а не строки. Это позволяет использовать их в математических вычислениях без дополнительного преобразования типов.
Для получения текстового представления месяца или дня недели на языке интерфейса используются функции МесяцСтр() и ДеньНеделиСтр(). Они полезны при формировании печатных форм документов, где требуется красивое отображение даты прописью.
Преобразование типов и форматов
В процессе обмена данными или при работе с пользовательским вводом часто возникает необходимость преобразовать строку в дату и наоборот. Неправильное преобразование является частой причиной ошибок выполнения в прикладных решениях 1С.
Для преобразования строки в дату используется функция Дата(). Она пытается распознать формат строки автоматически, но надежнее всего использовать стандартный формат "ДД.ММ.ГГГГ". Если строка не соответствует ожидаемому формату, функция вернет пустую дату или вызовет исключение.
СтрокаДаты = "20.10.2023";
ДатаЗнач = Дата(СтрокаДаты);
Обратное преобразование выполняется функцией Строка() или методом Формат(). Метод Формат() является более мощным инструментом, так как позволяет задать точный шаблон вывода, включая разделители и порядок элементов.
- 🔹 Строка(Дата) — быстрое преобразование в стандартный вид.
- 🔹 Формат(Дата, "ДФ=dd.MM.yyyy") — гибкое форматирование под любые требования.
- 🔹 СтрокаВДата() — альтернативный способ с явным указанием формата строки.
⚠️ Внимание: При импорте данных из внешних источников (CSV, XML) формат даты может отличаться от регионального стандарта пользователя. Всегда явно указывайте формат преобразования, чтобы избежать ошибок на компьютерах с другими настройками locale.
Существует также нюанс с часовыми поясами. При работе с веб-сервисами или синхронизацией между разными базами данных время может приходить в формате UTC. Его необходимо корректно конвертировать в локальное время базы данных, учитывая смещение часового пояса.
Особенности работы в запросах
При написании запросов к базе данных синтаксис работы с датами имеет свои отличия от встроенного языка. В тексте запроса даты также заключаются в апострофы, но логика сравнения работает на уровне СУБД, что требует особой внимательности к типам данных.
В условии ГДЕ часто используется конструкция МЕЖДУ.. И... Если вы указываете конец дня, убедитесь, что время действительно соответствует последней секунде суток, или используйте функцию КонецДня().
☑️ Проверка условий даты в запросе
Оптимизация запросов часто зависит от того, как именно вы фильтруете по дате. Использование функций от поля в условии (например, Год(ДатаДокумента) = 2023) может привести к полному сканированию таблицы и потере производительности.
Лучшей практикой считается формирование диапазона дат на стороне клиента (во встроенном языке) и передача в запрос уже готовых границ: ДатаДокумента >= &НачалоПериода. Такой подход позволяет базе данных использовать индексы по дате, что значительно ускоряет выполнение выборки.
Как правильно сравнить дату с текущим моментом в запросе?
В запросах нельзя напрямую использовать функцию ТекущаяДата(). Вместо этого нужно передать значение даты как параметр запроса из встроенного языка. Объявите параметр в тексте запроса, например &ТекущаяДата, и установите его значение перед выполнением запроса.
Почему дата 31.02.2023 не вызывает ошибку?
Платформа 1С автоматически корректирует некорректные даты. Если вы попытаетесь создать дату 31 февраля, система изменит её на последний валидный день месяца (28 или 29 февраля). Это поведение называется нормализацией даты.
В чем разница между Датой и ДатыВремя в метаданных?
В современных версиях платформы это единый тип ДатаВремя. Разделение на чисто "Дату" и "Время" существует как логическое понятие, но физически хранится как число секунд с начала эры. В метаданных вы выбираете флаг "Время" для поля, чтобы разрешить хранение временной составляющей.
Как получить количество дней между двумя датами?
Вычтите одну дату из другой, получив разницу в секундах. Затем разделите полученное число на 86400 (количество секунд в сутках). Для получения целого числа дней используйте функцию Цел() для отбрасывания дробной части.
Можно ли хранить даты до 1900 года?
Минимальное значение даты в 1С ограничено 1 января 1900 года (а в некоторых контекстах и 1980 годом для совместимости). Попытка установить дату раньше этого диапазона приведет к ошибке или некорректному поведению системы.