crystal
crystal copied to clipboard
Improve format for `Time#inspect`
Time#inspect produces a format that is roughly equivalent to to_s("%F %T.%N %::z %Z").
But there are some special cases:
- automatically trims insignificant digits of nanoseconds
- omits seconds in the time zone offset if zero
- omits the location if the offset is fixed
- unless the location is UTC, then omits the offset and prints
UTCinstead
- unless the location is UTC, then omits the offset and prints
These special cases make the format more concise, which is a good thing.
But the special cases for offset and location causes some inconsistencies. Sometimes there's an offset, sometimes an offset plus location and sometimes only a location 🤷
To simplify this, I suggest changing the format to always print the offset, and always omit the location when it's fixed.
For a UTC offset, we can use the Z identifier from ISO 8601/RFC 3339 which results in an even more concise format.
An additional consideration is to standardize on the Internet Extended Date/Time Format (IXDTF, RFC 9557), which defines a pretty standardized format for representing time instances with additional information. For our use case, it would be equivalent to an RFC3339 format[^1] plus an extended information tag identifying the location.
# Time.utc(2014, 1, 2, 3, 4, 5, nanosecond: 123_456_789).inspect
-2014-01-02 03:04:05.123456789 UTC
+2014-01-02 03:04:05.123456789Z
# Time.local(2014, 1, 2, 3, 4, 5, nanosecond: 123_456_789, location: Time::Location.load("Europe/Berlin")).inspect
-2014-01-02 03:04:05.123456789 +01:00 Europe/Berlin
+2014-01-02T03:04:05.123456789+01:00[Europe/Berlin]
# Time.local(2014, 1, 2, 3, 4, 5, nanosecond: 123_456_789, location: Time::Location.fixed(3600)).inspect
-2014-01-02 03:04:05.123456789 +01:00
+2014-01-02T03:04:05.123456789+01:00
The results are very similar to what we have right now, just a bit more refined.
Length is usually identical, but slightly shorter for fixed locations.
Changing the separator between date and time from white space to T may reduce human readbility, but it improves technical precision and interoperability.
The major benefit of following a standardized format is interoperability: it makes it easy to copy and paste the output into other systems without format conversion.
On that note, I hope to introduce a generic parse method which parses the output format of Time#inspect into a new Time instance, for easy (de-)serialization.
Related:
- Original discussion about time zone support: #4556
- Previous update to
Time#inspect: #5794
[^1]: Technically it would not be 100% conform to RFC3339 which does not support offsets with a fraction of a minute (see #15807).