Часовые пояса

Часовые пояса

Работа с часовыми поясами в Fincomtech Analytics

В архитектуре Fincomtech Analytics выделяется четыре уровня, на которых происходит обработка временных меток (Time Zones):

  1. Источник данных: Часовой пояс, в котором сохранены исходные данные.
  2. База данных (СУБД): Системное время движка базы данных.
  3. Бэкенд Fincomtech Analytics: Часовой пояс серверной части платформы.
  4. Клиент: Локальное время в браузере пользователя Fincomtech Analytics.

Если в полях типа DATETIME, TIME или TIMESTAMP часовой пояс не указан явно, система по умолчанию использует настройки соответствующего компонента.

Рекомендации по настройке (Best Practices)

Поскольку Fincomtech Analytics не может управлять форматом исходных данных (1) и настройками клиентского устройства (4), для обеспечения целостности данных критически важно синхронизировать уровни (2) и (3).

Настоятельно рекомендуется настроить базу данных и бэкенд платформы на использование единого стандарта — UTC. Это предотвратит некорректное преобразование полей без явной метки времени. Внутренняя логика Fincomtech Analytics неявно подразумевает работу с UTC, поэтому использование других часовых поясов на сервере (пункт 3) может привести к ошибкам в отчетах.

Технические особенности сериализации

Для обеспечения консистентности (независимо от локального времени пользователя) бэкенд Fincomtech Analytics стремится передавать на клиент временные метки с явным указанием часового пояса или в формате Unix time (всегда UTC).

Однако существует сложность, связанная с разнообразием поддерживаемых СУБД и различиями в их реализации драйверов Python Database API (DB-API). Fincomtech Analytics использует библиотеку Pandas для преобразования SQL-ответов в DataFrame перед сериализацией в JSON.

Проблема заключается в том, что Pandas часто игнорирует атрибут type_code из DB-API, полагаясь на базовые типы Python. В результате лишь часть драйверов СУБД позволяет корректно сериализовать время в JSON без привязки к локальному времени сервера, гарантируя правильное отображение у клиента.

Пример расхождений (MySQL vs Presto)

Ниже приведено сравнение обработки временных меток разными драйверами через Pandas:

pythonimport pandas as pd
from sqlalchemy import create_engine

# Пример для MySQL
pd.read_sql_query(
    sql="SELECT TIMESTAMP('2022-01-01 00:00:00') AS ts",
    con=create_engine("mysql://root@localhost:3360"),
).to_json()

# Пример для Presto
pd.read_sql_query(
    sql="SELECT TIMESTAMP '2022-01-01 00:00:00' AS ts",
    con=create_engine("presto://localhost:8080"),
).to_json()

Результаты вывода:

  • MySQL: {"ts":{"0":1640995200000}} — формат эпохи, жестко привязан к UTC.
  • Presto: {"ts":{"0":"2022-01-01 00:00:00.000"}} — строковый формат без указания часового пояса.

Это приводит к разной интерпретации на стороне JavaScript (клиента Fincomtech Analytics):

javascript// Интерпретация UTC (корректно)
new Date(1640995200000)
> Sat Jan 01 2022 13:00:00 GMT+1300 (New Zealand Daylight Time)

// Интерпретация локального времени (зависит от браузера)
new Date("2022-01-01 00:00:00.000")
> Sat Jan 01 2022 00:00:00 GMT+1300 (New Zealand Daylight Time)