[New-bugs-announce] [issue46614] Add option to output UTC datetimes as "Z" in `.isoformat()`

Paul Ganssle report at bugs.python.org
Wed Feb 2 12:31:46 EST 2022


New submission from Paul Ganssle <bpo at m.ganssle.io>:

As part of bpo-35829, it was suggested that we add the ability to output the "Z" suffix in `isoformat()`, so that `fromisoformat()` can both be the exact functional inverse of `isoformat()` and parse datetimes with "Z" outputs. I think that that's not a particularly compelling motivation for this, but I also see plenty of examples of `datetime.utcnow().isoformat() + "Z"` out there, so it seems like this is a feature that we would want to have *anyway*, particularly if we want to deprecate and remove `utcnow`.

I've spun this off into its own issue so that we can discuss how to implement the feature. The two obvious questions I see are:

1. What do we call the option? `use_utc_designator`, `allow_Z`, `utc_as_Z`?
2. What do we consider as "UTC"? Is it anything with +00:00? Just `timezone.utc`? Anything that seems like a fixed-offset zone with 0 offset?

For example, do we want this?

>>> LON = zoneinfo.ZoneInfo("Europe/London")
>>> datetime(2022, 3, 1, tzinfo=LON).isoformat(utc_as_z=True)
2022-03-01T00:00:00Z
>>> datetime(2022, 6, 1, tzinfo=LON).isoformat(utc_as_z=True)
2022-06-01T00:00:00+01:00

Another possible definition might be if the `tzinfo` is a fixed-offset zone with offset 0:

>>> datetime.timezone.utc.utcoffset(None)
timedelta(0)
>>> zoneinfo.ZoneInfo("UTC").utcoffset(None)
timedelta(0)
>>> dateutil.tz.UTC.utcoffset(None)
timedelta(0)
>>> pytz.UTC.utcoffset(None)
timedelta(0)

The only "odd man out" is `dateutil.tz.tzfile` objects representing fixed offsets, since all `dateutil.tz.tzfile` objects return `None` when `utcoffset` or `dst` are passed `None`. This can and will be changed in future versions.

I feel like "If the offset is 00:00, use Z" is the wrong rule to use conceptually, but considering that people will be opting into this behavior, it is more likely that they will be surprised by `datetime(2022, 3, 1, tzinfo=ZoneInfo("Europe/London").isoformat(utc_as_z=True)` returning `2022-03-01T00:00:00+00:00` than alternation between `Z` and `+00:00`.

Yet another option might be to add a completely separate function, `utc_isoformat(*args, **kwargs)`, which is equivalent to (in the parlance of the other proposal) `dt.astimezone(timezone.utc).isoformat(*args, **kwargs, utc_as_z=True)`.  Basically, convert any datetime to UTC and append a Z to it. The biggest footgun there would be people using it on naïve datetimes and not realizing that it would interpret them as system local times.

----------
assignee: p-ganssle
components: Library (Lib)
messages: 412384
nosy: belopolsky, brett.cannon, p-ganssle
priority: normal
severity: normal
stage: needs patch
status: open
title: Add option to output UTC datetimes as "Z" in `.isoformat()`
type: enhancement
versions: Python 3.11

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue46614>
_______________________________________


More information about the New-bugs-announce mailing list