Since changing datetime would break compatibility, I experimented with a module called adatetime ('a' for aware) where timezone-naive objects are not allowed.

The class methods adatetime.datetime.fromtimestamp(t) and adatetime.datetime.utcfromtimestamp(t) produces objects that compare as equal. One is in the local timezone and the other is in UTC but they represent the same point in time. With the standard datetime module this results in unequal naive objects.

There is no such thing as a local time_t in POSIX. Internal representation is always UTC and broken-down human time (struct tm) always has an associated timezone. No mixups. The python datetime module supports a non-UTC int or float representation with the methods .fromtimestamp(), .utcfromtimestamp() and .timestamp(). In these methods the time in seconds may be implicitly treated or generated as local time. I consider this the "Original Sin" of an otherwise very well-designed module.

I experimented with various alternatives for how adatetime should behave when tzinfo is not provided: using either UTC or the local timezone as default or always require it to be passed explicitly. I think the best default is UTC, with a singleton named 'local' that can be passed as tzinfo to specify using the local timezone (same behavior as adding .astimezone(None)). For code that always passes an explicit tzinfo this makes adatetime almost 100% compatible to the standard datetime. The only difference is the behavior of .fromtimestsamp() / .utcfromtimestamp() being aware by default. To make it fully compatible would require either adding some new method for creating aware datetime to both datetime and adatetime or removing .utcfromtimestamp() from adatetime and making adatetime's .fromtimestamp() tzinfo argument not optional.


On Tue, 28 Dec 2021 at 04:24, Paul Ganssle <python@ml.ganssle.io> wrote:

I don't really think zoneinfo being in the stdlib has much bearing on the question of utcnow/utctimestamp. We already had a UTC object in the standard library, and could have made this change any time, but chose not to because it would break backwards compatibility.

I'm definitely more in favor of deprecating it than I am of changing the behavior, which would be a major breaking change and one that is hard to warn about. Removing utcnow would probably be a lot of work for a lot of people, but many people are probably using it wrong anyway so that may be a net benefit.

That said, there is at least one use case I'm concerned about where the replacement is not great:

If you want a datetime in UTC that you immediately format, attaching the `UTC` object rather than using `utcnow` would lead to a performance regression without any actual benefit (and sometimes it's actually a bit of a pain). For example:

    print(datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"))
    print(datetime.utcnow().isoformat())

would have to turn into:

    print(datetime.now(UTC).strftime("%Y-%m-%d %H:%M:%S"))
    print(datetime.now(UTC).replace(tzinfo=None).isoformat())

The first of these is slower but no safer than the `utcnow` version, and the second of these actually involves stripping the UTC object from the result of `now` just to avoid `isoformat`'s behavior where it automatically appends the time zone offset to aware datetimes.

I haven't looked at it, but it may be that we can special-case `datetime.timezone.utc` in the `now()` and `fromtimestamp()` constructors so that `datetime.now(timezone.utc)` is just as fast as `datetime.utcnow()`, in which case the first example is not a huge deal, and maybe the second performance regression isn't so bad that it is worth leaving around footguns like this. It'd be nice to put some numbers on that.

Best,
Paul

On 12/27/21 19:33, Brock Mendel wrote:
Now that zoneinfo is in the stdlib, I'd like to revisit the idea of either a) making utcnow/utcfromtimestamp return tzaware or b) deprecating in favor of explicitly passing tzinfos to now/fromtimestamp.

Thoughts?

On Mon, Apr 22, 2019 at 10:54 AM Alexander Belopolsky <alexander.belopolsky@gmail.com> wrote:
> what if I'm in New York, but running on a JupyterLab system in Los Angeles?

In this case, it would be the responsibility of the JupyterLab designers to set the timezone of the kernel to something useful to the user.  In the case of a single-user kernel that would be the user's timezone, in the case of multi-user kernels - most likely UTC or something that the users can agree upon.  The location of the JupyterLab server should never be a consideration.

Setting the timezone is currently more complicated than it should be:

import sys, time
sys.environ['TZ'] = 'America/New_York'
time.tzset()

but I don't think we can improve that before python gets an integrated timezone database.  For now, this is what you should do to make sure a remote system uses the timezone that you want.
_______________________________________________
Datetime-SIG mailing list -- datetime-sig@python.org
To unsubscribe send an email to datetime-sig-leave@python.org
https://mail.python.org/mailman3/lists/datetime-sig.python.org/
The PSF Code of Conduct applies to this mailing list: https://www.python.org/psf/codeofconduct/

_______________________________________________
Datetime-SIG mailing list -- datetime-sig@python.org
To unsubscribe send an email to datetime-sig-leave@python.org
https://mail.python.org/mailman3/lists/datetime-sig.python.org/
The PSF Code of Conduct applies to this mailing list: https://www.python.org/psf/codeofconduct/
_______________________________________________
Datetime-SIG mailing list -- datetime-sig@python.org
To unsubscribe send an email to datetime-sig-leave@python.org
https://mail.python.org/mailman3/lists/datetime-sig.python.org/
The PSF Code of Conduct applies to this mailing list: https://www.python.org/psf/codeofconduct/