python – Why does datetime.datetime.utcnow() not contain timezone information?

python – Why does datetime.datetime.utcnow() not contain timezone information?

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() doesnt 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)

That means it is timezone naive, so you cant 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). Dont use tz.localize(datetime.now()) — it may fail during end-of-DST transition when the local time is ambiguous.

python – Why does datetime.datetime.utcnow() not contain timezone information?

The standard Python libraries didnt 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 cant 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.

Leave a Reply

Your email address will not be published.