This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author p-ganssle
Recipients belopolsky, brett.cannon, p-ganssle
Date 2022-02-02.17:31:46
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1643823106.57.0.535855742317.issue46614@roundup.psfhosted.org>
In-reply-to
Content
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.
History
Date User Action Args
2022-02-02 17:31:46p-gansslesetrecipients: + p-ganssle, brett.cannon, belopolsky
2022-02-02 17:31:46p-gansslesetmessageid: <1643823106.57.0.535855742317.issue46614@roundup.psfhosted.org>
2022-02-02 17:31:46p-gansslelinkissue46614 messages
2022-02-02 17:31:46p-gansslecreate