datetime.datetime.utcnow()
Why does this datetime
not have any timezone info given that it is explicitly a UTC datetime
?
I would expect that this would contain tzinfo
.
datetime.datetime.utcnow()
Why does this datetime
not have any timezone info given that it is explicitly a UTC datetime
?
I would expect that this would contain tzinfo
.
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.
astimezone
. So datetime not only has no native timezones, but the only widely-available implementation of tzinfo is non-compliant to the supposed standard. –
Oleander u=datetime.now(pytz.utc)
–
Edgeworth tzinfo=
does not work with pytz for DST timezones, see this answer. –
Sluggish tz.localize(datetime.now())
; use datetime.now(tz)
instead. –
Occasionally datetime(2015, 1, 1, tzinfo=pytz.timezone('Europe/Paris'))
–
Sluggish now(tz)
is always correct. We are not discussing anything else here. –
Occasionally now(tz)
is not always correct: 'even "datetime.now(pytz.timezone('Australia/Melbourne'))" could give you a timestamp out by one hour if you were unlucky and the DST transition occurred while that statement was being run.' –
Sluggish now(tz)
that calls tz.fromutc
internally works even during DST transitions (because there is no DST transitions in utc). If you think I'm wrong; provide specific example (date, timezone, python, pytz version) –
Occasionally pytz.utc.localize(datetime.utcnow())
. I've found this also incorporates the DST variations without issue. –
Dyan 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)
.
datetime.now(timezone.utc)
or datetime.utcnow(timezone.utc)
? –
Commute datetime.utcnow()
takes no arguments. So it would have to be datetime.now(timezone.utc)
. –
Edgeworth datetime.now()
will return the machine time but datetime.utcnow()
will return the actual UTC time. –
Clorindaclorinde 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. –
Edgeworth tz
object in the now constructor it will return time of that timezone? Ok! Thanks for pointing out. –
Clorindaclorinde datetime.utcnow()
. It doesn't set tzinfo
though it is utc, but naive datetime object is presumed to represent system local time by datetime library. If your system local time is not UTC, datetime.datetime.utcnow().astimezone(datetime.timezone.utc)
gives wrong result. –
Dube datetime
object in UTC with the proper tzinfo
attached? –
Katharynkathe datetime.utcnow()
is deprecated in favor of datetime.now(timezone.utc)
–
Shortcircuit 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.
astimezone
. So datetime not only has no native timezones, but the only widely-available implementation of tzinfo is non-compliant to the supposed standard. –
Oleander u=datetime.now(pytz.utc)
–
Edgeworth tzinfo=
does not work with pytz for DST timezones, see this answer. –
Sluggish tz.localize(datetime.now())
; use datetime.now(tz)
instead. –
Occasionally datetime(2015, 1, 1, tzinfo=pytz.timezone('Europe/Paris'))
–
Sluggish now(tz)
is always correct. We are not discussing anything else here. –
Occasionally now(tz)
is not always correct: 'even "datetime.now(pytz.timezone('Australia/Melbourne'))" could give you a timestamp out by one hour if you were unlucky and the DST transition occurred while that statement was being run.' –
Sluggish now(tz)
that calls tz.fromutc
internally works even during DST transitions (because there is no DST transitions in utc). If you think I'm wrong; provide specific example (date, timezone, python, pytz version) –
Occasionally pytz.utc.localize(datetime.utcnow())
. I've found this also incorporates the DST variations without issue. –
Dyan 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.
datetime
objects created by utcnow()
)... –
Hold struct
module would do automatic conversions from Unicode to bytestring, and the final decision was to break compatibility with earlier Python 3 versions to prevent a bad decision from going forward. –
Katharynkathe tzinfo
documentation includes examples of code to implement it, but they don't include that functionality in datetime itself! docs.python.org/2/library/datetime.html#datetime.tzinfo.fromutc –
Chuch pytz
module's implementation contains. It adds a few helpful methods. –
Chuch pytz
is a great resource. By the time I had edited my answer to put in the example code, somebody else had already suggested it and I didn't want to steal their thunder. –
Katharynkathe utcnow()
is kept as it is. –
Elatia 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.
utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
–
Impulsion datetime.now(pytz_tz)
that always works; datetime.now(dateutil.tz.tzlocal())
may fail during DST transitions. PEP 495 -- Local Time Disambiguation might improve dateutil
situation in the future. –
Occasionally utc_dt = datetime.fromtimestamp(1234567890, dateutil.tz.tzutc())
(note: dateutil
with a non-fixed utc offset (such as dateutil.tz.tzlocal()
) may fail here, use a pytz
-based solution instead). –
Occasionally dateutil
for dateutil.parser
, I liked this solution best. It was as simple as: utcCurrentTime = datetime.datetime.now(tz=dateutil.tz.tzutc())
. Viola!! –
Chuch To add timezone
information in Python 3.2+
import datetime
>>> d = datetime.datetime.now(tz=datetime.timezone.utc)
>>> print(d.tzinfo)
'UTC+00:00'
AttributeError: 'module' object has no attribute 'timezone'
Python 2.7.13 (default, Jan 19 2017, 14:48:08) –
Isopod from datetime import datetime, timezone
then invoke with datetime.now(tz=timezone.utc)
–
Madgemadhouse Julien Danjou wrote a good article explaining why you should never deal with timezones. An excerpt:
Indeed, Python datetime API always returns unaware datetime objects, which is very unfortunate. Indeed, as soon as you get one of this object, there is no way to know what the timezone is, therefore these objects are pretty "useless" on their own.
Alas, even though you may use utcnow()
, you still won't see the timezone info, as you discovered.
Recommendations:
Always use aware
datetime
objects, i.e. with timezone information. That makes sure you can compare them directly (aware and unawaredatetime
objects are not comparable) and will return them correctly to users. Leverage pytz to have timezone objects.Use ISO 8601 as the input and output string format. Use
datetime.datetime.isoformat()
to return timestamps as string formatted using that format, which includes the timezone information.If you need to parse strings containing ISO 8601 formatted timestamps, you can rely on
iso8601
, which returns timestamps with correct timezone information. This makes timestamps directly comparable.
The behaviour of datetime.datetime.utcnow()
returning UTC time as naive datetime object is obviously problematic and must be fixed. It can lead to unexpected result if your system local timezone is not UTC, since datetime library presume naive datetime object to represent system local time. For example, datetime.datetime.utcnow().timestaamp()
gives timestamp of 4 hours ahead from correct value on my computer. Also, as of python 3.6, datetime.astimezone()
can be called on naive datetime instances, but datetime.datetime.utcnow().astimezone(any_timezone)
gives wrong result unless your system local timezone is UTC.
datetime.datetime.utcnow()
since it was ever introduced into Python aren't using tz-aware objects in most cases anyway - we're only ever storing and processing UTC and only doing the conversion for human users at the UI level. If you want UTC with tzinfo for some reason, only stick to the modern datetime objects that have tz support. –
Morganica It should include and now()
also. Related issue.
So till that, now()
is preferred over today()
and utcnow()
.
from datetime import datetime, timezone
utc = timezone.utc
date = datetime.now(utc)
print(date) # 2022-04-06 05:40:13.025347+00:00
date = datetime.now(timezone.utc) # datetime.datetime(2023, 10, 13, 8, 17, 21, 862183, tzinfo=datetime.timezone.utc)
and date = datetime.utcnow() #datetime.datetime(2023, 10, 13, 8, 17, 35, 668704)
–
Nomo from datetime import datetime
from dateutil.relativedelta import relativedelta
d = datetime.now()
date = datetime.isoformat(d).split('.')[0]
d_month = datetime.today() + relativedelta(months=1)
next_month = datetime.isoformat(d_month).split('.')[0]
UTC dates don't need any timezone info since they're UTC, which by definition means that they have no offset.
pytz.utc
). Note that there's a big difference between a value whose offset from UTC is unknown and one where it is known to be 0. The latter is what utcnow()
should return, IMO. That would fit in with "An aware object is used to represent a specific moment in time that is not open to interpretation" as per the documentation. –
Alberto © 2022 - 2024 — McMap. All rights reserved.