HiveBrain v1.2.0
Get Started
← Back to all entries
snippetpythonCritical

How to make a datetime object aware (not naive)?

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
datetimehownaiveobjectmakeawarenot

Problem

What I need to do

I have a timezone-unaware datetime object, to which I need to add a time zone in order to be able to compare it with other timezone-aware datetime objects. I do not want to convert my entire application to timezone unaware for this one legacy case.

What I've Tried

First, to demonstrate the problem:

Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49) 
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> import pytz
>>> unaware = datetime.datetime(2011,8,15,8,15,12,0)
>>> unaware
datetime.datetime(2011, 8, 15, 8, 15, 12)
>>> aware = datetime.datetime(2011,8,15,8,15,12,0,pytz.UTC)
>>> aware
datetime.datetime(2011, 8, 15, 8, 15, 12, tzinfo=)
>>> aware == unaware
Traceback (most recent call last):
  File "", line 1, in 
TypeError: can't compare offset-naive and offset-aware datetimes


First, I tried astimezone:

>>> unaware.astimezone(pytz.UTC)
Traceback (most recent call last):
  File "", line 1, in 
ValueError: astimezone() cannot be applied to a naive datetime
>>>


It's not terribly surprising this failed, since it's actually trying to do a conversion. Replace seemed like a better choice (as per How do I get a value of datetime.today() in Python that is "timezone aware"?):

>>> unaware.replace(tzinfo=pytz.UTC)
datetime.datetime(2011, 8, 15, 8, 15, 12, tzinfo=)
>>> unaware == aware
Traceback (most recent call last):
  File "", line 1, in 
TypeError: can't compare offset-naive and offset-aware datetimes
>>>


But as you can see, replace seems to set the tzinfo, but not make the object aware. I'm getting ready to fall back to doctoring the input string to have a timezone before parsing it (I'm using dateutil for parsing, if that matters), but that seems incredibly kludgy.

Also, I've tried this in both Python 2.6 and Python 2.7, with the same results.

Context

I am writing a parser for some data files. There is an old format I need to

Solution

In general, to make a naive datetime timezone-aware, use the localize method:

import datetime
import pytz

unaware = datetime.datetime(2011, 8, 15, 8, 15, 12, 0)
aware = datetime.datetime(2011, 8, 15, 8, 15, 12, 0, pytz.UTC)

now_aware = pytz.utc.localize(unaware)
assert aware == now_aware


For the UTC timezone, it is not really necessary to use localize since there is no daylight savings time calculation to handle:

now_aware = unaware.replace(tzinfo=pytz.UTC)


works. (.replace returns a new datetime; it does not modify unaware.)

Code Snippets

import datetime
import pytz

unaware = datetime.datetime(2011, 8, 15, 8, 15, 12, 0)
aware = datetime.datetime(2011, 8, 15, 8, 15, 12, 0, pytz.UTC)

now_aware = pytz.utc.localize(unaware)
assert aware == now_aware
now_aware = unaware.replace(tzinfo=pytz.UTC)

Context

Stack Overflow Q#7065164, score: 890

Revisions (0)

No revisions yet.