В процессе разработки конфигураций и написания обработок в системе 1С:Предприятие часто возникает необходимость зафиксировать точный момент выполнения операции. Это может потребоваться для логирования действий пользователя, формирования временных меток в документах или расчета сроков исполнения задач. Понимание того, как корректно извлечь текущее время, является базовым навыком для любого разработчика платформы.
Казалось бы, задача тривиальна, но платформа 1С предлагает несколько механизмов получения временных данных, каждый из которых имеет свои особенности поведения в файловом и клиент-серверном вариантах работы. Неверный выбор метода может привести к рассинхронизации данных между клиентом и сервером или ошибкам при работе в разных часовых поясах. В этой статье мы детально разберем все доступные способы и нюансы их применения.
Важно сразу отметить, что платформа различает понятия «время системы» и «время сеанса». Эти сущности могут не совпадать, особенно в распределенных информационных системах, где сервер базы данных может находиться в другом регионе. Правильное использование инструментов платформы гарантирует целостность данных и предсказуемость работы вашего программного кода.
Основные функции получения времени
Самым распространенным и часто используемым методом является вызов глобальной функции ТекущаяДата(). Этот метод возвращает значение типа Дата, содержащее текущую дату и время согласно настройкам операционной системы компьютера, на котором выполняется код. Если код выполняется на клиенте, вы получите время клиента, если на сервере — время сервера.
Однако существует важный нюанс, о котором часто забывают начинающие разработчики. Функция ТекущаяДата() возвращает время с точностью до секунды, но при записи в базу данных или сравнении значений могут возникать ситуации, когда миллисекунды играют роль. Для большинства бизнес-задач этого достаточно, но для высокоточного логирования стоит учитывать особенности хранения типа Date в СУБД.
В клиент-серверном варианте работы критически важно понимать, где именно выполняется ваш код. Вызов этой функции в модуле формы вернет время рабочей станции пользователя, а в модуле менеджера или общем модуле с признаком «Сервер» — время сервера 1С. Это различие может стать причиной ошибок при проверке условий «вовремя/не вовремя».
⚠️ Внимание: Никогда не используйте
ТекущаяДата()в условиях запросов, выполняемых на сервере, если вам критично время клиента. В таком случае время будет взято с сервера, что может отличаться от времени пользователя на несколько часов.
Если вам нужно зафиксировать время создания документа именно по часам пользователя, передавайте значение даты из клиентского модуля в серверный метод в качестве параметра.
Рассмотрим пример простого присваивания значения переменной. Синтаксис предельно прост и не требует подключения дополнительных библиотек:
ДатаСейчас = ТекущаяДата();
Сообщить("Текущее время: " + ДатаСейчас);
Различия между ТекущаяДата и ТекущаяДатаСеанса
Для решения проблем рассинхронизации времени в распределенных системах платформа предоставляет функцию ТекущаяДатаСеанса(). Этот метод возвращает дату и время, установленные для текущего сеанса работы с базой данных. Значение формируется на основе настроек сеанса и не зависит от того, где выполняется код — на клиенте или на сервере.
Использование ТекущаяДатаСеанса() является предпочтительным способом при записи временных меток в документы в клиент-серверном режиме. Это гарантирует, что все пользователи, независимо от их географического положения и настроек локального времени, будут видеть единую временную шкалу в документах, сформированных в рамках одного сеанса.
Однако стоит помнить, что время сеанса может быть явно установлено программно или через параметры запуска. Если администратор базы данных изменил настройки сеанса, функция вернет именно это измененное значение, а не реальное астрономическое время. Это полезно для тестирования, но требует осторожности в промышленной эксплуатации.
- 🕒 ТекущаяДата() — возвращает время ОС (клиента или сервера в зависимости от контекста).
- 🌐 ТекущаяДатаСеанса() — возвращает унифицированное время сеанса, одинаковое для клиента и сервера.
- ⚙️ Настройка сеанса — может влиять на возвращаемое значение функции сеанса.
В таблице ниже приведено сравнение поведения функций в различных контекстах выполнения кода:
| Контекст выполнения | Функция ТекущаяДата() | Функция ТекущаяДатаСеанса() | Рекомендация |
|---|---|---|---|
| Тонкий клиент (Форма) | Время компьютера пользователя | Время сеанса (обычно совпадает с сервером) | Для отображения пользователю |
| Сервер 1С (Модуль объекта) | Время сервера 1С | Время сеанса | Для записи в документы |
| Файловая база | Время компьютера | Время компьютера | Различий нет |
| Внешнее соединение | Время сервера | Время сеанса подключения | Зависит от настроек |
Работа с часовыми поясами и смещениями
В современных версиях платформы 1С:Предприятие 8.3 реализована полноценная поддержка часовых поясов. Это позволяет корректно работать с данными в международных компаниях, где филиалы расположены в разных регионах. Для получения текущего времени с учетом конкретного часового пояса используется объект ЧасовойПояс.
Чтобы получить время в конкретном поясе, необходимо сначала найти нужный пояс в классификаторе, а затем выполнить конвертацию. Платформа автоматически учитывает переход на летнее/зимнее время, если это предусмотрено правилами для выбранного региона. Это избавляет разработчика от необходимости писать сложные алгоритмы коррекции времени вручную.
Код для получения времени в часовом поясе "Москва" может выглядеть следующим образом. Обратите внимание на использование контекста для поиска пояса:
Попытка
ЧП = ЧасовойПояса.НайтиПоНаименованию("Москва");
Если ЧП = Неопределено Тогда
ЧП = ЧасовойПояса.Москва;
КонецЕсли;
ВремяВМоскве = ТекущаяДатаСеанса() + ЧП.СмещениеОтUTC;
Исключение
// Обработка ошибки, если пояс не найден
КонецПопытки;
⚠️ Внимание: Смещение от UTC может меняться динамически в зависимости от даты, так как правила перехода на летнее время меняются законодательно. Всегда используйте методы объекта
ЧасовойПоясдля расчета, а не жестко заданные константы часов.
При хранении дат в базе данных рекомендуется использовать универсальное координированное время (UTC) или время сервера, а конвертацию в локальное время пользователя выполнять только на этапе отображения в интерфейсе. Такой подход упрощает отчетность и анализ данных across different regions.
Почему не стоит хранить локальное время?
Хранение локального времени пользователя в базе данных приводит к хаосу при анализе. Например, документ созданный в 10:00 в Москве и документ созданный в 10:00 во Владивостоке физически созданы в разное время, но в базе будут выглядеть одинаково.
Получение отдельных компонентов времени
Часто разработчику требуется не полная дата, а конкретная её составляющая: час, минута или секунда. Платформа 1С предоставляет набор встроенных функций для извлечения этих компонентов из значения типа Дата. Это позволяет гибко формировать условия отбора или выполнять арифметические операции.
Для получения часа используется функция Час(), для минут — Минута(), а для секунд — Секунда(). Все эти функции принимают на вход значение даты и возвращают целое число. Это удобно, например, при реализации логики работы системы в зависимости от времени суток (утро, день, вечер).
Пример использования для проверки рабочего времени:
ТекущийЧас = Час(ТекущаяДатаСеанса());
Если ТекущийЧас >= 9 И ТекущийЧас < 18 Тогда
Статус = "Рабочее время";
Иначе
Статус = "Внерабочее время";
КонецЕсли;
Также существует функция НачалоЧаса(), которая возвращает дату, усеченную до начала текущего часа (минуты и секунды обнуляются). Это часто используется при группировке данных в отчетах по часам. Аналогично работают функции НачалоМинуты() и НачалоДня().
- ⏱️
Час(Дата)— возвращает число от 0 до 23. - 📟
Минута(Дата)— возвращает число от 0 до 59. - ⏳
Секунда(Дата)— возвращает число от 0 до 59.
Они не обращаются к системному времени повторно, а анализируют переданный параметр. Это делает их безопасными для использования внутри циклов и запросов.
Используйте функции усечения времени (НачалоЧаса, НачалоДня) для оптимизации индексов при отборе данных в запросах.
Использование времени в запросах к базе данных
При написании запросов к базе данных часто возникает необходимость отобрать документы за определенный период или найти записи, созданные сегодня. В языке запросов 1С есть специальные ключевые слова и функции, позволяющие работать с датой непосредственно в тексте запроса, что повышает производительность.
Для получения текущей даты и времени в запросе используется ключевое слово &Сейчас (в параметризированных запросах) или функция ТЕКУЩАЯДАТА() внутри текста запроса. Однако лучшим тоном считается передача даты из кода 1С в параметр запроса. Это позволяет движку запросов эффективнее планировать выполнение.
Рассмотрим пример выборки документов, созданных в текущем месяце. Здесь мы используем функции НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА в сочетании с текущей датой:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Документы.РеализацияТоваровУслуг.Ссылка КАК Ссылка,
| Документы.РеализацияТоваровУслуг.Дата КАК Дата
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Документы
|ГДЕ
| Документы.Дата МЕЖДУ &НачалоМесяца И &КонецМесяца";
Запрос.УстановитьПараметр("НачалоМесяца", НачалоМесяца(ТекущаяДатаСеанса()));
Запрос.УстановитьПараметр("КонецМесяца", КонецМесяца(ТекущаяДатаСеанса()));
Результат = Запрос.Выполнить();
Использование параметров запроса вместо прямой подстановки функций в текст запроса дает еще одно важное преимущество: возможность переиспользовать план выполнения запроса сервером СУБД. Это особенно критично в высоконагруженных системах, где счет идет на миллионы документов.
⚠️ Внимание: При работе с полями типа
ДатаВремяв условиях запроса помните, что сравнение идет вплоть до миллисекунд. Если вы сравниваете дату документа сТекущаяДата(), вы можете не найти документ, созданный секундой ранее. Используйте усечение до дня или минуты при необходимости.
☑️ Оптимизация запросов по дате
Частые ошибки и лучшие практики
Несмотря на простоту получения времени, разработчики регулярно совершают типичные ошибки, которые приводят к трудноуловимым багам. Одна из самых распространенных — смешение времени клиента и сервера в одной логической операции. Например, сравнение даты документа (записанной по серверу) с текущим временем клиента может дать ложный результат.
Еще одна проблема связана с точностью. Тип Дата в 1С хранит значение с точностью до миллисекунды, но при выводе в интерфейсе или экспорте в Excel часто происходит округление. При сравнении двух дат, полученных в разное время разными способами, рекомендуется использовать допустимую погрешность или сравнивать усеченные значения.
Также стоит упомянуть о проблеме "вечных" дат. Иногда для обозначения отсутствия времени используют дату 01.01.1900 или 01.01.2000. При фильтрации по текущему времени такие записи могут непредсказуемо попадать в выборки, если не выставлены строгие границы отсечки. Всегда явно проверяйте значимость даты перед использованием.
Соблюдение следующих правил поможет избежать большинства проблем:
- 🔒 Всегда используйте
ТекущаяДатаСеанса()для записи дат в документы в клиент-серверном режиме. - 🔄 Передавайте дату из клиентского приложения на сервер явным параметром, если важно время пользователя.
- 📉 Используйте усечение даты (НачалоДня) для группировки и индексации в запросах.
Правильная работа со временем — это фундамент стабильной системы. Уделяйте внимание выбору правильного метода получения даты на этапе проектирования, чтобы не переписывать логику в дальнейшем.
Как тестировать время?
Для тестирования логики, зависящей от времени, используйте процедуру УстановитьВремяСеанса() в коде теста. Это позволит имитировать любую дату и время без изменения системных часов компьютера.
В чем разница между ТекущаяДата() и Теперь()?
Функция Теперь() является устаревшим синонимом функции ТекущаяДата(). Она оставлена для совместимости со старыми версиями платформы и конфигурациями. В новом коде рекомендуется использовать только ТекущаяДата() или ТекущаяДатаСеанса() для ясности намерений разработчика.
Как получить время с миллисекундами?
Функция ТекущаяДата() возвращает значение типа Дата, которое внутренне хранит миллисекунды. Однако стандартные функции вывода часто их скрывают. Чтобы увидеть или использовать миллисекунды, работайте с объектом напрямую или используйте свойство Миллисекунда (доступно в некоторых версиях через дополнительные обработки) либо вычисляйте разницу между датами.
Почему время на сервере отличается от моего?
Сервер 1С Предприятие может физически располагаться в другом часовом поясе. Кроме того, на сервере может быть установлено иное системное время администратором. Для синхронизации используйте время сеанса, которое платформа транслирует клиенту, или явно передавайте локальное время клиента в серверные процедуры.
Можно ли изменить текущее время в 1С?
Изменить системное время компьютера или сервера из кода 1С невозможно из соображений безопасности. Однако вы можете изменить время текущего сеанса с помощью процедуры УстановитьВремяСеанса(). Это повлияет на все последующие вызовы ТекущаяДатаСеанса() в рамках этого подключения, что удобно для тестирования.
Как корректно сравнить две даты с разным временем?
Если время не важно, используйте функции усечения: НачалоДня(Дата1) = НачалоДня(Дата2). Если нужно проверить, что дата наступила, используйте операторы сравнения с учетом погрешности или сравнивайте целочисленное представление дат. Избегайте прямого сравнения на равенство для дат, полученных в разных местах системы.