kotlinx-datetime: Serializing `FixedOffsetTimeZone` doesn't produce timezone database entry

When serializing the constant TimeZone.UTC, which is a FixedOffsetTimeZone, I was seeing the value "Z". Comparing this against the tzdb, I don’t believe this to be the right value. I believe the correctly encoded value should be one of:

  • Etc/Zulu
  • Etc/UTC
  • Zulu
  • UTC

Is it possible the Z is the serialized form of the offset portion of an ISO 8601 String? Is that to be expected? I would expect the serialization of a TimeZone to yield the tzdb name.

I am unsure if other instances of FixedOffsetTimeZone experience the same problem. I’m happy to help dig in if more info is needed.

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Comments: 17 (5 by maintainers)

Most upvoted comments

FWIW, I had some tests for a class that does some date formatting to include the time zone at the end. When switching from TimeZone.of("UTC") to TimeZone.UTC, my tests started failing because they were expecting UTC at the end of the formatted string but the switch to TimeZone.UTC consequently led to a formatted string with GMT as the time zone.

Ultimately the code was using java.text.SimpleDateFormat and it was setting the time zone to java.util.TimeZone.getTimeZone(TimeZone.of("UTC").toString()) originally. But replacing TimeZone.of("UTC") to TimeZone.UTC changed the behavior due to the toString() going from returning "UTC" to "Z". Upon digging a little further, that’s when I realized that TimeZone.of("UTC") != TimeZone.UTC. 🤔

Yes, but what end function does this serve?

I see the difference between them as the difference between numbers (5, -10) and functions that return numbers ({ _ -> 5 }, { _ -> 10 }). Another analogy is the difference between a clock reading (the position of the hour and minute hands) and a clock that is stuck. Is a clock that is stuck forever literally just the time that it shows?

A time zone is a function that maps the actual time to the UtcOffset that is used in that location at that moment, and a fixed-offset time zone is, when seen like this, a constant function.

What end functions (that I’m potentially unaware of) does a FixedOffsetTimeZone facilitate that a UtcOffset cannot?

FixedOffsetTimeZone, as you saw, also stores the name of the timezone. For example, GMT and UTC are both timezones that are fixed-offset and always have the UtcOffset value of zero, but they even have different Wikipedia pages: https://en.wikipedia.org/wiki/Universal_Time https://en.wikipedia.org/wiki/Greenwich_Mean_Time Time zones are used not only for computation but also for communication. If someone says something is in the GMT timezone, maybe the do want to highlight that it’s not the UTC timezone. Who knows.

java.time has the class ZoneOffset which is an inheritor of ZoneId and combines the functionality of expressing an offset from UTC and using it as a time zone. We decided to split these aspects into separate classes. It’s true that FixedOffsetTimeZone and UtcOffset have the same representation when serialized to string, but it doesn’t mean that their functionality is duplicated.