pytz and astimezone() cannot be applied to a naive datetime

PythonDatetimeTimezonePytz

Python Problem Overview


I have a date and I need to make it time zone aware.

local_tz = timezone('Asia/Tokyo')
start_date = '2012-09-27'
start_date = datetime.strptime(start_date, "%Y-%m-%d")   
start_date = start_date.astimezone(local_tz)


now_utc = datetime.now(timezone('UTC'))
local_now = now_utc.astimezone(local_tz)

I need to find if this is true:

print start_date>local_now

But I get this error.

   start_date = start_date.astimezone(local_tz)
   ValueError: astimezone() cannot be applied to a naive datetime

I convert utc to tokyo with no issue. I need to make start_date timezone aware ad well in tokyo.

Thanks

Python Solutions


Solution 1 - Python

For pytz timezones, use their .localize() method to turn a naive datetime object into one with a timezone:

start_date = local_tz.localize(start_date)

For timezones without a DST transition, the .replace() method to attach a timezone to a naive datetime object should normally also work:

start_date = start_date.replace(tzinfo=local_tz)

See the localized times and date arithmetic of the pytz documentation for more details.

Solution 2 - Python

You could use local_tz.localize(naive_dt, is_dst=None) to convert a naive datetime object to timezone-aware one.

from datetime import datetime
import pytz

local_tz = pytz.timezone('Asia/Tokyo')
 
start_date = local_tz.localize(datetime(2012, 9, 27), is_dst=None)
now_utc = datetime.utcnow().replace(tzinfo=pytz.utc)

print start_date > now_utc

is_dst=None forces .localize() to raise an exception if given local time is ambiguous.

Solution 3 - Python

If you are using Django Rest Framework you could override the DateTimeField class like:

class DateTimeFieldOverridden(serializers.DateTimeField):

def to_representation(self, value):
    local_tz = pytz.timezone(TIME_ZONE)
    value = local_tz.localize(value)
    return super(DateTimeFieldOverridden, self).to_representation(value)

And you use it like this in your serializer:

date_time = DateTimeFieldOverridden(format='%d-%b-%Y', read_only=True)

Hope this helps someone.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTampaView Question on Stackoverflow
Solution 1 - PythonMartijn PietersView Answer on Stackoverflow
Solution 2 - PythonjfsView Answer on Stackoverflow
Solution 3 - PythonJoseph DaudiView Answer on Stackoverflow