Dates.DateTime() can decode string dates with a terminal Z (for UTC). However, if TimeZones has been loaded, it fails, even using the module name (Dates.DateTime()).
What’s the best way of dealing with this?
julia> using Dates
julia> Dates.DateTime("2024-11-23T15:32:14.211Z", "yyyy-mm-ddTHH:MM:SS.sssZ")
2024-11-23T15:32:14.211
julia> using TimeZones
julia> Dates.DateTime("2024-11-23T15:32:14.211Z", "yyyy-mm-ddTHH:MM:SS.sssZ")
ERROR: ArgumentError: Unable to parse date time. Expected directive DatePart(Z) at char 24
There is no character code Z in the stdlib Dates per the Julia documentation. So, you’re matching a literal Z in your first example. It’s parsed like any of the delimiters.
TimeZones.jl overloads the Dates.jl functions with additional methods that accept Z or z as the character codes for time zones. So, it doesn’t matter if you prefix the functions with Dates..
TimeZones.jl uses the IANA database that doesn’t have a zone called Z. See the valid names with TimeZones.timezone_abbrs() or here.
I know, Z is often used to indicate UTC but it’s not in the official database. I usually just cut the Z off or replace it:
This is a good example of why you should always escape character literals that shouldn’t have a special meaning in the dateformat[1] (like T and Z in this example):
julia> using Dates
julia> fmt = "yyyy-mm-dd\\THH:MM:SS.sss\\Z"; # note the double \\
julia> Dates.DateTime("2024-11-23T15:32:14.211Z", fmt)
2024-11-23T15:32:14.211
julia> using TimeZones
julia> Dates.DateTime("2024-11-23T15:32:14.211Z", fmt)
2024-11-23T15:32:14.211
Note also that it is better to create the dateformat ones (instead of having to parse the formatting string on every call). This can be done with the dateformat string macro:
julia> dfmt = dateformat"yyyy-mm-dd\THH:MM:SS.sss\Z" # note the single \
dateformat"yyyy-mm-dd\THH:MM:SS.sss\Z"
julia> Dates.DateTime("2024-11-23T15:32:14.211Z", dfmt)
2024-11-23T15:32:14.211
The way Dates and TimeZones interact this way isn’t very nice though, but atleast you are immune to these types of errors if you escape. ↩︎
This must be due to some piracy in the TimeZones package, right? One doesn’t really expect simply loading another package (that may happen indirectly) to affect basic Date parsing. Escaping non-control characters isn’t even mentioned in the DateFormat docs afaict.
Thanks for the very informative replies. The treatment of Z is a bit irritating, but I see it has a logic. Both chopsuffix() and escaping look like sufficient fixes for me.