@@ -51,6 +51,63 @@ def test_now():
51
51
@pytest .mark .parametrize (
52
52
"input_value,expected_output,error_type,error_match" ,
53
53
[
54
+ # Valid formats - must have T delimiter and timezone
55
+ ("2023-03-14T15:09:26+00:00" , "2023-03-14T15:09:26+00:00" , None , None ), # Basic UTC format
56
+ (
57
+ "2023-03-14T15:09:26.123+00:00" ,
58
+ "2023-03-14T15:09:26.123000+00:00" ,
59
+ None ,
60
+ None ,
61
+ ), # With milliseconds
62
+ (
63
+ "2023-03-14T15:09:26.123456+00:00" ,
64
+ "2023-03-14T15:09:26.123456+00:00" ,
65
+ None ,
66
+ None ,
67
+ ), # With microseconds
68
+ (
69
+ "2023-03-14T15:09:26-04:00" ,
70
+ "2023-03-14T15:09:26-04:00" ,
71
+ None ,
72
+ None ,
73
+ ), # With timezone offset
74
+ ("2023-03-14T15:09:26Z" , "2023-03-14T15:09:26+00:00" , None , None ), # With Z timezone
75
+ (
76
+ "2023-03-14T00:00:00+00:00" ,
77
+ "2023-03-14T00:00:00+00:00" ,
78
+ None ,
79
+ None ,
80
+ ), # Full datetime with zero time
81
+ (
82
+ "2023-03-14T15:09:26GMT" ,
83
+ "2023-03-14T15:09:26+00:00" ,
84
+ None ,
85
+ None ,
86
+ ), # Non-standard timezone name ok
87
+ (
88
+ "2023-03-14T15:09:26" ,
89
+ "2023-03-14T15:09:26+00:00" ,
90
+ None ,
91
+ None ,
92
+ ), # Missing timezone, assume UTC
93
+ (
94
+ "2023-03-14 15:09:26" ,
95
+ "2023-03-14T15:09:26+00:00" ,
96
+ None ,
97
+ None ,
98
+ ), # Missing T delimiter ok, assume UTC
99
+ (
100
+ "2023-03-14" ,
101
+ "2023-03-14T00:00:00+00:00" ,
102
+ None ,
103
+ None ,
104
+ ), # Date only, missing time and timezone
105
+ (
106
+ "2023/03/14T15:09:26Z" ,
107
+ "2023-03-14T15:09:26+00:00" ,
108
+ None ,
109
+ None ,
110
+ ), # Wrong date separator, ok
54
111
# Valid formats
55
112
("2023-03-14T15:09:26Z" , "2023-03-14T15:09:26+00:00" , None , None ),
56
113
("2023-03-14T15:09:26-04:00" , "2023-03-14T15:09:26-04:00" , None , None ),
@@ -71,20 +128,10 @@ def test_now():
71
128
("2023-12-32" , None , ValueError , "Invalid date format: 2023-12-32" ),
72
129
("2023-00-14" , None , ValueError , "Invalid date format: 2023-00-14" ),
73
130
("2023-12-00" , None , ValueError , "Invalid date format: 2023-12-00" ),
74
- # Invalid separators and formats
75
- ("2023/12/14" , None , ValueError , "Could not parse datetime string: 2023/12/14" ),
76
- (
77
- "2023-03-14 15:09:26Z" ,
78
- None ,
79
- ValueError ,
80
- "Could not parse datetime string: 2023-03-14 15:09:26Z" ,
81
- ),
82
- (
83
- "2023-03-14T15:09:26GMT" ,
84
- None ,
85
- ValueError ,
86
- "Could not parse datetime string: 2023-03-14T15:09:26GMT" ,
87
- ),
131
+ # Non-standard separators and formats, ok
132
+ ("2023/12/14" , "2023-12-14T00:00:00+00:00" , None , None ),
133
+ ("2023-03-14 15:09:26Z" , "2023-03-14T15:09:26+00:00" , None , None ),
134
+ ("2023-03-14T15:09:26GMT" , "2023-03-14T15:09:26+00:00" , None , None ),
88
135
# Invalid time components
89
136
(
90
137
"2023-03-14T25:09:26Z" ,
@@ -105,16 +152,24 @@ def test_now():
105
152
"Could not parse datetime string: 2023-03-14T15:09:99Z" ,
106
153
),
107
154
],
155
+ # ("invalid datetime", None), # Completely invalid
156
+ # ("15:09:26Z", None), # Missing date component
157
+ # ("2023-03-14T25:09:26Z", None), # Invalid hour
158
+ # ("2023-03-14T15:99:26Z", None), # Invalid minute
159
+ # ("2023-03-14T15:09:99Z", None), # Invalid second
160
+ # ("2023-02-30T00:00:00Z", None), # Impossible date
108
161
)
109
162
def test_parse (input_value , expected_output , error_type , error_match ):
110
163
"""Test parsing various datetime string formats."""
111
164
if error_type :
112
165
with pytest .raises (error_type , match = error_match ):
113
166
ab_datetime_parse (input_value )
167
+ assert not ab_datetime_try_parse (input_value )
114
168
else :
115
169
dt = ab_datetime_parse (input_value )
116
170
assert isinstance (dt , AirbyteDateTime )
117
171
assert str (dt ) == expected_output
172
+ assert ab_datetime_try_parse (input_value ) and ab_datetime_try_parse (input_value ) == dt
118
173
119
174
120
175
@pytest .mark .parametrize (
@@ -194,42 +249,6 @@ def test_operator_overloading():
194
249
_ = "invalid" - dt
195
250
196
251
197
- @pytest .mark .parametrize (
198
- "input_value,expected_output" ,
199
- [
200
- # Valid formats - must have T delimiter and timezone
201
- ("2023-03-14T15:09:26+00:00" , "2023-03-14T15:09:26+00:00" ), # Basic UTC format
202
- ("2023-03-14T15:09:26.123+00:00" , "2023-03-14T15:09:26.123000+00:00" ), # With milliseconds
203
- (
204
- "2023-03-14T15:09:26.123456+00:00" ,
205
- "2023-03-14T15:09:26.123456+00:00" ,
206
- ), # With microseconds
207
- ("2023-03-14T15:09:26-04:00" , "2023-03-14T15:09:26-04:00" ), # With timezone offset
208
- ("2023-03-14T15:09:26Z" , "2023-03-14T15:09:26+00:00" ), # With Z timezone
209
- ("2023-03-14T00:00:00+00:00" , "2023-03-14T00:00:00+00:00" ), # Full datetime with zero time
210
- # Invalid formats - reject anything without proper ISO8601/RFC3339 format
211
- ("invalid datetime" , None ), # Completely invalid
212
- ("2023-03-14 15:09:26" , None ), # Missing T delimiter
213
- ("2023-03-14" , None ), # Date only, missing time and timezone
214
- ("15:09:26Z" , None ), # Missing date component
215
- ("2023-03-14T15:09:26" , None ), # Missing timezone
216
- ("2023-03-14T15:09:26GMT" , None ), # Invalid timezone format
217
- ("2023/03/14T15:09:26Z" , None ), # Wrong date separator
218
- ("2023-03-14T25:09:26Z" , None ), # Invalid hour
219
- ("2023-03-14T15:99:26Z" , None ), # Invalid minute
220
- ("2023-03-14T15:09:99Z" , None ), # Invalid second
221
- ],
222
- )
223
- def test_ab_datetime_try_parse (input_value , expected_output ):
224
- """Test datetime string format validation."""
225
- result = ab_datetime_try_parse (input_value )
226
- if expected_output is None :
227
- assert result is None
228
- else :
229
- assert isinstance (result , AirbyteDateTime )
230
- assert str (result ) == expected_output
231
-
232
-
233
252
def test_epoch_millis ():
234
253
"""Test Unix epoch millisecond timestamp conversion methods."""
235
254
# Test to_epoch_millis()
0 commit comments