@@ -238,21 +238,31 @@ end
238238# see https://github.com/invenia/LibPQ.jl/issues/33
239239_trunc_seconds (str) = replace (str, r" (\. [\d ]{3})\d +" => s "\g <1>" )
240240
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
244245 if str == " infinity"
245246 depwarn_timetype_inf ()
246- return typemax (DateTime)
247+ return f ( typemax (DateTime) )
247248 elseif str == " -infinity"
248249 depwarn_timetype_inf ()
249- return typemin (DateTime)
250+ return f ( typemin (DateTime) )
250251 end
251252
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)
256266end
257267
258268# ISO, YMD
@@ -265,34 +275,29 @@ const TIMESTAMPTZ_FORMATS = (
265275)
266276
267277function 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
275280
276281 for fmt in TIMESTAMPTZ_FORMATS[1 : (end - 1 )]
277282 parsed = tryparse (ZonedDateTime, str, fmt)
278- parsed != = nothing && return parsed
283+ isnothing ( parsed) || return parsed
279284 end
280285
281286 return parse (ZonedDateTime, _trunc_seconds (str), TIMESTAMPTZ_FORMATS[end ])
282287end
283288
284289function 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
292292
293293 # Postgres should always give us strings ending with +00 if our timezone is set to UTC
294294 # 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)
296301end
297302
298303_DEFAULT_TYPE_MAP[:date ] = Date
0 commit comments