@@ -238,21 +238,31 @@ end
238
238
# see https://github.com/invenia/LibPQ.jl/issues/33
239
239
_trunc_seconds (str) = replace (str, r" (\. [\d ]{3})\d +" => s "\g <1>" )
240
240
241
- _DEFAULT_TYPE_MAP[:timestamp ] = DateTime
242
- const TIMESTAMP_FORMAT = dateformat " y-m-d HH:MM:SS.s" # .s is optional here
243
- function pqparse (:: Type{DateTime} , str:: AbstractString )
241
+ # Utility function for handling "infinity" strings for datetime types to reduce duplication
242
+ function _tryparse_datetime_inf (
243
+ typ:: Type{T} , str, f= typ
244
+ ):: Union{T, Nothing} where T <: Dates.AbstractDateTime
244
245
if str == " infinity"
245
246
depwarn_timetype_inf ()
246
- return typemax (DateTime)
247
+ return f ( typemax (DateTime) )
247
248
elseif str == " -infinity"
248
249
depwarn_timetype_inf ()
249
- return typemin (DateTime)
250
+ return f ( typemin (DateTime) )
250
251
end
251
252
252
- # Cut off digits after the third after the decimal point,
253
- # since DateTime in Julia currently handles only milliseconds, see Issue #33
254
- str = replace (str, r" (\. [\d ]{3})\d +" => s "\g <1>" )
255
- return parse (DateTime, str, TIMESTAMP_FORMAT)
253
+ return nothing
254
+ end
255
+
256
+ _DEFAULT_TYPE_MAP[:timestamp ] = DateTime
257
+ const TIMESTAMP_FORMAT = dateformat " y-m-d HH:MM:SS.s" # .s is optional here
258
+ function pqparse (:: Type{DateTime} , str:: AbstractString )
259
+ parsed = _tryparse_datetime_inf (DateTime, str)
260
+ isnothing (parsed) || return parsed
261
+
262
+ parsed = tryparse (DateTime, str, TIMESTAMP_FORMAT)
263
+ isnothing (parsed) || return parsed
264
+
265
+ return parse (DateTime, _trunc_seconds (str), TIMESTAMP_FORMAT)
256
266
end
257
267
258
268
# ISO, YMD
@@ -265,34 +275,29 @@ const TIMESTAMPTZ_FORMATS = (
265
275
)
266
276
267
277
function pqparse (:: Type{ZonedDateTime} , str:: AbstractString )
268
- if str == " infinity"
269
- depwarn_timetype_inf ()
270
- return ZonedDateTime (typemax (DateTime), tz " UTC" )
271
- elseif str == " -infinity"
272
- depwarn_timetype_inf ()
273
- return ZonedDateTime (typemin (DateTime), tz " UTC" )
274
- end
278
+ parsed = _tryparse_datetime_inf (ZonedDateTime, str, Base. Fix2 (ZonedDateTime, tz " UTC" ))
279
+ isnothing (parsed) || return parsed
275
280
276
281
for fmt in TIMESTAMPTZ_FORMATS[1 : (end - 1 )]
277
282
parsed = tryparse (ZonedDateTime, str, fmt)
278
- parsed != = nothing && return parsed
283
+ isnothing ( parsed) || return parsed
279
284
end
280
285
281
286
return parse (ZonedDateTime, _trunc_seconds (str), TIMESTAMPTZ_FORMATS[end ])
282
287
end
283
288
284
289
function pqparse (:: Type{UTCDateTime} , str:: AbstractString )
285
- if str == " infinity"
286
- depwarn_timetype_inf ()
287
- return UTCDateTime (typemax (DateTime))
288
- elseif str == " -infinity"
289
- depwarn_timetype_inf ()
290
- return UTCDateTime (typemin (DateTime))
291
- end
290
+ parsed = _tryparse_datetime_inf (UTCDateTime, str)
291
+ isnothing (parsed) || return parsed
292
292
293
293
# Postgres should always give us strings ending with +00 if our timezone is set to UTC
294
294
# which is the default
295
- return parse (UTCDateTime, _trunc_seconds (replace (str, " +00" => " " )), TIMESTAMP_FORMAT)
295
+ str = replace (str, " +00" => " " )
296
+
297
+ parsed = tryparse (UTCDateTime, str, TIMESTAMP_FORMAT)
298
+ isnothing (parsed) || return parsed
299
+
300
+ return parse (UTCDateTime, _trunc_seconds (str), TIMESTAMP_FORMAT)
296
301
end
297
302
298
303
_DEFAULT_TYPE_MAP[:date ] = Date
0 commit comments