aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/clickhouse-connect/clickhouse_connect/driver/tzutil.py
blob: c27b51dd72cb6b98a0eb2a8d575a297591ea04e1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import os
from datetime import datetime
from typing import Tuple

import pytz

tzlocal = None
try:
    import tzlocal  # Maybe we can use the tzlocal module to get a safe timezone
except ImportError:
    pass

# Set the local timezone for DateTime conversions.  Note in most cases we want to use either UTC or the server
# timezone, but if someone insists on using the local timezone we will try to convert.  The problem is we
# never have anything but an epoch timestamp returned from ClickHouse, so attempts to convert times when the
# local timezone is "DST" aware (like 'CEST' vs 'CET') will be wrong approximately half the time
local_tz: pytz.timezone
local_tz_dst_safe: bool = False


def normalize_timezone(timezone: pytz.timezone) -> Tuple[pytz.timezone, bool]:
    if timezone.tzname(None) in ('UTC', 'GMT', 'Universal', 'GMT-0', 'Zulu', 'Greenwich'):
        return pytz.UTC, True

    if timezone.tzname(None) in pytz.common_timezones:
        return timezone, True

    if tzlocal is not None:  # Maybe we can use the tzlocal module to get a safe timezone
        local_name = tzlocal.get_localzone_name()
        if local_name in pytz.common_timezones:
            return pytz.timezone(local_name), True

    return timezone, False


try:
    local_tz = pytz.timezone(os.environ.get('TZ', ''))
except pytz.UnknownTimeZoneError:
    local_tz = datetime.now().astimezone().tzinfo

local_tz, local_tz_dst_safe = normalize_timezone(local_tz)