Skip to content

Commit 6a5b9f8

Browse files
committed
Add some simplifications to the UTCDateTime parsing code.
1 parent 2505ade commit 6a5b9f8

File tree

1 file changed

+13
-38
lines changed

1 file changed

+13
-38
lines changed

src/parsing.jl

Lines changed: 13 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -257,31 +257,12 @@ end
257257

258258
# ISO, YMD
259259
_DEFAULT_TYPE_MAP[:timestamptz] = ZonedDateTime
260-
const TIMESTAMPTZ_ZDT_FORMATS = (
260+
const TIMESTAMPTZ_FORMATS = (
261261
dateformat"y-m-d HH:MM:SSz",
262262
dateformat"y-m-d HH:MM:SS.sz",
263263
dateformat"y-m-d HH:MM:SS.ssz",
264264
dateformat"y-m-d HH:MM:SS.sssz",
265265
)
266-
const TIMESTAMPTZ_UTC_FORMATS = (
267-
dateformat"y-m-d HH:MM:SS",
268-
dateformat"y-m-d HH:MM:SS.s",
269-
dateformat"y-m-d HH:MM:SS.ss",
270-
dateformat"y-m-d HH:MM:SS.sss",
271-
)
272-
273-
timestamptz_formats(::Type{ZonedDateTime}) = TIMESTAMPTZ_ZDT_FORMATS
274-
timestamptz_formats(::Type{UTCDateTime}) = TIMESTAMPTZ_UTC_FORMATS
275-
276-
function _pqparse(::Type{T}, str::AbstractString) where T<:Union{UTCDateTime, ZonedDateTime}
277-
formats = timestamptz_formats(T)
278-
for fmt in formats[1:(end - 1)]
279-
parsed = tryparse(T, str, fmt)
280-
parsed !== nothing && return parsed
281-
end
282-
283-
return parse(T, _trunc_seconds(str), formats[end])
284-
end
285266

286267
function pqparse(::Type{ZonedDateTime}, str::AbstractString)
287268
if str == "infinity"
@@ -292,7 +273,12 @@ function pqparse(::Type{ZonedDateTime}, str::AbstractString)
292273
return ZonedDateTime(typemin(DateTime), tz"UTC")
293274
end
294275

295-
return _pqparse(ZonedDateTime, str)
276+
for fmt in TIMESTAMPTZ_FORMATS[1:(end - 1)]
277+
parsed = tryparse(ZonedDateTime, str, fmt)
278+
parsed !== nothing && return parsed
279+
end
280+
281+
return parse(ZonedDateTime, _trunc_seconds(str), TIMESTAMPTZ_FORMATS[end])
296282
end
297283

298284
function pqparse(::Type{UTCDateTime}, str::AbstractString)
@@ -304,11 +290,9 @@ function pqparse(::Type{UTCDateTime}, str::AbstractString)
304290
return UTCDateTime(typemin(DateTime))
305291
end
306292

307-
# Postgres should give us strings ending with +00, +00:00, -00:00
308-
# We use the regex below to strip these character off before parsing, iff,
309-
# the values after the `-`/`+` are `0` or `:`. This means parsing will fail if
310-
# we're asked to parse a non-UTC string like +04:00.
311-
return _pqparse(UTCDateTime, replace(str, r"[-|\+][0|:]*$" => ""))
293+
# Postgres should always give us strings ending with +00 if our timezone is set to UTC
294+
# which is the default
295+
return parse(UTCDateTime, _trunc_seconds(replace(str, "+00" => "")), TIMESTAMP_FORMAT)
312296
end
313297

314298
_DEFAULT_TYPE_MAP[:date] = Date
@@ -363,7 +347,7 @@ function Base.parse(::Type{ZonedDateTime}, pqv::PQValue{PQ_SYSTEM_TYPES[:int8]})
363347
end
364348

365349
function Base.parse(::Type{UTCDateTime}, pqv::PQValue{PQ_SYSTEM_TYPES[:int8]})
366-
return UTCDateTime(unix2datetime(parse(Int64, pqv)))
350+
return UTCDateTime(parse(DateTime, pqv))
367351
end
368352

369353
# All postgresql timestamptz are stored in UTC time with the epoch of 2000-01-01.
@@ -387,16 +371,7 @@ function pqparse(::Type{ZonedDateTime}, ptr::Ptr{UInt8})
387371
end
388372

389373
function pqparse(::Type{UTCDateTime}, ptr::Ptr{UInt8})
390-
value = ntoh(unsafe_load(Ptr{Int64}(ptr)))
391-
if value == typemax(Int64)
392-
depwarn_timetype_inf()
393-
return UTCDateTime(typemax(DateTime))
394-
elseif value == typemin(Int64)
395-
depwarn_timetype_inf()
396-
return UTCDateTime(typemin(DateTime))
397-
end
398-
dt = POSTGRES_EPOCH_DATETIME + Microsecond(value)
399-
return UTCDateTime(dt)
374+
return UTCDateTime(pqparse(DateTime, ptr))
400375
end
401376

402377
function pqparse(::Type{DateTime}, ptr::Ptr{UInt8})
@@ -408,7 +383,7 @@ function pqparse(::Type{DateTime}, ptr::Ptr{UInt8})
408383
depwarn_timetype_inf()
409384
return typemin(DateTime)
410385
end
411-
return POSTGRES_EPOCH_DATETIME + Microsecond(ntoh(unsafe_load(Ptr{Int64}(ptr))))
386+
return POSTGRES_EPOCH_DATETIME + Microsecond(value)
412387
end
413388

414389
function pqparse(::Type{Date}, ptr::Ptr{UInt8})

0 commit comments

Comments
 (0)