TimeZones.jl
TimeZones.jl copied to clipboard
Parse date-time with optional timezone in the format.
Currently, this invocation of ZonedDateTime
constructor throws an error:
julia> ZonedDateTime("1988-04-29 09:00", "yyyy-mm-dd HH:MM")
ERROR: ArgumentError: Unable to parse string "1988-04-29 09:00" using format dateformat"yyyy-mm-dd HH:MM". Unknown time zone ""
Stacktrace:
[1] (::getfield(TimeZones, Symbol("##3#4")){String})() at /Users/dashti/.julia/packages/TimeZones/M8H2J/src/types/timezone.jl:54
[2] get!(::getfield(TimeZones, Symbol("##3#4")){String}, ::Dict{String,Tuple{TimeZone,TimeZones.Class}}, ::String) at ./dict.jl:452
[3] TimeZone(::String, ::TimeZones.Class) at /Users/dashti/.julia/packages/TimeZones/M8H2J/src/types/timezone.jl:46 (repeats 2 times)
[4] ZonedDateTime(::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::String) at /Users/dashti/.julia/packages/TimeZones/M8H2J/src/types/zoneddatetime.jl:127
[5] parse at /Users/sabae/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.2/Dates/src/parse.jl:285 [inlined]
[6] ZonedDateTime(::String, ::Dates.DateFormat{Symbol("yyyy-mm-dd HH:MM"),Tuple{Dates.DatePart{'y'},Dates.Delim{Char,1},Dates.DatePart{'m'},Dates.Delim{Char,1},Dates.DatePart{'d'},Dates.Delim{Char,1},Dates.DatePart{'H'},Dates.Delim{Char,1},Dates.DatePart{'M'}}}) at /Users/dashti/.julia/packages/TimeZones/M8H2J/src/parse.jl:85
[7] #ZonedDateTime#29(::String, ::Type{ZonedDateTime}, ::String, ::String) at /Users/dashti/.julia/packages/TimeZones/M8H2J/src/parse.jl:98
[8] ZonedDateTime(::String, ::String) at /Users/dashti/.julia/packages/TimeZones/M8H2J/src/parse.jl:98
[9] top-level scope at REPL[6]:1
The reason is that no timezone is specified in the date format. You might say that I should use DateTime("1988-04-29 09:00", "yyyy-mm-dd HH:MM")
, but what if I'm programming a library function and receiving the format as a parameter. Then, I have to have something like this (which is UGLY):
function parse_date_into_utc(input::String, format::String) :: DateTime
if occursin("z", format) || occursin("Z", format)
zdt = TimeZones.ZonedDateTime(input, format)
zdt.utc_datetime
else
DateTime(input, format)
end
end
Ideally, it should be possible to implement the same like this:
function parse_date_into_utc(input::String, format::String) :: DateTime
zdt = TimeZones.ZonedDateTime(input, format)
zdt.utc_datetime
end
The main reason for the error is that an empty timezone string produces an error in here. Can we have a default timezone (e.g., user-specified, UTC or local timezone) for this case?
The default would have to be user specified otherwise people could be very surprised when we assume the local time zone or UTC.
I think this a keyword could be added to specify the DateFormat
does not contain a time zone.
Asides:
- You should really use
dateformat"yyyy-mm-dd HH:MM"
if you want performant code. Constructing theDateFormat
object is rather of expensive - Prefer using
parse(ZonedDateTime, ::String, ::DateFormat)
. I have plans to deprecate theZonedDateTime
constructor with a date format.
The default would have to be user specified otherwise people could be very surprised when we assume the local time zone or UTC.
@omus Agreed, It's better for it to be user-defined.
Any updates on this?
I have a similar issue: I would like to parse a string with no time zone info directly into a ZonedDateTime
by supplying the time zone myself.
As an example, instead of this workaround
using Dates
using TimeZones
t_string = "2021-11-13T12:34:56Z"
fmt = Dates.DateFormat("yyyy-mm-ddTHH:MM:SS\\Z")
t = Dates.DateTime(t_string, fmt)
TimeZones.ZonedDateTime(t, TimeZones.tz"UTC")
I would like something like this
TimeZones.ZonedDateTime(t_string, fmt, TimeZones.tz"UTC")
(@omus : Is your comment about preferring parse
still valid? It seems that the constructor for ZonedDateTime
is still around)
Unfortunately no updates at this time. PRs are welcome.
I do still recommend using parse
to make your intent clear. The constructor is around and probably will continue to be around due to how the compact printing works in Dates.