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

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

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

Базовые функции получения текущего момента

Самый простой и распространенный способ узнать, который сейчас час в системе, — это вызов встроенной функции ТекущаяДата(). Эта функция не принимает аргументов и возвращает значение типа Дата, содержащее текущие дату и время согласно настройкам операционной системы компьютера, на котором выполняется код. Однако результат ее работы напрямую зависит от того, где именно выполняется этот код: на клиенте или на сервере.

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

Для получения только даты или только времени существуют дополнительные функции, которые часто используются для очистки временной составляющей или для сравнения дней. Функция ТекущаяДатаСеанса() возвращает дату начала сеанса, что удобно для отчетов, привязанных к моменту входа пользователя в систему, а не к моменту нажатия кнопки.

  • 🕒 ТекущаяДата() — возвращает полные дату и время выполнения кода.
  • 📅 ТекущаяДатаСеанса() — возвращает дату начала текущего пользовательского сеанса.
  • ⏱️ Время() — вспомогательная функция для создания значения времени из часов, минут и секунд.

⚠️ Внимание: Никогда не используйте клиентское время для записи критически важных временных меток в регистры или документы, если в вашей организации пользователи работают из разных часовых поясов. Это приведет к рассинхронизации данных при анализе.

Различия клиентского и серверного времени

Понимание контекста выполнения кода — ключ к предотвращению ошибок в распределенных системах. В тонком клиенте код может выполняться как на стороне рабочей станции пользователя, так и передаваться на сервер для выполнения. Когда вы вызываете ТекущаяДата() в модуле формы, вы получаете время «железа» перед монитором пользователя. Если пользователь переведет часы на своем ПК, это изменит результат работы вашей программы в этот момент.

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

Особую сложность представляет работа в веб-клиенте или в режиме тонкого клиента через терминальный сервер (RDP). В таких сценариях понятие «локального времени» может размываться. Платформа 1С старается нивелировать эти различия, но разработчик должен четко осознавать, где выполняется его код. Если алгоритм требует сравнения времени двух пользователей, находящихся в разных городах, необходимо приводить все значения к единому стандарту, обычно к времени сервера или UTC.

📊 Где чаще всего вы используете функцию ТекущаяДата()?
В модуле формы (клиент)
В модуле объекта (сервер)
В общих модулях
В запросах

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

&НаСервере

Функция ПолучитьСерверноеВремя()

Возврат ТекущаяДата();

КонецФункции

&НаКлиенте

Процедура КнопкаЗаписать(Команда)

СерверноеВремя = ПолучитьСерверноеВремя();

// Использование переменной СерверноеВремя

КонецПроцедуры

Конструирование даты из строки и компонентов

Часто в 1С возникает необходимость получить дату не «прямо сейчас», а конкретное историческое или будущее значение, заданное в виде строки или набора чисел. Для этого используется функция Дата(), которая является конструктором объектов типа Дата. Она позволяет гибко формировать значения времени, что необходимо при импорте данных из внешних источников или при ручном вводе периодов.

Функция Дата() имеет несколько вариантов вызова. Самый простой — передача строки в формате "ГГГГММДДЧЧММСС". Важно соблюдать порядок цифр: сначала год, затем месяц, день, часы, минуты и секунды. Если какие-то компоненты не указаны, они считаются равными нулю (или единице для дня и месяца, в зависимости от версии платформы и контекста, но лучше указывать все явно).

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

Способ вызова Пример кода Результат
Строковый формат Дата("20231231235959") 31 декабря 2023 г., 23:59:59
Числовые параметры Дата(2023, 12, 31, 23, 59, 59) 31 декабря 2023 г., 23:59:59
Только дата (время 00:00) Дата(2023, 12, 31) 31 декабря 2023 г., 00:00:00
Неполная строка Дата("202312") 1 декабря 2023 г., 00:00:00

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

Особенности високосных годов

Функция Дата() автоматически учитывает високосные годы. Если вы попытаетесь создать дату 29 февраля для невисокосного года (например, 2023), платформа выдаст ошибку выполнения. Всегда проверяйте корректность входных данных перед конструированием даты в циклах или при массовом импорте.

Операции начала и конца периодов

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

Функция НачалоПериода(Дата, Период) возвращает дату начала периода, в который попадает указанная дата. Второй параметр определяетgranularity (детализацию) периода: Период.День, Период.Месяц, Период.Квартал, Период.Год. Аналогично работает функция КонецПериода(), которая возвращает последнюю секунду указанного периода.

Эти функции незаменимы при формировании выборок из регистров накопления. Например, чтобы получить остатки на конец месяца, необходимо использовать КонецПериода(ТекущаяДата(), Период.Месяц) в качестве границы интервала в запросе. Использование этих функций гарантирует корректную работу алгоритма даже в високосные годы и при переходе через границы лет.

  • 📆 НачалоПериода(Дата, Период.Месяц) — вернет 1-е число месяца в 00:00:00.
  • 🌑 КонецПериода(Дата, Период.Год) — вернет 31 декабря (или 30/29) в 23:59:59.
  • Период — перечисление, задающее масштаб округления времени.

Если вы сравниваете даты через оператор «Меньше» (<), то конец периода может не попасть в выборку, если время события совпадает с последней секундой. Для надежного закрытия интервалов лучше использовать оператор «Меньше или равно» (<=) или сдвигать границу на одну секунду вперед.

⚠️ Внимание: Функции начала и конца периода работают строго по календарю Григорианского стиля. Убедитесь, что настройки регионального стандарта на сервере 1С соответствуют требованиям вашего законодательства, особенно при работе с историческими данными до 1918 года.

Форматирование и отображение даты

Получение значения даты — это только половина задачи. Часто необходимо представить это значение в удобочитаемом виде для пользователя или выгрузить в файл в определенном формате. Для этого в 1С используется универсальная функция Формат(). Она позволяет гибко настраивать вывод даты, времени или даты-времени с учетом языковых настроек.

Строка формата состоит из описания типа отображения и дополнительных параметров. Например, чтобы получить дату в виде «ДД.ММ.ГГГГ», используется строка "ДФ=dd.MM.yyyy". Для отображения времени — "ВФ=HH:mm:ss". Платформа поддерживает множество кодов форматирования, включая названия месяцев прописью, сокращенные названия дней недели и форматы ISO.

При выводе даты в интерфейсе (в полях форм, заголовках) часто достаточно стандартных настроек поля, но для печатных форм, отчетов и выгрузки в текстовые файлы функция Формат() является основным инструментом. Она также позволяет учитывать часовой пояс при конвертации, если это явно указано в параметрах.

💡

Используйте формат "ДФ=dd.MM.yyyy 'г.' HH:mm:ss" для создания понятных человеку штампов времени в печатных формах. Это избавит пользователей от необходимости мысленно расшифровывать стандартный формат 1С.

ТекущееВремя = ТекущаяДата();

СтрокаВремени = Формат(ТекущееВремя, "ДФ=dd.MM.yyyy; ВФ=HH:mm:ss");

// Результат: "25.10.2023; 14:30:00"

Стоит отметить, что функция Формат() возвращает строку (Строка), а не дату. Обратное преобразование строки в дату выполняется функцией Дата() или СтрокаВДата(), но требует строгого соответствия формата входной строки ожидаемому шаблону. Ошибка в формате приведет к получению пустой даты (0001-01-01).

Работа с часовыми поясами и UTC

В современных распределенных системах, особенно при интеграции с веб-сервисами или работе облачных версий 1С, критически важно понятие универсального координированного времени (UTC). Локальное время пользователя может отличаться от времени сервера на несколько часов из-за часового пояса и перехода на летнее/зимнее время.

Платформа 1С предоставляет функции для конвертации между локальным временем и UTC. Функция УниверсальнаяДата(Дата) преобразует локальное время в UTC, а МестноеВремя(Дата) выполняет обратное преобразование. Это необходимо при обмене данными с системами, которые хранят время в UTC, например, с большинством современных API и баз данных PostgreSQL.

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

☑️ Проверка временных настроек

Выполнено: 0 / 4

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

Частые ошибки и лучшие практики

Несмотря на кажущуюся простоту, работа со временем в 1С таит в себе множество подводных камней. Одна из самых распространенных ошибок — сравнение дат с разным временным компонентом. Если вы сравниваете дату документа (где есть время) с границей периода (где время обнулено функцией НачалоПериода), результаты могут быть непредсказуемыми без явного указания условий сравнения.

Еще одна проблема — использование ТекущаяДата() внутри циклов. Если цикл выполняется быстро, время может не измениться, но если цикл долгий или происходит переключение контекста, время может «скакать». Для фиксации момента начала процесса лучше записать время в переменную перед входом в цикл и использовать эту переменную.

Также стоит избегать хранения даты в виде строки в базе данных. Всегда используйте тип Дата. Хранение в строке лишает вас возможности использовать эффективные индексы, стандартные функции периодов и приводит к проблемам сортировки (например, "01.02.2023" может быть отсортировано иначе, чем дата).

💡

Золотое правило разработчика 1С: Храните даты в базе в типе Дата, сравнивайте их с учетом временной компоненты, а для пользователей отображайте в локальном времени через функцию Формат().

FAQ: Часто задаваемые вопросы

Как получить только текущую дату без времени?

Используйте функцию НачалоПериода(ТекущаяДата(), Период.День). Это вернет дату с временем 00:00:00. Простое присваивание не уберет время, так как тип Дата всегда хранит и дату, и время.

Почему время в отчете отличается от времени на моем компьютере?

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

Как добавить к дате 1 час или 5 дней?

В 1С даты можно складывать с числами. Число интерпретируется как дни. Для добавления часов нужно добавить дробную часть: НоваяДата = СтараяДата + 5 + (1/24). Либо используйте функцию ДобавитьКДате().

Что вернет Дата("20230230")?

Это вызовет ошибку выполнения, так как 30 февраля не существует. Платформа строго контролирует корректность календарных дат при конструировании объекта.

Как узнать количество секунд между двумя датами?

Просто вычтите одну дату из другой: Разница = Дата2 - Дата1. Результат будет числом, представляющим количество секунд. Для получения дней разделите результат на 86400.