Как получить дату сервера PostgreSQL в 1С без смещения часового пояса?

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

При работе с внешними источниками данных (ВИД) в 1С программисты часто сталкиваются с проблемой автоматического преобразования дат. Типичная ситуация: сервер базы данных PostgreSQL настроен на UTC-0, а сервер приложений 1С находится в часовом поясе UTC+3. При запросе даты через ODBC-драйвер платформа 1С или сам драйвер автоматически добавляют разницу в 3 часа, что искажает данные для бизнес-логики. Давайте разберем, почему это происходит и какими способами можно добиться получения «чистой» локальной даты сервера базы данных.

Анализируем причину возникновения смещения

Прежде чем переходить к решениям, проанализируем ситуацию. В PostgreSQL хранение даты и времени зависит от используемого типа данных: timestamp without time zone или timestamp with time zone (timestamptz). Если используется второй вариант, PostgreSQL хранит данные в формате UTC, но при выдаче результата клиенту (в нашем случае — драйверу ODBC) автоматически преобразует их в часовой пояс текущей сессии. Если часовой пояс сессии явно не задан, сервер использует настройки своей операционной системы или настройки по умолчанию из postgresql.conf. Однако драйвер на стороне клиента (сервера 1С) может передавать свои параметры или интерпретировать полученный результат в соответствии с локальными настройками системы 1С.

Способ 1. Настройка часового пояса для конкретного пользователя базы данных

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

  1. Откройте консоль управления PostgreSQL (например, pgAdmin или psql).
  2. Выполните SQL-команду для изменения параметров пользователя. Допустим, ваш пользователь называется user_1c, и вы хотите, чтобы он всегда видел время в UTC-0:

ALTER ROLE user_1c SET TimeZone = 'UTC';

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

Способ 2. Использование параметра ConnSettings в строке подключения

Если у вас нет прав на изменение настроек пользователя в базе данных или вы хотите управлять смещением динамически из кода 1С, рассмотрим вариант с изменением строки подключения. В параметрах ODBC существует ключ ConnSettings, который позволяет выполнить SQL-команду сразу после авторизации.

Проанализируем пример строки подключения для внешнего источника данных:


DRIVER={PostgreSQL Unicode}; SERVER=my_server; PORT=5432; DATABASE=my_db; UID=my_user; PWD=my_pass; ConnSettings=SET time zone 'UTC';

Параметр ConnSettings=SET time zone 'UTC'; заставляет сессию переключиться на нужное время немедленно после установки связи. Это гарантирует, что все последующие запросы к timestamp with time zone будут возвращать значения в UTC.

Способ 3. Преобразование типов в SQL-запросе (AT TIME ZONE)

Рассмотрим ситуацию, когда мы не можем менять настройки подключения или пользователя. В этом случае нам поможет явное преобразование часового пояса прямо в тексте запроса. В PostgreSQL для этого используется конструкция AT TIME ZONE. Выясним, как это работает на примере.

Если ваше поле order_date имеет тип timestamptz, вы можете привести его к «абстрактному» времени без пояса, которое 1С воспримет «как есть»:

SELECT order_date AT TIME ZONE 'UTC' FROM orders;

В данном случае время будет сконвертировано в UTC, а результат будет иметь тип timestamp without time zone. Для 1С это станет обычной датой без каких-либо скрытых смещений. Это особенно полезно при написании прямых запросов через ExternalDataSources или при создании представлений (View) на стороне PostgreSQL, которые потом подключаются к 1С.

Способ 4. Выбор правильного типа данных в PostgreSQL

Проанализируем разницу в типах данных. Часто проблема решается на этапе проектирования схемы базы данных:

Если специфика вашего учета позволяет, переведите поля в timestamp without time zone. Это избавит вас от необходимости настраивать драйверы и параметры сессий, так как время перестанет быть «чувствительным» к настройкам сервера.

Способ 5. Настройка драйвера через системный DSN

Если вы используете системный DSN (Data Source Name) на сервере, где запущен rphost, настройки можно внести через графический интерфейс администратора источников данных ODBC.

Разберем, куда нужно нажать:

  1. Запустите odbcad32.exe на сервере 1С.
  2. Найдите ваш источник данных и нажмите Configure.
  3. В появившемся окне нажмите кнопку Datasource, затем перейдите на Page 2.
  4. В поле Initial Command впишите: SET TIME ZONE 'UTC';

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

Важные замечания по кэшированию в 1С

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

  1. Перезапустить сеанс 1С:Предприятия.
  2. Если изменения не видны — очистить кэш сервера 1С (папка snccntx в каталоге кластера).
  3. В крайнем случае — обновить описание внешнего источника данных в конфигураторе (команда «Обновить из СУБД»).

Таким образом, мы выяснили, что наиболее надежным и «чистым» решением является либо установка TimeZone для пользователя БД, либо использование ConnSettings в строке подключения. Это позволяет сохранить целостность данных и гарантирует, что 1С получит именно ту дату, которая реально хранится на сервере PostgreSQL.

← На главную