Работа с временными метками является фундаментальной частью разработки и администрирования в платформе 1С:Предприятие 8. Правильное понимание того, как система интерпретирует моменты времени, критически важно для корректной выборки документов, формирования отчетов и расчета периодов. Ошибки в форматировании или логике сравнения дат могут привести к тому, что важные документы не попадут в выборку или отчет покажет неверные остатки.
В отличие от многих языков программирования, где дата часто представляется строкой или числом, в 1С используется специальный тип данных Date. Этот тип хранит информацию с точностью до секунды, что позволяет проводить тонкие настройки временных интервалов. Однако новички часто сталкиваются с трудностями при попытке жестко зафиксировать дату в коде или параметрах отчета, особенно когда речь идет о границах периодов.
Данная статья подробно разбирает механизмы задания даты, начиная от базового синтаксиса конструктора и заканчивая нюансами работы с бесконечными пределами временных диапазонов. Мы рассмотрим, как избежать распространенных ошибок при вводе литеральных значений и как эффективно использовать встроенные функции для манипуляции временем.
Базовый синтаксис конструктора Date()
Для явного указания даты в коде конфигурации или в запросах используется специальная конструкция, называемая конструктором даты. Она начинается с ключевого слова Date, за которым следуют параметры в круглых скобках. Это единственный надежный способ гарантировать, что система распознает введенное значение именно как тип Date, а не как строку или число.
Конструктор поддерживает различные уровни детализации, позволяя задавать время с точностью до года, месяца, дня, часа, минуты или секунды. Если вы указали только год, система автоматически дополнит дату началом этого года. Например, запись Date(2026) будет интерпретирована как 1 января 2026 года, 00:00:00. Это удобно для формирования годовых отчетов без лишних вычислений.
При необходимости указать конкретный момент времени используется полный формат с разделителями. Это строгое требование синтаксиса языка запросов и встроенного языка 1С.
ДатаНачалаРабочегоДня = Date(2026, 10, 25, 9, 0, 0);
Использование конструктора делает код более читаемым и защищенным от ошибок локализации. В отличие от строковых представлений, которые могут зависеть от региональных настроек компьютера пользователя (например, формат ДД.ММ.ГГГГ против ММ/ДД/ГГГГ), конструктор Date() работает одинаково на любых машинах.
Используйте конструктор Date() даже для переменных, чтобы избежать неявного преобразования типов, которое может замедлить выполнение запроса в больших базах данных.
Стоит отметить, что при работе с датами в запросах конструктор может быть использован непосредственно в теле запроса. Это позволяет передавать жестко заданные временные метки без создания дополнительных переменных в коде модуля.
Литеральные значения и форматы ввода
Помимо конструктора, в языке 1С существует понятие литеральных значений даты. Это способ записи даты непосредственно в коде с использованием фигурных скобок. Такой подход часто используется в старых версиях конфигураций или в специфических сценариях мета-данных, но он менее гибок, чем вызов функции.
Литерал даты записывается в формате {'ГГГГММДДЧЧММСС'}. Здесь важно соблюдать порядок следования цифр: сначала год, затем месяц, день, часы, минуты и секунды. Отсутствие разделителей требует от разработчика предельной внимательности, так как ошибка в одной цифре сместит весь последующий параметр.
⚠️ Внимание: Литеральный формат даты не поддерживает раздельное указание компонентов через запятые. Любая попытка вставить пробел или символ разделителя приведет к синтаксической ошибке компиляции модуля.
Рассмотрим пример использования литерала для установки даты начала эпохи Unix в контексте 1С (хотя это редко требуется на практике):
ЛитеральнаяДата = {'19700101000000'};
Главное преимущество конструктора перед литералом заключается в возможности использования переменных. В литерале можно указать только константные значения, тогда как Date(Год, Месяц..) позволяет подставлять значения из переменных, что необходимо для динамических расчетов.
При вводе дат в интерфейсе пользователя, например в полях отчета, система автоматически преобразует строковое представление во внутренний формат. Однако при программной обработке всегда предпочтительнее использовать типизированные значения, чтобы избежать ошибок преобразования типов в runtime.
Работа с периодами и границами времени
Одной из самых частых задач в 1С является выборка данных за определенный период. Для этого необходимо корректно задать начало и конец интервала. Платформа предоставляет специальные значения для обозначения бесконечности, что упрощает формирование выборок "с начала времен" или "по текущий момент".
Для обозначения нижней границы периода, уходящей в бесконечное прошлое, используется значение Date(0001, 01, 01). Это минимально возможная дата в системе 1С. Аналогично, для верхней границы используется максимально возможная дата, которую можно сгенерировать конструктором, либо специальные константы в зависимости от контекста запроса.
При формировании отчетов часто возникает потребность получить первый или последний день месяца, квартала или года. Для этих целей существуют встроенные функции, такие как НачалоПериода() и КонецПериода(). Они принимают дату произвольного момента внутри периода и возвращают соответствующую границу.
| Функция | Описание | Пример входа | Пример выхода |
|---|---|---|---|
НачалоДня() |
Возвращает 00:00:00 текущей даты | 25.10.2026 15:30 | 25.10.2026 00:00 |
КонецДня() |
Возвращает 23:59:59 текущей даты | 25.10.2026 10:00 | 25.10.2026 23:59 |
НачалоМесяца() |
Первое число месяца 00:00 | 15.03.2026 | 01.03.2026 00:00 |
КонецГода() |
31 декабря 23:59:59 | 01.01.2026 | 31.12.2026 23:59 |
Использование этих функций гарантирует, что ваш код будет работать корректно независимо от того, в какой момент времени он был запущен. Жесткая прописка дат, например, Date(2026, 12, 31), делает отчет неактуальным уже на следующий день.
☑️ Проверка корректности периода
Особое внимание следует уделить включению границ периода в запросах. В языке запросов 1С операторы МЕЖДУ включают обе границы. Если вам нужно исключить конечную дату, следует использовать операторы сравнения < или >, сдвигая границу на одну секунду или используя начало следующего периода.
Получение текущей даты и времени
Часто в процессе работы программы требуется зафиксировать текущий момент времени. Для этого в глобальном контексте 1С предусмотрена функция ТекущаяДата(). Она возвращает значение типа Date, соответствующее времени на компьютере, где выполняется код (клиент или сервер).
Важно понимать разницу между временем клиента и временем сервера. Если код выполняется на стороне клиента (в форме), ТекущаяДата() вернет время локального компьютера пользователя. Если же код выполняется в модуле объекта или общем модуле с признаком "Сервер", будет использовано время сервера 1С.
Это различие критично для регистраторов документов. Рекомендуется всегда использовать серверное время для записи даты документа, чтобы обеспечить единую хронологию событий в распределенной информационной базе. Локальное время пользователя может быть сбито или находиться в другом часовом поясе.
⚠️ Внимание: При работе в веб-клиенте или тонком клиенте убедитесь, что сервер 1С настроен на правильный часовой пояс. Ошибка в настройках ОС сервера приведет к некорректному времени во всех регистрируемых документах.
Для получения только текущей даты без времени (обнуление часов, минут и секунд) удобно комбинировать функцию получения времени с функцией НачалоДня(). Это позволяет сравнивать даты без учета временной составляющей, что часто требуется при отборе документов за "сегодня".
Сегодня = НачалоДня(ТекущаяДата());
Такой подход избавляет от проблем, когда документ создан сегодня в 09:00, а сравнение идет с датой, полученной вчера в 23:59, что формально является "вчерашним" днем, хотя для пользователя это один и тот же календарный день.
Преобразование строк и чисел в дату
В реальной разработке часто возникают ситуации, когда дата поступает из внешних источников в виде строки или числа. Например, при загрузке данных из CSV-файла или обмене с сайтом по JSON. Для преобразования таких данных в тип Date используется функция Дата() (в отличие от конструктора Date() с большой буквы в английском написании, в русскоязычном коде это одноименная функция).
Функция преобразования строки в дату чувствительна к формату входной строки. По умолчанию 1С пытается распознать формат, соответствующий краткому формату даты, установленному в операционной системе. Это может привести к неоднозначности, если строка имеет вид "01.02.2026" (1 февраля или 2 января?).
Для надежного преобразования рекомендуется использовать функцию СтрокаВДату() с явным указанием формата или предварительно приводить строку к унифицированному виду. Если же дата хранится в виде числа (например, 20261025), ее необходимо разбить на составные части перед передачей в конструктор.
Как разобрать числовую дату 20261025?
Разделите число на части с помощью операций деления и остатка от деления. Год = Число / 10000, Месяц = (Число % 10000) / 100, День = Число % 100. Затем используйте конструктор Date(Год, Месяц, День).
При импорте данных из Excel даты часто приходят в виде чисел serial date (количество дней от определенной эпохи). Для таких случаев в 1С нет встроенной прямой конвертации, и требуется написание небольшой функции-конвертера, учитывающей разницу в системах отсчета между Excel и 1С.
Обратное преобразование, из даты в строку, выполняется функцией Формат(). Она позволяет гибко настраивать вывод, задавая нужное количество знаков, разделители и текстовое представление месяцев. Это незаменимый инструмент для формирования печатных форм и выгрузок.
Типичные ошибки и способы их решения
Разработчики, особенно начинающие, часто допускают ряд типичных ошибок при работе с датами. Одна из самых распространенных — попытка сложить дату и число без понимания смысла операции. В 1С к дате можно прибавить число, и это будет означать добавление количества дней, но вычитание одной даты из другой даст число дней между ними.
Другая частая ошибка связана с часовыми поясами при работе с распределенными базами данных. Если сервер находится в Москве, а пользователь владивостоке, то при записи ТекущаяДата() на клиенте в документ попадет местное время пользователя, что может нарушить последовательность документов в общей базе.
- 📅 Ошибка формата: Использование слэшей вместо точек в строковых литералах без учета региональных настроек.
- ⏳ Потеря секунд: Сравнение дат с точностью до дня, когда в реальности документы разнесены по времени в пределах одной минуты.
- 🚫 Null-значения: Попытка вызвать функции периода для неопределенного значения даты (ПустаяДата), что приводит к исключению.
Для избежания проблем с пустыми датами всегда проверяйте значение перед использованием. Функция ПустаяДата() возвращает минимально возможную дату, но логически она означает отсутствие значения. Сравнение реальной даты с пустой датой всегда даст истину для операторов "больше", что может исказить логику отбора.
⚠️ Внимание: Интерфейсы и поведение функций могут незначительно отличаться в зависимости от версии платформы 1С:Предприятие (8.2, 8.3, 8.3.20+). Всегда сверяйте синтаксис с официальной документацией для вашей конкретной версии платформы перед внедрением в промышленную эксплуатацию.
Еще один нюанс — високосные годы. Функции работы с периодами в 1С автоматически учитывают високосные годы при расчете конца февраля. Однако при ручном добавлении дней (например, Дата + 365) можно ошибиться и попасть на 1 марта вместо 28 февраля в невисокосном году. Лучше использовать функцию ДобавитьМесяц() или ДобавитьГод().
Всегда используйте встроенные функции манипуляции датами (НачалоПериода, КонецПериода, ДобавитьМесяц) вместо арифметических операций, чтобы учесть високосные годы и разную длину месяцев.
Понимание этих тонкостей позволяет писать устойчивый код, который не сломается при смене года, переходе на летнее время (если применимо) или переносе базы на другой сервер. Уделяйте внимание тестированию пограничных значений: 31 декабря, 29 февраля, переход через полночь.
Часто задаваемые вопросы (FAQ)
Как задать дату в запросе 1С напрямую без переменных?
В тексте запроса вы можете использовать конструктор даты напрямую в условии отбора. Например: ГДЕ Период.Начало >= Date(2026, 01, 01). Это допустимый синтаксис, который часто используется для отладки или статических выборок.
Что вернет функция ТекущаяДата() в фоновом задании?
В фоновом задании, которое выполняется на стороне сервера, функция ТекущаяДата() вернет время сервера 1С, независимо от того, какой пользователь запустил это задание. Это обеспечивает консистентность времени в системных журналах.
Можно ли хранить дату в виде строки в регистре сведений?
Технически можно, но это считается грубой ошибкой проектирования. Хранение даты в строке лишает вас возможности эффективно использовать индексацию по времени, сортировку и стандартные функции периодов. Всегда используйте тип Date для полей дат.
Как получить количество дней между двумя датами?
Для этого достаточно вычесть одну дату из другой: КоличествоДней = Дата2 - Дата1. Результатом будет число типа Number, представляющее разницу в днях (дробная часть означает долю суток).
Почему дата 31.02.2026 не вызывает ошибку при вводе?
Платформа 1С обладает механизмом автоматической коррекции дат. Если вы зададите несуществующую дату (например, 31 февраля), система автоматически перенесет ее на следующий валидный день (в данном случае на 2 или 3 марта в зависимости от високосности). Это может привести к скрытым логическим ошибкам.