Разработка эффективных конфигураций на платформе 1С:Предприятие невозможна без глубокого понимания того, как система обрабатывает временные интервалы. Дата и время являются фундаментальными типами данных, используемыми в регистрах накопления, отчетах и бизнес-процессах. Ошибки при работе с ними могут привести к некорректному начислению зарплаты или искажению остатков на складе.
В этой статье мы детально разберем механизмы получения текущего времени, извлечения конкретных компонентов (год, месяц, день) и преобразования строковых представлений в полноценные объекты. Вы узнаете о нюансах часовых поясов и о том, как избежать распространенных ошибок при сравнении временных меток.
Платформа предоставляет мощный инструментарий для манипуляций с календарем. Однако простота базовых функций часто вводит в заблуждение начинающих разработчиков, которые упускают из виду специфику внутреннего хранения значений. Мы рассмотрим как стандартные методы, так и скрытые возможности встроенного языка.
Получение текущей даты и времени
Самая базовая операция, с которой сталкивается программист — это фиксация момента выполнения кода. Для этого используется встроенная функция ТекущаяДата. Она возвращает значение типа Дата, содержащее текущие дату и время с точностью до секунды, согласно настройкам операционной системы пользователя или сервера.
Если вам требуется получить только дату без времени (обнулить часы, минуты и секунды), удобно применять функцию НачалоДня. Это критически важно при формировании выборок из баз данных, где точное совпадение времени может привести к потере нужных записей. Например, при отборе документов за сегодня условие Дата = ТекущаяДата сработает только в одну конкретную секунду, что неверно.
Иногда возникает необходимость получить начало или конец более крупных периодов. Платформа предлагает готовый набор функций для таких задач, что избавляет от ручных вычислений.
- 📅
НачалоМесяца(Дата)— возвращает первое число месяца 00:00:00. - 📅
КонецМесяца(Дата)— возвращает последний день месяца 23:59:59. - 📅
НачалоГода(Дата)— устанавливает дату на 1 января 00:00:00. - 📅
КонецГода(Дата)— устанавливает дату на 31 декабря 23:59:59.
⚠️ Внимание: Функция
ТекущаяДатав тонком клиенте возвращает время локальной машины пользователя, а не сервера 1С. При работе в распределенной информационной базе это может привести к рассинхронизации документов, созданных разными пользователями в разных часовых поясах.
Извлечение компонентов даты (Год, Месяц, День)
Часто требуется проанализировать существующую дату и выделить из нее отдельную часть. Например, для группировки продаж по кварталам или проверки високосного года. Для этих целей в языке 1С предусмотрен ряд функций-селекторов.
Чтобы получить числовой год, используется функция Год(Дата). Аналогично работают функции Месяц(Дата) и День(Дата).
Для получения номера недели или квартала также существуют специализированные функции. Они автоматически учитывают правила календаря и позволяют быстро (классифицировать) данные для отчетов.
ТекущийГод = Год(ТекущаяДата);
ТекущийМесяц = Месяц(ТекущаяДата);
НомерКвартала = НомерКвартала(ТекущаяДата);
Помимо числовых значений, часто требуется получить текстовое представление, например, название месяца для печати в документе. Функция МесяцСтр(Дата) возвращает строку"Январь","Февраль" и так далее, в зависимости от локали системы.
- 🔢
Час(Дата)— возвращает час от 0 до 23. - 🔢
Минута(Дата)— возвращает минуту от 0 до 59. - 🔢
Секунда(Дата)— возвращает секунду от 0 до 59. - 🔢
ДеньНедели(Дата)— возвращает номер дня (1-Понедельник.. 7-Воскресенье).
Для определения количества дней в месяце не нужно писать сложные условия. Просто используйте функцию КонецМесяца(Дата) и извлеките из результата День.
Конструирование даты из отдельных значений
Обратная задача — создание объекта даты из разрозненных чисел — решается с помощью функции Дата. Она принимает три обязательных аргумента: год, месяц и день. Если время не указано, оно по умолчанию устанавливается в 00:00:00.
Существует также расширенная версия этой функции, позволяющая задать точное время. Это необходимо при создании документов с жесткой привязкой к временной метке, например, при импорте данных из внешних систем логов.
| Функция | Аргументы | Результат |
|---|---|---|
Дата(2023, 10, 5) |
Год, Месяц, День | 05.10.2023 00:00:00 |
Дата(2023, 10, 5, 14, 30) |
Год, Месяц, День, Час, Минута | 05.10.2023 14:30:00 |
Дата(2023, 10, 5, 14, 30, 45) |
Год, Месяц, День, Час, Минута, Секунда | 05.10.2023 14:30:45 |
При конструировании даты платформа автоматически выполняет нормализацию. Если вы укажете 32-е число месяца, система перенесет дату на первое число следующего месяца. Это поведение может быть как полезным, так и опасным, если не контролировать ввод данных пользователем.
Особенность високосных годов
Функция Дата автоматически корректно обрабатывает високосные годы. Если вы попытаетесь создать дату 29 февраля в невисокосном году (например, 2023), результат будет равен 01.03.2023.
Преобразование строки в дату и обратно
Взаимодействие с пользователем или внешними файлами часто требует конвертации текстовых данных. Для преобразования строки в дату используется функция Дата (в варианте с одним строковым аргументом) или СтрокаВДату в некоторых контекстах, но основным методом является явное приведение типов или функция ПолучитьДатуВремени в зависимости от версии платформы.
Стандартный способ — использование функции Дата(Строка). Она пытается распознать формат даты автоматически. Однако надежность этого метода зависит от региональных настроек операционной системы.
СтрокаДаты ="25.12.2023";
МояДата = Дата(СтрокаДаты);
Для обратного преобразования, когда дату нужно вывести на экран или записать в текстовый файл, применяется функция Формат. Она позволяет гибко настраивать вид строки, используя специальные параметры формата.
- 📝
Формат(Дата,"ДФ=dd.MM.yyyy")— формат"25.12.2023". - 📝
Формат(Дата,"ДФ=dd.MM.yyyy ЧЧ:мм")— формат"25.12.2023 14:30". - 📝
Формат(Дата,"ДФ=LONG")— длинный формат"25 декабря 2023 г.".
⚠️ Внимание: При парсинге дат из строки всегда учитывайте разделители. В русской локали это точки, в американской — слеши. Неявное преобразование может привести к ошибке выполнения, если формат строки не совпадает с ожидаемым.
Арифметические операции с датами
Платформа 1С поддерживает прямые арифметические действия над датами. Вы можете складывать даты с числами или вычитать их. Единицей измерения при сложении числа с датой является секунда.
Чтобы добавить один день к текущей дате, необходимо прибавить количество секунд в сутках (86400). Это может показаться неудобным, поэтому для упрощения существуют функции сдвига.
Функция ДобавитьКДате позволяет добавлять интервалы specified в специальных единицах измерения: годы, месяцы, дни, часы. Это гораздо читабельнее и безопаснее, чем ручные вычисления секунд.
НоваяДата = ДобавитьКДате(ТекущаяДата, Интервал.День, 1);
ПрошлыйГод = ДобавитьКДате(ТекущаяДата, Интервал.Год, -1);
Разность двух дат возвращает число секунд, прошедших между ними. Для получения разницы в днях результат делится на 86400. При этом важно учитывать, что дробная часть может указывать на неполный день.
Используйте функцию ДобавитьКДате вместо ручной арифметики секунд для повышения читаемости кода и избежания ошибок при переходе через високосные годы или границы месяцев.
Сравнение дат и работа с интервалами
Сравнение дат в 1С выполняется стандартными операторами: =, <, >, <=, >=. Операторы сравнивают даты с точностью до секунды. Это значит, что две даты, отличающиеся на миллисекунды (что возможно при импорте), будут считаться неравными.
При формировании запросов к базе данных частой ошибкой является попытка выбрать все документы за день, указав начало и конец дня inclusively. Более надежный способ — использовать полуоткрытый интервал.
Вместо условия Между НачалоДня(Дата) И КонецДня(Дата), которое может потерять документы, созданные в последнюю миллисекунду дня, лучше использовать: >= НачалоДня(Дата) И < НачалоДня(Дата + 1).
☑️ Проверка корректности интервала
⚠️ Внимание: Сравнение дат, полученных от разных источников (сервер vs клиент), может дать неожиданные результаты из-за рассинхронизации часов. Всегда приводите даты к единому источнику времени перед сравнением в критических алгоритмах.
Часто задаваемые вопросы (FAQ)
Как получить текущую дату без времени в запросе 1С?
В языке запросов 1С используется функция НАЧАЛОДНЯ. Пример: ВЫБРАТЬ НАЧАЛОДНЯ(Ссылка.Дата) ИЗ Документ.Реализация. Это позволит сгруппировать данные по дням, игнорируя время проведения.
Почему при сравнении дат в условии отбора не выбираются документы?
Скорее всего, проблема в точности сравнения. Если вы сравниваете дату документа с датой, введенной пользователем (где время обнулено), документы, проведенные днем, не попадут в выборку. Используйте интервалы от начала дня до начала следующего дня.
Как определить, является ли год високосным в 1С?
Создайте дату 29 февраля нужного года с помощью функции Дата и проверьте месяц полученной даты. Если Месяц(Дата(Год, 2, 29)) = 2, то год високосный. Если месяц стал 3, значит, 29 февраля не существовало.
Можно ли хранить дату без времени в типе Дата?
Нет, тип Дата в 1С всегда хранит и время. Чтобы имитировать хранение только даты, принято явно обнулять время с помощью функции НачалоДня перед записью в базу данных или сравнением.