You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
datetime.datetime.utcnow should return a UTC timestamp #56965
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=<Date2011-08-16.18:16:48.484>created_at=<Date2011-08-16.06:52:54.393>labels= ['type-feature', 'library', '3.9']
title='datetime.datetime.utcnow should return a UTC timestamp'updated_at=<Date2022-01-10.18:40:59.514>user='https://bugs.python.org/bignose'
The documentation for ‘datetime.datetime.utcnow’ says “Return a new datetime representing UTC day and time.” The resulting object should be in the UTC timezone, not a naive no-timezone value.
This results in programs specifically requesting UTC time with ‘utcnow’, but then Python treating the return value as representing local time since it is not marked with the UTC timezone.
This is for backwards-compatibility as the UTC object did not come into existence until (I believe) Python 2.7. The docs for utcnow() explicitly state that if you want a timezone-aware UTC datetime object that you should use now() w/ the UTC object passed in.
Now if you would like to have a keyword argument for utcnow() to cause it to return a UTC object (e.g., utcnow(aware=True)), that may be a patch that could get accepted as it doesn't break backwards-compatibility if you leave the argument out.
Note that you can replace "timezone.utc" with *any* time zone. The result will be a timezone-aware time zone representing the current time in the time zone passed to the function.
I think because there is already a preferred solution available in the standard library, there is no need to add a parameter that would make utcnow return an aware datetime.
rtphokie commented on Jan 10, 2022
rtphokiemannequin
Mannequin
More actions
This enhancement request should be reconsidered.
Yes it is the documented behavior but that doesn't mean it's the right behavior. Functions should work as expected not just in the context of the module they are implemented in but the context of the problem they are solving.
The suggested workaround of essentially nesting the specified UTC time via datetime.now(timezone.utc) is ugly rather than beautiful, complex rather than simple, and nested instead of flat.
The suggestion that now is preferred over isnow loses sight that UTC is not like other timezones.
A lot has changed since Python 2.7 was released in 2010. It is the default timezone of cloud infrastructure.
from practical experience, it is a whole lot better to not deal with
timezones in data processing code at all, but instead only use
naive UTC datetime values everywhere, expect when you have to
prepare reports or output which has a requirement to show datetime
value in local time or some specific timezone.
You convert all datetime values into UTC upon input, possibly
store the timezone somewhere, if that is relevant for later reporting,
and then forget about timezones.
Your code will run faster, become a lot easier to understand
and you avoid many pitfalls that TZs have, esp. when TZs are
silently dropped interfacing to e.g. numeric code, databases or
other external code.
There's a reason why cloud code (and a lot of other code, such
as data science code) has standardized on UTC :-)
Note also that datetime.now() gives you a naive datetime. From an API consistency standpoint I think it makes sense that datetime.utcnow() gives a naive datetime. It would actually be confusing (IMO) for it to return an aware datetime. I can see why you might disagree, but backward compatibility wins in this case regardless.
rtphokie commented on Jan 10, 2022
rtphokiemannequin
Mannequin
More actions
I would argue that PEP-20 should win over backward compatibility, in addition to the points I hinted at above,
from practical experience, it is a whole lot better to not deal with timezones in data processing code at all, but instead only use naive UTC datetime values everywhere, expect when you have to prepare reports or output which has a requirement to show datetime value in local time or some specific timezone.
If you are working with datetime objects that represent time in a specific time zone other than the system local zone, you should probably have them carry around a tzinfo object.
Note also that datetime.now() gives you a naive datetime. From an API consistency standpoint I think it makes sense that datetime.utcnow() gives a naive datetime.
This... is not accurate. .now() gives you the local time; to the extent that they represent a date in a time zone at all, naïve time zones represent times in the system local time, which is why it makes sense for .now() to default to returning naïve time zones. For example, datetime.now().timestamp() will give accurate information, whereas datetime.utcnow().timestamp() will not (unless your local zone happens to be UTC or equivalent).
It would actually be confusing (IMO) for it to return an aware datetime. I can see why you might disagree, but backward compatibility wins in this case regardless.
As evidenced by this thread, the fact that we have some APIs that return naïve datetimes generated by a process that treats them as localized datetimes in something other than system local times is actually the source of confusion 😛
That said, from a backwards compatibility point of view, we simply cannot change this. It has been proposed many times and it would be a major breaking change for almost no reason. The best we can do is to deprecate the offending methods and remove them.
I am sympathetic to the idea of removing it, but we would probably want to put some optimizations in place for UTC first, to make the transition more seamless in the few places where there are legitimate uses for utcnow and utcfromtimestamp.
I would argue that PEP-20 should win over backward compatibility, in addition to the points I hinted at above, practicality beats purity
PEP-20 contains a bunch of contradictory advice, and it's not really a binding document anyway, so it definitely doesn't "win" over anything, but in this case you have it backwards. "Purity" would be making a breaking change for the purposes of making the function do what a lot of people think it does, but doing so would actually be impractical, because it would cause a lot of work for people, and create a lot of ambiguity in what people meant when they wrote a given line of code. The practical things to do here would be to either do nothing (not break anything that works and try and guide people away from using utcnow — maybe get a linting rule added to pylint to warn against it), or to deprecate and remove the function.
, which is why it makes sense for .now() to default to returning naïve time zones. For example, datetime.now().timestamp() will give accurate information,
The problem arises when comparing with aware objects. So how about returning aware objects and adding alias for timzezone.utc as utc?
Activity
bignose commentedon Aug 16, 2011
=====
=====
The documentation for ‘datetime.datetime.utcnow’ says “Return a new datetime representing UTC day and time.” The resulting object should be in the UTC timezone, not a naive no-timezone value.
This results in programs specifically requesting UTC time with ‘utcnow’, but then Python treating the return value as representing local time since it is not marked with the UTC timezone.
brettcannon commentedon Aug 16, 2011
This is for backwards-compatibility as the UTC object did not come into existence until (I believe) Python 2.7. The docs for utcnow() explicitly state that if you want a timezone-aware UTC datetime object that you should use now() w/ the UTC object passed in.
Now if you would like to have a keyword argument for utcnow() to cause it to return a UTC object (e.g., utcnow(aware=True)), that may be a patch that could get accepted as it doesn't break backwards-compatibility if you leave the argument out.
agustinhenze commentedon Apr 3, 2019
Hi there, I was wondering if we re-open this issue breaking the backward compatibility now?
pganssle commentedon Apr 3, 2019
@Tin utcnow is a semi-deprecated way to get a naive datetime that represents the time in UTC. The preferred replacement is to do this:
Note that you can replace "timezone.utc" with *any* time zone. The result will be a timezone-aware time zone representing the current time in the time zone passed to the function.
I think because there is already a preferred solution available in the standard library, there is no need to add a parameter that would make
utcnowreturn an aware datetime.rtphokie commentedon Jan 10, 2022
This enhancement request should be reconsidered.
Yes it is the documented behavior but that doesn't mean it's the right behavior. Functions should work as expected not just in the context of the module they are implemented in but the context of the problem they are solving.
The suggested workaround of essentially nesting the specified UTC time via datetime.now(timezone.utc) is ugly rather than beautiful, complex rather than simple, and nested instead of flat.
The suggestion that now is preferred over isnow loses sight that UTC is not like other timezones.
A lot has changed since Python 2.7 was released in 2010. It is the default timezone of cloud infrastructure.
malemburg commentedon Jan 10, 2022
Hi Tony,
from practical experience, it is a whole lot better to not deal with
timezones in data processing code at all, but instead only use
naive UTC datetime values everywhere, expect when you have to
prepare reports or output which has a requirement to show datetime
value in local time or some specific timezone.
You convert all datetime values into UTC upon input, possibly
store the timezone somewhere, if that is relevant for later reporting,
and then forget about timezones.
Your code will run faster, become a lot easier to understand
and you avoid many pitfalls that TZs have, esp. when TZs are
silently dropped interfacing to e.g. numeric code, databases or
other external code.
There's a reason why cloud code (and a lot of other code, such
as data science code) has standardized on UTC :-)
Cheers,
Marc-Andre Lemburg
eGenix.com
bitdancer commentedon Jan 10, 2022
Note also that datetime.now() gives you a naive datetime. From an API consistency standpoint I think it makes sense that datetime.utcnow() gives a naive datetime. It would actually be confusing (IMO) for it to return an aware datetime. I can see why you might disagree, but backward compatibility wins in this case regardless.
rtphokie commentedon Jan 10, 2022
I would argue that PEP-20 should win over backward compatibility, in addition to the points I hinted at above,
practicality beats purity
pganssle commentedon Jan 10, 2022
This is not good advice. It is out of date, and has some significant pitfalls. See my blog post on the subject: https://blog.ganssle.io/articles/2019/11/utcnow.html
If you are working with
datetimeobjects that represent time in a specific time zone other than the system local zone, you should probably have them carry around a tzinfo object.This... is not accurate.
.now()gives you the local time; to the extent that they represent a date in a time zone at all, naïve time zones represent times in the system local time, which is why it makes sense for.now()to default to returning naïve time zones. For example,datetime.now().timestamp()will give accurate information, whereasdatetime.utcnow().timestamp()will not (unless your local zone happens to be UTC or equivalent).As evidenced by this thread, the fact that we have some APIs that return naïve datetimes generated by a process that treats them as localized datetimes in something other than system local times is actually the source of confusion 😛
That said, from a backwards compatibility point of view, we simply cannot change this. It has been proposed many times and it would be a major breaking change for almost no reason. The best we can do is to deprecate the offending methods and remove them.
There is more information about the challenge that doing this would present in this datetime-SIG thread: https://mail.python.org/archives/list/datetime-sig@python.org/thread/PT4JWJLYBE5R2QASVBPZLHH37ULJQR43/
I am sympathetic to the idea of removing it, but we would probably want to put some optimizations in place for
UTCfirst, to make the transition more seamless in the few places where there are legitimate uses forutcnowandutcfromtimestamp.PEP-20 contains a bunch of contradictory advice, and it's not really a binding document anyway, so it definitely doesn't "win" over anything, but in this case you have it backwards. "Purity" would be making a breaking change for the purposes of making the function do what a lot of people think it does, but doing so would actually be impractical, because it would cause a lot of work for people, and create a lot of ambiguity in what people meant when they wrote a given line of code. The practical things to do here would be to either do nothing (not break anything that works and try and guide people away from using
utcnow— maybe get a linting rule added topylintto warn against it), or to deprecate and remove the function.SmartManoj commentedon Apr 20, 2022
The problem arises when comparing with aware objects. So how about returning aware objects and adding alias for
timzezone.utcasutc?