在 Python 中,我需要在没有时区信息的情况下将给定字符串时间戳的实际时间转换为不同的时区。我正在使用pytz来做到这一点。但我得到的只是给定的日期时间,并附加了时区信息。
基准日期时间 :2020-05-29 19:00:00(没有时区信息的字符串日期时间(
要求:当此时间转换为(美国邮政编码 90071(-0700时区时, 它应该返回"2020-05-29 12:00:00",而不是">2020-05-29 19:00:00-0700">
法典:
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')
但这返回2020-05-29 19:00:00.000000-0700。我需要检索一个 DateTime 对象/字符串,其中包含该时区中显示的实际时间,而没有将时区块附加到日期时间的末尾。
假设您的"基本日期时间"指的是 UTC,则必须先添加tzinfo=UTC
,然后再转换为其他时区。另外,请避免覆盖内置函数,例如zip
.使用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'
如果需要使用pytz
,请确保使用localize
而不是replace
(即使 UTC 是一个例外(。
旁注:如果您的"基准日期时间"是指本地时间(操作系统(,您可以通过以下方式获取该时区
import time
import dateutil
localtzname = time.tzname[time.daylight]
tz = dateutil.tz.gettz(localtzname)
您的原始日期和时间似乎采用 UTC。 因此,为了使localize
正常工作,您必须从附加正确的时区开始。
date_time_obj = datetime.strptime("2020-05-29 19:00:00", '%Y-%m-%d %H:%M:%S').replace(tzinfo=pytz.utc)
然后,您可以在转换后再次将其删除:
return date_time_obj.astimezone(tz).replace(tzinfo=None)