I may be over-stating the degree of consensus about the deprecation here. I'm not sure too many people have discussed it, but there is very little reason to ever use them, because:

1. The reason they existed in the first place was as a convenience when there were no concrete time zone types in the standard library.
2. Adding the `tz` argument to `now` and `timestamp` has provided a more general solution to the problem anyway.
3. They create objects that are inconsistent with the way Python treats naive datetimes, since naive datetimes are supposed to be abstract representations of a time, and if they need to be treated as a concrete time, they are taken to be local times.

The one advantage `datetime.utcnow()` has is that it is somewhat faster than `datetime.now(tz=timezone.utc)` (I clock it at 168ns vs 300ns), but getting the current time in UTC is not likely to be the bottleneck in any sort of "hot loop" situation where 300ns is going to make the difference.

I think deprecating them would be nice, but it would break backwards compatibility to actually remove them, so I'm maybe +0 on that. I'd say at the very least documenting that these things have a good replacement would be a good idea. Maybe we should make a bpo issue (and possibly PR) for this.

Best,
Paul

On 4/15/19 10:32 PM, Brock Mendel wrote:
utcnow() and utcfromtimestamp are semi-deprecated functions because they do not return tz-aware datetime objects

Is this documented somewhere?  Should that be reflected in the docs?  Is there a game-plan to make it actually-deprecated instead of semi-deprecated?




On Mon, Apr 15, 2019 at 5:23 PM Paul Ganssle <paul@ganssle.io> wrote:

utcnow() and utcfromtimestamp are semi-deprecated functions because they do not return tz-aware datetime objects and because in all functions that require a time zone offset (like `timestamp`), naive datetimes are treated as *local* times.

If you want to use tz-aware datetime objects (which will have the correct behavior), you should simply pass a time zone to the `tz` parameter of `now()` and `fromtimestamp`, respectively, so:

```
from datetime import datetime, timezone
a = datetime.now(tz=timezone.utc)
b = a.timestamp()
c = datetime.fromtimestamp(b, tz=timezone.utc)
assert a == c
```

I will note that because of the way aware datetime comparison semantics works, `a == c` will be true no matter what `tz` object you pass to `fromtimestamp`.

If I rewrite your example with equivalent commands that do not use `utcnow`, you will hopefully see how it works:

```
from datetime import datetime, timezone
from dateutil.tz import tzlocal

a = datetime.now(tz=timezone.utc).replace(tzinfo=None)
b = a.replace(tzinfo=tzlocal()).timestamp()
c = datetime.fromtimestamp(b, tz=timezone.utc).replace(tzinfo=None)
assert a == c
```

As you can see, in `a` you discard the time zone information associated with the datetime, and so in `b` it is implicitly taken to be "local time", shifting it by however many hours from UTC your local time is.

I will answer the hashability question in a separate e-mail, but I don't see how this has much to do with hashability.

P.S. Accidentally sent this to just Brock - Brock, sorry you are getting this twice.

On 4/15/19 8:01 PM, Brock Mendel wrote:
This has come up in pandas.Timestamp (which subclasses datetime).  The issue is internal consistency and round-trips.  Intuitively, we would expect:

```
a = datetime.utcnow()
b = a.timestamp()
c = datetime.utcfromtimestamp(b)
assert a == b
```

but this fails.  (Note: it works for `datetime.now()` with `datetime.fromtimestamp()`, though that is partially because of weird-to-me behavior of `timestamp()` for naive datetimes).

It would succeed if utcnow and utcfromtimestamp returned tz-aware datetime objects.  Thoughts?


_______________________________________________
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/