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\'
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>)
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)