Python: Add or remove timezone hours from a timestamp and get actual time

Viewed 585

In Python, I need to get the actual time of a given string timestamp converted to a different timezone without timezone information. I am using pytz to do this. But all I get is the given DateTime with the timezone information appended to it.

Base datetime : 2020-05-29 19:00:00 (A string datetime without timezone info)

Requirement: When this time is converted to (US Zipcode 90071) -0700 timezone, it should return "2020-05-29 12:00:00", not "2020-05-29 19:00:00-0700"

Code:

import pytz
from datetime import datetime
from uszipcode import SearchEngine
from timezonefinder import TimezoneFinder

date_time_obj = datetime.strptime("2020-05-29 19:00:00", '%Y-%m-%d %H:%M:%S')
zip = "90071"

search = SearchEngine(simple_zipcode=True)
zipcode = search.by_zipcode(zip)
zipcode = zipcode.to_dict()
tf = TimezoneFinder(in_memory=True)
timezone = tf.timezone_at(lng=zipcode['lng'], lat=zipcode['lat'])
tz = pytz.timezone(timezone)
new_timestamp = tz.localize(date_time_obj)

new_timestamp_str = datetime.strftime(new_timestamp, '%m/%d/%Y %H:%M:%S')

But this returns 2020-05-29 19:00:00.000000-0700. I need to retrieve a DateTime object/string with the actual time shown in that timezone without a timezone chunk attached to the end of the DateTime.

2 Answers

It appears that your original date and time are in UTC. So for localize to work properly, you have to start with the proper timezone attached.

date_time_obj = datetime.strptime("2020-05-29 19:00:00", '%Y-%m-%d %H:%M:%S').replace(tzinfo=pytz.utc)

Then you can remove it again after the conversion:

return date_time_obj.astimezone(tz).replace(tzinfo=None)

Assuming your "Base datetime" refers to UTC, you have to add a tzinfo=UTC first before you convert to another timezone. Also, avoid overwriting built-ins like zip. Example using dateutil:

from datetime import datetime
import dateutil
from uszipcode import SearchEngine
from timezonefinder import TimezoneFinder

date_time_obj = datetime.strptime("2020-05-29 19:00:00", '%Y-%m-%d %H:%M:%S')
zipcode = "90071"

search = SearchEngine(simple_zipcode=True)
zipcode = search.by_zipcode(zipcode)
zipcode = zipcode.to_dict()
tf = TimezoneFinder(in_memory=True)
timezone = tf.timezone_at(lng=zipcode['lng'], lat=zipcode['lat'])

# localize to UTC first
date_time_obj = date_time_obj.replace(tzinfo=dateutil.tz.UTC)

# now localize to timezone of the zipcode:
new_timestamp = date_time_obj.astimezone(dateutil.tz.gettz(timezone))

new_timestamp_str = datetime.strftime(new_timestamp, '%m/%d/%Y %H:%M:%S')
# '05/29/2020 12:00:00'

If you need to use pytz, make sure to use localize instead of replace (even though UTC is an exception).

Sidenote: If your "Base datetime" refers to local time (operating system), you could obtain that timezone by

import time
import dateutil
localtzname = time.tzname[time.daylight]
tz = dateutil.tz.gettz(localtzname)
Related