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

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

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

Базовая функция получения времени

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

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

Рассмотрим простейший пример присваивания значения переменной:

Перем МояДата;

// ...

МояДата = ТекущаяДата();

Сообщить("Текущее время: " + МояДата);

Обратите внимание, что переменная должна быть объявлена или неявно типизирована как Дата. Если вы попытаетесь присвоить результат функции строковой переменной без явного преобразования, платформа может выдать предупреждение или выполнить неявное приведение типов, что не всегда желательно для чистоты кода.

💡

При работе в файловом варианте базы данных время берется с локального компьютера пользователя, а в клиент-серверном варианте — с той машины, где запущен конкретный клиентский сеанс (толстый или тонкий клиент).

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

Наиболее частый сценарий использования — установка даты создаваемого документа. Обычно это делается в модуле объекта или в модуле менеджера перед записью. Однако здесь существует важный нюанс: реквизит Дата у документа и системная дата могут не совпадать из-за настроек интерфейса или прав доступа.

При создании нового объекта через код, например, с помощью метода СоздатьДокумент(), поле даты по умолчанию часто заполняется текущим временем. Но если вам нужно явно переопределить это значение или установить дату для уже существующего объекта, используется прямое присваивание свойства.

Алгоритм действий выглядит следующим образом:

  • 📅 Создаем новый объект документа с помощью менеджера.
  • ⏱ Вызываем функцию ТекущаяДата() и сохраняем результат во временную переменную.
  • 💾 Присваиваем значение реквизиту Дата объекта перед вызовом метода Записать().

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

⚠️ Внимание: Если вы работаете в режиме предприятия с включенной блокировкой дат, присвоение текущей даты может быть проигнорировано системой, если она выходит за рамки разрешенного интервала. Всегда проверяйте свойство Дата после записи.
📊 Как вы чаще всего получаете дату в коде?
Вызываю ТекущаяДата() каждый раз
Записываю в переменную один раз
Беру из системной даты документа
Использую глобальный контекст

Разделение даты и времени в 1С

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

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

Пример использования для очистки времени:

Перем ЧистаяДата;

ЧистаяДата = НачалоДня(ТекущаяДата());

// Теперь в ЧистаяДата время равно 00:00:00

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

В таблице ниже приведены основные функции для работы с частями даты:

Функция Описание Пример результата
ТекущаяДата() Возвращает полную дату и время 25.10.2023 14:30:15
НачалоДня() Обнуляет время, оставляя дату 25.10.2023 00:00:00
КонецДня() Устанавливает время на 23:59:59 25.10.2023 23:59:59
Время() Извлекает только время из даты 14:30:15
💡

Всегда используйте НачалоДня() при сравнении дат в условиях запросов, чтобы избежать ошибок из-за несовпадения временных компонент.

Форматирование даты в строку

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

Для контролируемого преобразования используется глобальный метод Формат(). Он позволяет задать точный шаблон вывода, используя специальные символы описания формата. Это дает возможность получать строки вида "25102023" или "25.10.2023 14:30" независимо от региональных настроек Windows.

Синтаксис функции требует указания форматируемого значения и строки описания формата:

Перем СтрокаДаты;

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

В строке формата символ ДФ указывает на дату-время, а последующие коды определяют порядок вывода элементов. Использование такого подхода гарантирует, что ваша программа будет вести себя предсказуемо на компьютерах с разными языковыми стандартами.

При формировании имен файлов или уникальных ключей часто используют компактный формат без разделителей:

  • 📂 Для имен файлов: Формат(Дата, "ДФ='yyyyMMdd_HHmmss'").
  • 🔑 Для кодов документов: Формат(Дата, "ДФ='yyMMdd'").
  • 📝 Для отчетов: Формат(Дата, "ДФ='d MMMM yyyy г.'").

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

Секрет продвинутого форматирования

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

Особенности работы в запросах

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

Основной заменой служит конструкция &ТекущаяДата или функция СЕГОДНЯ() в зависимости от диалекта и версии платформы. Однако наиболее надежным и универсальным способом является передача значения из кода 1С в параметр запроса.

Рассмотрим правильный алгоритм работы с датами в запросах:

  1. Создаем объект запроса и пишем текст с параметром.
  2. В коде 1С получаем текущую дату через ТекущаяДата().
  3. Устанавливаем значение параметра запроса методом УстановитьПараметр().

Такой подход обеспечивает защиту от SQL-инъекций (хотя в 1С это менее актуально) и позволяет переиспользовать текст запроса с разными датами без его компиляции заново. Кроме того, это дает возможность явно контролировать тип передаваемого значения.

ТекстЗапроса = "ВЫБРАТЬ * ИЗ Документ.РеализацияТоваровУслуг ГДЕ Дата > &НачалоПериода";

Запрос = Новый Запрос(ТекстЗапроса);

Запрос.УстановитьПараметр("НачалоПериода", ТекущаяДата());

Результат = Запрос.Выполнить();

Использование параметров также ускоряет выполнение запросов в клиент-серверном варианте, так как план выполнения может кэшироваться сервером 1С:Предприятие.

⚠️ Внимание: При передаче даты в запрос убедитесь, что вы передаете именно тип Дата, а не строку. Передача строки может привести к неявному преобразованию и замедлению выборки из-за отсутствия использования индексов по дате.

Часовые пояса и распределенные базы

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

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

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

  • 🌐 Хранить все даты в базе в UTC и конвертировать только при отображении.
  • 🖥 Использовать серверное время через вызов общей модуля на стороне сервера.
  • ⏳ Учитывать смещение часового пояса при расчете периодов отчетности.

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

☑️ Проверка корректности работы с датой

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

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

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

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

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

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

Можно ли присвоить текущую дату строковой переменной напрямую?

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

Что делать, если ТекущаяДата() возвращает неверное время в веб-клиенте?

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

Как записать дату в формате YYYYMMDD для выгрузки?

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