# Dates/TimeZones clash when decoding string date with terminal Z

**URL:** <https://discourse.julialang.org/t/dates-timezones-clash-when-decoding-string-date-with-terminal-z/123025>\
**Category:** General Usage\
**Created:** [November 24, 2024, 8:29pm UTC](https://discourse.julialang.org/t/dates-timezones-clash-when-decoding-string-date-with-terminal-z/123025 "2024-11-24T20:29:46Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![bhalpin](https://avatars.discourse-cdn.com/v4/letter/b/779978/32.png) [@bhalpin](https://discourse.julialang.org/u/bhalpin)\
**Post date:** [November 24, 2024, 8:29pm UTC](https://discourse.julialang.org/t/dates-timezones-clash-when-decoding-string-date-with-terminal-z/123025/1 "2024-11-24T20:29:46Z")

</div>

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
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

```

---

<div class="post-metadata">

**Author:** ![piechologist](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piechologist/32/27662_2.png) [@piechologist](https://discourse.julialang.org/u/piechologist)\
**Post date:** [November 25, 2024, 10:30am UTC](https://discourse.julialang.org/t/dates-timezones-clash-when-decoding-string-date-with-terminal-z/123025/2 "2024-11-25T10:30:02Z")

</div>

A few different things are going on here:

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](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).

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:

```julia
julia> DateTime(chopsuffix("2024-11-23T15:32:14.211Z", "Z"), dateformat"yyyy-mm-ddTHH:MM:SS.sssZ")

julia> DateTime(replace("2024-11-23T15:32:14.211Z", "Z"=>"+0000"), dateformat"yyyy-mm-ddTHH:MM:SS.ssszzzz")

```

Note the use of the `dateformat""` macro instead of passing a plain format string. The latter is pretty expensive if you do that often.

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [November 25, 2024, 2:29pm UTC](https://discourse.julialang.org/t/dates-timezones-clash-when-decoding-string-date-with-terminal-z/123025/3 "2024-11-25T14:29:01Z")

</div>

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-repl
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-repl
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

```

* * *

1. 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.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [November 25, 2024, 4:23pm UTC](https://discourse.julialang.org/t/dates-timezones-clash-when-decoding-string-date-with-terminal-z/123025/4 "2024-11-25T16:23:20Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [November 25, 2024, 4:27pm UTC](https://discourse.julialang.org/t/dates-timezones-clash-when-decoding-string-date-with-terminal-z/123025/5 "2024-11-25T16:27:03Z")

</div>

See [https://github.com/JuliaTime/TimeZones.jl/issues/303](https://github.com/JuliaTime/TimeZones.jl/issues/303) and [https://github.com/JuliaLang/julia/pull/38959](https://github.com/JuliaLang/julia/pull/38959) for some prior discussion.

---

<div class="post-metadata">

**Author:** ![bhalpin](https://avatars.discourse-cdn.com/v4/letter/b/779978/32.png) [@bhalpin](https://discourse.julialang.org/u/bhalpin)\
**Post date:** [November 25, 2024, 4:44pm UTC](https://discourse.julialang.org/t/dates-timezones-clash-when-decoding-string-date-with-terminal-z/123025/6 "2024-11-25T16:44:38Z")

</div>

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.
