-
Notifications
You must be signed in to change notification settings - Fork 71
/
Copy pathtest_timezones.py
166 lines (140 loc) · 7.21 KB
/
test_timezones.py
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import os
import time
from datetime import datetime
import pytz
from clickhouse_connect.driver import Client, tzutil
# We have to localize a datetime from a timezone to get a current, sensible timezone object for testing. See
# https://stackoverflow.com/questions/35462876/python-pytz-timezone-function-returns-a-timezone-that-is-off-by-9-minutes
chicago_tz = pytz.timezone('America/Chicago').localize(datetime(2020, 8, 8, 10, 5, 5)).tzinfo
def test_basic_timezones(test_client: Client):
row = test_client.query("SELECT toDateTime('2022-10-25 10:55:22', 'America/Chicago') as chicago," +
"toDateTime('2023-07-05 15:10:40') as utc",
query_tz='America/Chicago').first_row
assert row[0].tzinfo == chicago_tz
assert row[0].hour == 10
assert row[0].day == 25
assert row[1].tzinfo == chicago_tz
assert row[1].hour == 10
assert row[1].day == 5
if test_client.min_version('20'):
row = test_client.query("SELECT toDateTime64('2022-10-25 10:55:22.789123', 6, 'America/Chicago')",
query_tz='America/Chicago').first_row
assert row[0].tzinfo == chicago_tz
assert row[0].hour == 10
assert row[0].day == 25
assert row[0].microsecond == 789123
def test_server_timezone(test_client: Client):
# This test is really for manual testing since changing the timezone on the test ClickHouse server
# still requires a restart. Other tests will depend on https://github.com/ClickHouse/ClickHouse/pull/44149
test_client.apply_server_timezone = True
test_datetime = datetime(2023, 3, 18, 16, 4, 25)
try:
date = test_client.query('SELECT toDateTime(%s) as st', parameters=[test_datetime]).first_row[0]
if test_client.server_tz == pytz.UTC:
assert date.tzinfo is None
assert date == datetime(2023, 3, 18, 16, 4, 25, tzinfo=None)
assert date.timestamp() == 1679155465
else:
den_tz = pytz.timezone('America/Denver').localize(datetime(2020, 8, 8)).tzinfo
assert date == datetime(2023, 3, 18, 16, 4, 25, tzinfo=den_tz)
assert date.tzinfo == den_tz
assert date.timestamp() == 1679177065
finally:
test_client.apply_server_timezone = False
def test_column_timezones(test_client: Client):
date_tz64 = "toDateTime64('2023-01-02 15:44:22.7832', 6, 'Asia/Shanghai')"
if not test_client.min_version('20'):
date_tz64 = "toDateTime('2023-01-02 15:44:22', 'Asia/Shanghai')"
column_tzs = {'chicago': 'America/Chicago', 'china': 'Asia/Shanghai'}
row = test_client.query("SELECT toDateTime('2022-10-25 10:55:22', 'America/Chicago') as chicago," +
f'{date_tz64} as china,' +
"toDateTime('2023-07-05 15:10:40') as utc",
column_tzs=column_tzs).first_row
china_tz = pytz.timezone('Asia/Shanghai').localize(datetime(2024, 12, 4, 10, 5, 5)).tzinfo
assert row[0].tzinfo == chicago_tz
assert row[1].tzinfo == china_tz
assert row[2].tzinfo is None
if test_client.min_version('20'):
row = test_client.query("SELECT toDateTime('2022-10-25 10:55:22', 'America/Chicago') as chicago," +
"toDateTime64('2023-01-02 15:44:22.7832', 6, 'Asia/Shanghai') as china").first_row
if test_client.protocol_version:
assert row[0].tzinfo == chicago_tz
else:
assert row[0].tzinfo is None
assert row[1].tzinfo == china_tz # DateTime64 columns work correctly
def test_local_timezones(test_client: Client):
denver_tz = pytz.timezone('America/Denver')
tzutil.local_tz = denver_tz
test_client.apply_server_timezone = False
try:
row = test_client.query("SELECT toDateTime('2022-10-25 10:55:22'," +
"'America/Chicago') as chicago," +
"toDateTime('2023-07-05 15:10:40') as raw_utc_dst," +
"toDateTime('2023-07-05 12:44:22', 'UTC') as forced_utc," +
"toDateTime('2023-12-31 17:00:55') as raw_utc_std").first_row
if test_client.protocol_version:
assert row[0].tzinfo.tzname(None) == chicago_tz.tzname(None)
else:
assert row[0].tzinfo.tzname(None) == denver_tz.tzname(None)
assert row[1].tzinfo.tzname(None) == denver_tz.tzname(None)
assert row[2].tzinfo is None
assert row[3].tzinfo.tzname(None) == denver_tz.tzname(None)
finally:
tzutil.local_tz = pytz.UTC
test_client.apply_server_timezone = True
def test_naive_timezones(test_client: Client):
row = test_client.query("SELECT toDateTime('2022-10-25 10:55:22', 'America/Chicago') as chicago," +
"toDateTime('2023-07-05 15:10:40') as utc").first_row
if test_client.protocol_version:
assert row[0].tzinfo == chicago_tz
else:
assert row[0].tzinfo is None
assert row[1].tzinfo is None
def test_timezone_binding_client(test_client: Client):
os.environ['TZ'] = 'America/Denver'
time.tzset()
denver_tz = pytz.timezone('America/Denver')
tzutil.local_tz = denver_tz
test_client.apply_server_timezone = False
denver_time = datetime(2023, 3, 18, 16, 4, 25, tzinfo=denver_tz)
try:
server_time = test_client.query(
'SELECT toDateTime(%(dt)s) as dt', parameters={'dt': denver_time}).first_row[0]
assert server_time == denver_time
finally:
os.environ['TZ'] = 'UTC'
tzutil.local_tz = pytz.UTC
time.tzset()
test_client.apply_server_timezone = True
naive_time = datetime(2023, 3, 18, 16, 4, 25)
server_time = test_client.query(
'SELECT toDateTime(%(dt)s) as dt', parameters={'dt': naive_time}).first_row[0]
assert server_time.astimezone(pytz.UTC) == naive_time.astimezone(pytz.UTC)
utc_time = datetime(2023, 3, 18, 16, 4, 25, tzinfo=pytz.UTC)
server_time = test_client.query(
'SELECT toDateTime(%(dt)s) as dt', parameters={'dt': utc_time}).first_row[0]
assert server_time.astimezone(pytz.UTC) == utc_time
def test_timezone_binding_server(test_client: Client):
os.environ['TZ'] = 'America/Denver'
time.tzset()
denver_tz = pytz.timezone('America/Denver')
tzutil.local_tz = denver_tz
test_client.apply_server_timezone = False
denver_time = datetime(2022, 3, 18, 16, 4, 25, tzinfo=denver_tz)
try:
server_time = test_client.query(
'SELECT toDateTime({dt:DateTime}) as dt', parameters={'dt': denver_time}).first_row[0]
assert server_time == denver_time
finally:
os.environ['TZ'] = 'UTC'
time.tzset()
tzutil.local_tz = pytz.UTC
test_client.apply_server_timezone = True
naive_time = datetime(2022, 3, 18, 16, 4, 25)
server_time = test_client.query(
'SELECT toDateTime({dt:DateTime}) as dt', parameters={'dt': naive_time}).first_row[0]
assert naive_time.astimezone(pytz.UTC) == server_time.astimezone(pytz.UTC)
utc_time = datetime(2020, 3, 18, 16, 4, 25, tzinfo=pytz.UTC)
server_time = test_client.query(
'SELECT toDateTime({dt:DateTime}) as dt', parameters={'dt': utc_time}).first_row[0]
assert server_time.astimezone(pytz.UTC) == utc_time