1
- import datetime
1
+ from datetime import (
2
+ date ,
3
+ timedelta ,
4
+ )
2
5
3
6
import numpy as np
4
7
import pytest
5
8
9
+ from pandas ._libs .tslibs .timezones import maybe_get_tz
6
10
import pandas .util ._test_decorators as td
7
11
8
12
import pandas as pd
@@ -36,200 +40,109 @@ def _compare_with_tz(a, b):
36
40
raise AssertionError (f"invalid tz comparison [{ a_e } ] [{ b_e } ]" )
37
41
38
42
39
- def test_append_with_timezones_dateutil (setup_path ):
43
+ # use maybe_get_tz instead of dateutil.tz.gettz to handle the windows
44
+ # filename issues.
45
+ gettz_dateutil = lambda x : maybe_get_tz ("dateutil/" + x )
46
+ gettz_pytz = lambda x : x
40
47
41
- from datetime import timedelta
42
48
43
- # use maybe_get_tz instead of dateutil.tz. gettz to handle the windows
44
- # filename issues.
45
- from pandas . _libs . tslibs . timezones import maybe_get_tz
49
+ @ pytest . mark . parametrize ( " gettz" , [ gettz_dateutil , gettz_pytz ])
50
+ def test_append_with_timezones ( setup_path , gettz ):
51
+ # as columns
46
52
47
- gettz = lambda x : maybe_get_tz ("dateutil/" + x )
53
+ # Single-tzinfo, no DST transition
54
+ df_est = DataFrame (
55
+ {
56
+ "A" : [
57
+ Timestamp ("20130102 2:00:00" , tz = gettz ("US/Eastern" ))
58
+ + timedelta (hours = 1 ) * i
59
+ for i in range (5 )
60
+ ]
61
+ }
62
+ )
63
+
64
+ # frame with all columns having same tzinfo, but different sides
65
+ # of DST transition
66
+ df_crosses_dst = DataFrame (
67
+ {
68
+ "A" : Timestamp ("20130102" , tz = gettz ("US/Eastern" )),
69
+ "B" : Timestamp ("20130603" , tz = gettz ("US/Eastern" )),
70
+ },
71
+ index = range (5 ),
72
+ )
73
+
74
+ df_mixed_tz = DataFrame (
75
+ {
76
+ "A" : Timestamp ("20130102" , tz = gettz ("US/Eastern" )),
77
+ "B" : Timestamp ("20130102" , tz = gettz ("EET" )),
78
+ },
79
+ index = range (5 ),
80
+ )
81
+
82
+ df_different_tz = DataFrame (
83
+ {
84
+ "A" : Timestamp ("20130102" , tz = gettz ("US/Eastern" )),
85
+ "B" : Timestamp ("20130102" , tz = gettz ("CET" )),
86
+ },
87
+ index = range (5 ),
88
+ )
48
89
49
- # as columns
50
90
with ensure_clean_store (setup_path ) as store :
51
91
52
92
_maybe_remove (store , "df_tz" )
53
- df = DataFrame (
54
- {
55
- "A" : [
56
- Timestamp ("20130102 2:00:00" , tz = gettz ("US/Eastern" ))
57
- + timedelta (hours = 1 ) * i
58
- for i in range (5 )
59
- ]
60
- }
61
- )
62
-
63
- store .append ("df_tz" , df , data_columns = ["A" ])
93
+ store .append ("df_tz" , df_est , data_columns = ["A" ])
64
94
result = store ["df_tz" ]
65
- _compare_with_tz (result , df )
66
- tm .assert_frame_equal (result , df )
95
+ _compare_with_tz (result , df_est )
96
+ tm .assert_frame_equal (result , df_est )
67
97
68
98
# select with tz aware
69
- expected = df [ df .A >= df .A [3 ]]
70
- result = store .select ("df_tz" , where = "A>=df .A[3]" )
99
+ expected = df_est [ df_est .A >= df_est .A [3 ]]
100
+ result = store .select ("df_tz" , where = "A>=df_est .A[3]" )
71
101
_compare_with_tz (result , expected )
72
102
73
103
# ensure we include dates in DST and STD time here.
74
104
_maybe_remove (store , "df_tz" )
75
- df = DataFrame (
76
- {
77
- "A" : Timestamp ("20130102" , tz = gettz ("US/Eastern" )),
78
- "B" : Timestamp ("20130603" , tz = gettz ("US/Eastern" )),
79
- },
80
- index = range (5 ),
81
- )
82
- store .append ("df_tz" , df )
105
+ store .append ("df_tz" , df_crosses_dst )
83
106
result = store ["df_tz" ]
84
- _compare_with_tz (result , df )
85
- tm .assert_frame_equal (result , df )
86
-
87
- df = DataFrame (
88
- {
89
- "A" : Timestamp ("20130102" , tz = gettz ("US/Eastern" )),
90
- "B" : Timestamp ("20130102" , tz = gettz ("EET" )),
91
- },
92
- index = range (5 ),
93
- )
107
+ _compare_with_tz (result , df_crosses_dst )
108
+ tm .assert_frame_equal (result , df_crosses_dst )
94
109
95
110
msg = (
96
111
r"invalid info for \[values_block_1\] for \[tz\], "
97
- r"existing_value \[dateutil/.*US/Eastern\] "
98
- r"conflicts with new value \[dateutil/.*EET\]"
112
+ r"existing_value \[( dateutil/.*)? US/Eastern\] "
113
+ r"conflicts with new value \[( dateutil/.*)? EET\]"
99
114
)
100
115
with pytest .raises (ValueError , match = msg ):
101
- store .append ("df_tz" , df )
116
+ store .append ("df_tz" , df_mixed_tz )
102
117
103
118
# this is ok
104
119
_maybe_remove (store , "df_tz" )
105
- store .append ("df_tz" , df , data_columns = ["A" , "B" ])
120
+ store .append ("df_tz" , df_mixed_tz , data_columns = ["A" , "B" ])
106
121
result = store ["df_tz" ]
107
- _compare_with_tz (result , df )
108
- tm .assert_frame_equal (result , df )
122
+ _compare_with_tz (result , df_mixed_tz )
123
+ tm .assert_frame_equal (result , df_mixed_tz )
109
124
110
125
# can't append with diff timezone
111
- df = DataFrame (
112
- {
113
- "A" : Timestamp ("20130102" , tz = gettz ("US/Eastern" )),
114
- "B" : Timestamp ("20130102" , tz = gettz ("CET" )),
115
- },
116
- index = range (5 ),
117
- )
118
-
119
126
msg = (
120
127
r"invalid info for \[B\] for \[tz\], "
121
- r"existing_value \[dateutil/.*EET\] "
122
- r"conflicts with new value \[dateutil/.*CET\]"
128
+ r"existing_value \[( dateutil/.*)? EET\] "
129
+ r"conflicts with new value \[( dateutil/.*)? CET\]"
123
130
)
124
131
with pytest .raises (ValueError , match = msg ):
125
- store .append ("df_tz" , df )
132
+ store .append ("df_tz" , df_different_tz )
126
133
127
- # as index
128
- with ensure_clean_store (setup_path ) as store :
129
134
130
- dti = date_range ("2000-1-1" , periods = 3 , freq = "H" , tz = gettz ("US/Eastern" ))
131
- dti = dti ._with_freq (None ) # freq doesnt round-trip
135
+ @pytest .mark .parametrize ("gettz" , [gettz_dateutil , gettz_pytz ])
136
+ def test_append_with_timezones_as_index (setup_path , gettz ):
137
+ # GH#4098 example
132
138
133
- # GH 4098 example
134
- df = DataFrame ({"A" : Series (range (3 ), index = dti )})
135
-
136
- _maybe_remove (store , "df" )
137
- store .put ("df" , df )
138
- result = store .select ("df" )
139
- tm .assert_frame_equal (result , df )
140
-
141
- _maybe_remove (store , "df" )
142
- store .append ("df" , df )
143
- result = store .select ("df" )
144
- tm .assert_frame_equal (result , df )
139
+ dti = date_range ("2000-1-1" , periods = 3 , freq = "H" , tz = gettz ("US/Eastern" ))
140
+ dti = dti ._with_freq (None ) # freq doesnt round-trip
145
141
142
+ df = DataFrame ({"A" : Series (range (3 ), index = dti )})
146
143
147
- def test_append_with_timezones_pytz (setup_path ):
148
-
149
- from datetime import timedelta
150
-
151
- # as columns
152
144
with ensure_clean_store (setup_path ) as store :
153
145
154
- _maybe_remove (store , "df_tz" )
155
- df = DataFrame (
156
- {
157
- "A" : [
158
- Timestamp ("20130102 2:00:00" , tz = "US/Eastern" )
159
- + timedelta (hours = 1 ) * i
160
- for i in range (5 )
161
- ]
162
- }
163
- )
164
- store .append ("df_tz" , df , data_columns = ["A" ])
165
- result = store ["df_tz" ]
166
- _compare_with_tz (result , df )
167
- tm .assert_frame_equal (result , df )
168
-
169
- # select with tz aware
170
- _compare_with_tz (store .select ("df_tz" , where = "A>=df.A[3]" ), df [df .A >= df .A [3 ]])
171
-
172
- _maybe_remove (store , "df_tz" )
173
- # ensure we include dates in DST and STD time here.
174
- df = DataFrame (
175
- {
176
- "A" : Timestamp ("20130102" , tz = "US/Eastern" ),
177
- "B" : Timestamp ("20130603" , tz = "US/Eastern" ),
178
- },
179
- index = range (5 ),
180
- )
181
- store .append ("df_tz" , df )
182
- result = store ["df_tz" ]
183
- _compare_with_tz (result , df )
184
- tm .assert_frame_equal (result , df )
185
-
186
- df = DataFrame (
187
- {
188
- "A" : Timestamp ("20130102" , tz = "US/Eastern" ),
189
- "B" : Timestamp ("20130102" , tz = "EET" ),
190
- },
191
- index = range (5 ),
192
- )
193
-
194
- msg = (
195
- r"invalid info for \[values_block_1\] for \[tz\], "
196
- r"existing_value \[US/Eastern\] conflicts with new value \[EET\]"
197
- )
198
- with pytest .raises (ValueError , match = msg ):
199
- store .append ("df_tz" , df )
200
-
201
- # this is ok
202
- _maybe_remove (store , "df_tz" )
203
- store .append ("df_tz" , df , data_columns = ["A" , "B" ])
204
- result = store ["df_tz" ]
205
- _compare_with_tz (result , df )
206
- tm .assert_frame_equal (result , df )
207
-
208
- # can't append with diff timezone
209
- df = DataFrame (
210
- {
211
- "A" : Timestamp ("20130102" , tz = "US/Eastern" ),
212
- "B" : Timestamp ("20130102" , tz = "CET" ),
213
- },
214
- index = range (5 ),
215
- )
216
-
217
- msg = (
218
- r"invalid info for \[B\] for \[tz\], "
219
- r"existing_value \[EET\] conflicts with new value \[CET\]"
220
- )
221
- with pytest .raises (ValueError , match = msg ):
222
- store .append ("df_tz" , df )
223
-
224
- # as index
225
- with ensure_clean_store (setup_path ) as store :
226
-
227
- dti = date_range ("2000-1-1" , periods = 3 , freq = "H" , tz = "US/Eastern" )
228
- dti = dti ._with_freq (None ) # freq doesnt round-trip
229
-
230
- # GH 4098 example
231
- df = DataFrame ({"A" : Series (range (3 ), index = dti )})
232
-
233
146
_maybe_remove (store , "df" )
234
147
store .put ("df" , df )
235
148
result = store .select ("df" )
@@ -327,17 +240,19 @@ def test_timezones_fixed_format_frame_non_empty(setup_path):
327
240
tm .assert_frame_equal (result , df )
328
241
329
242
330
- def test_timezones_fixed_format_frame_empty (setup_path , tz_aware_fixture ):
243
+ def test_timezones_fixed_format_empty (setup_path , tz_aware_fixture , frame_or_series ):
331
244
# GH 20594
332
245
333
246
dtype = pd .DatetimeTZDtype (tz = tz_aware_fixture )
334
247
248
+ obj = Series (dtype = dtype , name = "A" )
249
+ if frame_or_series is DataFrame :
250
+ obj = obj .to_frame ()
251
+
335
252
with ensure_clean_store (setup_path ) as store :
336
- s = Series (dtype = dtype )
337
- df = DataFrame ({"A" : s })
338
- store ["df" ] = df
339
- result = store ["df" ]
340
- tm .assert_frame_equal (result , df )
253
+ store ["obj" ] = obj
254
+ result = store ["obj" ]
255
+ tm .assert_equal (result , obj )
341
256
342
257
343
258
def test_timezones_fixed_format_series_nonempty (setup_path , tz_aware_fixture ):
@@ -352,18 +267,6 @@ def test_timezones_fixed_format_series_nonempty(setup_path, tz_aware_fixture):
352
267
tm .assert_series_equal (result , s )
353
268
354
269
355
- def test_timezones_fixed_format_series_empty (setup_path , tz_aware_fixture ):
356
- # GH 20594
357
-
358
- dtype = pd .DatetimeTZDtype (tz = tz_aware_fixture )
359
-
360
- with ensure_clean_store (setup_path ) as store :
361
- s = Series (dtype = dtype )
362
- store ["s" ] = s
363
- result = store ["s" ]
364
- tm .assert_series_equal (result , s )
365
-
366
-
367
270
def test_fixed_offset_tz (setup_path ):
368
271
rng = date_range ("1/1/2000 00:00:00-07:00" , "1/30/2000 00:00:00-07:00" )
369
272
frame = DataFrame (np .random .randn (len (rng ), 4 ), index = rng )
@@ -384,7 +287,7 @@ def test_store_timezone(setup_path):
384
287
# original method
385
288
with ensure_clean_store (setup_path ) as store :
386
289
387
- today = datetime . date (2013 , 9 , 10 )
290
+ today = date (2013 , 9 , 10 )
388
291
df = DataFrame ([1 , 2 , 3 ], index = [today , today , today ])
389
292
store ["obj1" ] = df
390
293
result = store ["obj1" ]
@@ -394,7 +297,7 @@ def test_store_timezone(setup_path):
394
297
with ensure_clean_store (setup_path ) as store :
395
298
396
299
with tm .set_timezone ("EST5EDT" ):
397
- today = datetime . date (2013 , 9 , 10 )
300
+ today = date (2013 , 9 , 10 )
398
301
df = DataFrame ([1 , 2 , 3 ], index = [today , today , today ])
399
302
store ["obj1" ] = df
400
303
0 commit comments