Why does datetime.datetime.utcnow() not contain timezone information?
Hire the world's top talent on demand or became one of them at Toptal: https://topt.al/25cXVn
and get $2,000 discount on your first invoice
--------------------------------------------------
Take control of your privacy with Proton's trusted, Swiss-based, secure services.
Choose what you need and safeguard your digital life:
Mail: https://go.getproton.me/SH1CU
VPN: https://go.getproton.me/SH1DI
Password Manager: https://go.getproton.me/SH1DJ
Drive: https://go.getproton.me/SH1CT
Music by Eric Matyas
https://www.soundimage.org
Track title: Switch On Looping
--
Chapters
00:00 Why Does Datetime.Datetime.Utcnow() Not Contain Timezone Information?
00:20 Answer 1 Score 88
01:17 Accepted Answer Score 251
02:08 Answer 3 Score 21
02:49 Answer 4 Score 374
03:31 Thank you
--
Full question
https://stackoverflow.com/questions/2331...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #datetime
#avk47
ANSWER 1
Score 374
Note that for Python 3.2 onwards, the datetime module contains datetime.timezone. The documentation for datetime.utcnow() says:
An aware current UTC datetime can be obtained by calling
datetime.now(timezone.utc).
So, datetime.utcnow() doesn't set tzinfo to indicate that it is UTC, but datetime.now(datetime.timezone.utc) does return UTC time with tzinfo set.
So you can do:
>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2014, 7, 10, 2, 43, 55, 230107, tzinfo=datetime.timezone.utc)
Since Python 3.11, there also exists datetime.UTC which is equivalent to datetime.timezone.utc. So you can also do datetime.datetime.now(datetime.UTC).
ACCEPTED ANSWER
Score 251
That means it is timezone naive, so you can't use it with datetime.astimezone
you can give it a timezone like this
import pytz # 3rd party: $ pip install pytz
u = datetime.utcnow()
u = u.replace(tzinfo=pytz.utc) #NOTE: it works only with a fixed utc offset
now you can change timezones
print(u.astimezone(pytz.timezone("America/New_York")))
To get the current time in a given timezone, you could pass tzinfo to datetime.now() directly:
#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz
print(datetime.now(pytz.timezone("America/New_York")))
It works for any timezone including those that observe daylight saving time (DST) i.e., it works for timezones that may have different utc offsets at different times (non-fixed utc offset). Don't use tz.localize(datetime.now()) -- it may fail during end-of-DST transition when the local time is ambiguous.
ANSWER 3
Score 88
The standard Python libraries didn't include any tzinfo classes until Python 3.2. I can only guess at the reasons. Personally I think it was a mistake not to include a tzinfo class for UTC, because that one is uncontroversial enough to have a standard implementation. Although there was no implementation in the library, there is one given as an example in the tzinfo documentation.
from datetime import timedelta, tzinfo
ZERO = timedelta(0)
# A UTC class.
class UTC(tzinfo):
"""UTC"""
def utcoffset(self, dt):
return ZERO
def tzname(self, dt):
return "UTC"
def dst(self, dt):
return ZERO
utc = UTC()
Once you have a UTC tzinfo object, you still can't use it with utcnow. To get the current time as an aware datetime object:
from datetime import datetime
now = datetime.now(utc)
In Python 3.2 they finally put a UTC tzinfo class in the library:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
In Python 3.9 they created tzinfo classes for all the other time zones. See PEP 615 -- Support for the IANA Time Zone Database in the Standard Library for all the details.
ANSWER 4
Score 21
The pytz module is one option, and there is another python-dateutil, which although is also third party package, may already be available depending on your other dependencies and operating system.
I just wanted to include this methodology for reference- if you've already installed python-dateutil for other purposes, you can use its tzinfo instead of duplicating with pytz
import datetime
import dateutil.tz
# Get the UTC time with datetime.now:
utcdt = datetime.datetime.now(dateutil.tz.tzutc())
# Get the UTC time with datetime.utcnow:
utcdt = datetime.datetime.utcnow()
utcdt = utcdt.replace(tzinfo=dateutil.tz.tzutc())
# For fun- get the local time
localdt = datetime.datetime.now(dateutil.tz.tzlocal())
I tend to agree that calls to utcnow should include the UTC timezone information. I suspect that this is not included because the native datetime library defaults to naive datetimes for cross compatibility.