seddonym
seddonym

Reputation: 17229

In python, how do I create a timezone aware datetime from a date and time?

In Python, let's say I have a date of 25 December 2016. How can I create a timezone-aware datetime of noon on that date?

Bonus points if it's compatible with Django's timezone handling.

Upvotes: 24

Views: 29319

Answers (2)

seddonym
seddonym

Reputation: 17229

The trick is to first combine the naive time and the date into a naive datetime. This naive datetime can then be converted to an aware datetime.

The conversion can be done using the third party package pytz (using, in this case, the 'Europe/London' timezone):

import datetime
import pytz

naive_time = datetime.time(0, 30)
date = datetime.date(2016, 12, 25)
naive_datetime = datetime.datetime.combine(date, naive_time)

timezone = pytz.timezone('Europe/London')
aware_datetime = timezone.localize(naive_datetime) 

If you're doing it in Django, and want to use the current timezone (as configured in Django), you can replace the final two lines with a call to make_aware:

from django.utils import timezone

aware_datetime = timezone.make_aware(naive_datetime)

Upvotes: 52

Neal Gokli
Neal Gokli

Reputation: 485

Erik's answer to this question explains why you should use datetime.combine() followed by timezone.localize(). Setting the timezone directly on the datetime.time instance will not take the date into account, which could leave you with an incorrect result (due to daylight savings or even historic transitions). datetime.combine() just isn't that smart!

>>> import pytz
>>> import datetime
>>> d = datetime.date(2016, 12, 25)
>>> t = datetime.time(12)
>>> tz = pytz.timezone('US/Pacific')
>>> tz.localize(datetime.datetime.combine(d,t))
datetime.datetime(2016, 12, 25, 12, 0, tzinfo=<DstTzInfo 'US/Pacific' PST-1 day, 16:00:00 STD>)

Upvotes: 5

Related Questions