Что такое смещение дат в 1С и почему возникает ошибка при записи в базу на MS SQL Server?

Системный администратор 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с базами данных 1С:Предприятие, развернутыми на сервере Microsoft SQL Server, администраторы и разработчики часто сталкиваются со специфической ошибкой: Дата '31.12.0001 23:59:59' не может быть записана в базу данных на MS SQL Server с нулевым смещением дат. Давайте разберем природу этого явления, выясним, почему архитектуры двух систем вошли в противоречие, и как правильно настроить смещение, чтобы избежать подобных проблем в будущем.

Причина возникновения конфликта: Разница в диапазонах дат

Для начала проанализируем, как хранят время обе системы. В платформе 1С:Предприятие 8 тип данных Дата охватывает диапазон от 1 января 1 года нашей эры до 31 декабря 9999 года. При этом дата 01.01.0001 00:00:00 считается «пустой» датой (значением по умолчанию).

С другой стороны, в классических версиях MS SQL Server для хранения дат долгое время использовался тип данных DATETIME. У этого типа есть существенное ограничение: он поддерживает диапазон дат только начиная с 1 января 1753 года. Даты, предшествующие этой отметке, SQL-сервер обработать в поле этого типа не может.

Рассмотрим подробнее, к чему это приводит: если конфигурация 1С пытается записать в базу данных дату, которая меньше 1753 года (например, ту самую пустую дату или ошибочно введенный 201 год вместо 2021), SQL-сервер возвращает ошибку, так как значение выходит за пределы его физических возможностей хранения.

Что такое параметр «Смещение дат»?

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

Разберем по шагам, как работают два основных режима смещения:

  1. Смещение 0: В этом режиме даты передаются «как есть». Исключение сделано только для интервала от 01.01.0001 до 01.01.0001 23:59:59 (так называемое «время без даты»), который принудительно преобразуется в диапазон начала 1753 года. Однако любая другая дата в интервале от 0002 года до 1752 года вызовет фатальную ошибку.
  2. Смещение 2000: Это наиболее безопасный режим. Платформа автоматически прибавляет 2000 лет к любой дате перед ее записью в SQL. Например, документ от 2023 года будет храниться в таблице SQL с датой 4023 год. При чтении данных платформа выполняет обратную операцию — вычитает 2000 лет. Это позволяет беспрепятственно хранить в базе даже самые ранние даты (начиная с 1 года н.э.), так как в SQL они превратятся в даты начиная с 2001 года.

Почему происходят ошибки при нулевом смещении?

Проанализируем типичную ситуацию из практики. Программист использует метод НайтиПоНомеру или пытается восстановить нумерацию документов. В процессе выполнения кода в объект попадает незаполненная дата (пустая), или в результате логической ошибки (например, при расчете периода) формируется дата, близкая к началу нашей эры. Если база создана со смещением 0, попытка записи такого объекта приведет к немедленной остановке процесса.

Чаще всего такие ошибки — это «карма» за невнимательность пользователей или недоработки в коде:

Влияние на производительность и внешние системы

Многие задаются вопросом: не замедляет ли смещение 2000 работу системы? Выясним это. Теоретически, при каждом чтении и записи процессору приходится выполнять арифметическую операцию вычитания или сложения. Однако в современных реалиях эти затраты ничтожны по сравнению с временем выполнения самого SQL-запроса или передачи данных по сети. На практике разница в производительности практически неощутима.

Основная сложность смещения 2000 заключается в интеграции. Если вы планируете строить отчеты в Power BI, Excel или использовать прямые SQL-запросы к базе 1С, вы столкнетесь с тем, что все даты «улетели» в будущее. Вам придется в каждом запросе использовать функцию DATEADD:


SELECT 
    DATEADD(year, -2000, DateColumn) as RealDate,
    Number
FROM 
    _Document150

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

Современное состояние: тип DATETIME2

Важно отметить, что в современных версиях MS SQL Server (начиная с 2008 года) существует тип данных DATETIME2, который поддерживает даты от 1 года нашей эры. Казалось бы, это должно было решить проблему навсегда. Однако 1С:Предприятие сохраняет механизм смещения для обеспечения обратной совместимости. Платформа должна гарантировать, что база, созданная 15 лет назад, сможет работать на новом сервере без тотальной переработки структуры таблиц.

Как изменить смещение в существующей базе?

Если вы обнаружили, что ваша база страдает от ошибок из-за нулевого смещения, просто поменять галочку в настройках не получится. Изменение смещения «на лету» сделало бы все существующие даты нечитаемыми (они бы внезапно сдвинулись на 2000 лет). Рассмотрим правильный алгоритм действий:

  1. Создайте полную резервную копию базы данных.
  2. Выгрузите информационную базу в файл конфигурации .dt через Конфигуратор.
  3. Удалите текущую базу из списка кластера (и, желательно, саму БД с SQL-сервера).
  4. Создайте новую информационную базу в кластере 1С, выбрав в диалоге создания параметр Смещение дат: 2000.
  5. Загрузите ранее созданный файл .dt в новую пустую базу.

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

Резюме и рекомендации

Мы проанализировали ситуацию и можем сделать следующие выводы: смещение дат 2000 является наиболее надежным выбором для большинства корпоративных систем. Оно страхует от человеческих и программных ошибок, связанных с некорректными датами. Выбирать смещение 0 стоит только в тех случаях, когда критически важна чистота данных в SQL для внешних аналитических систем и вы на 100% уверены в чистоте своего кода и внимательности пользователей.

← На главную