你会天真地期望这样做:
import pytz
from datetime import datetime
def tz_datetime_from_timestamp(timestamp):
"""Convert a timestamp into a datetime """
tz = pytz.timezone('Australia/Perth')
server_time = datetime.utcnow()
delta = tz.utcoffset(server_time)
value = datetime.utcfromtimestamp(timestamp).replace(tzinfo=tz)
return value + delta
print tz_datetime_from_timestamp(1416387060)
并将时间戳1416387060转换为Wed Nov 19 16:51:00 GMT + 8:00。
......但事实并非如此。它打印:
2014-11-19 16:51:00+07:43
澳大利亚/珀斯的时区不是GMT + 7:43。
GMT + 8:00。澳大利亚政府网站http://www.australia.gov.au/about-australia/our-country/time明确说明了这一点:
AWST is equal to Coordinated Universal Time plus 8 hours (UTC +8).
那么,哪里是pytz从7.43拉?
嗯,事实证明,pytz从http://www.iana.org/time-zones时区数据库中提取数据,该数据库说明:
# Western Australia
#
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule AW 1974 only - Oct lastSun 2:00s 1:00 D
Rule AW 1975 only - Mar Sun>=1 2:00s 0 S
Rule AW 1983 only - Oct lastSun 2:00s 1:00 D
Rule AW 1984 only - Mar Sun>=1 2:00s 0 S
Rule AW 1991 only - Nov 17 2:00s 1:00 D
Rule AW 1992 only - Mar Sun>=1 2:00s 0 S
Rule AW 2006 only - Dec 3 2:00s 1:00 D
Rule AW 2007 2009 - Mar lastSun 2:00s 0 S
Rule AW 2007 2008 - Oct lastSun 2:00s 1:00 D
Zone Australia/Perth 7:43:24 - LMT 1895 Dec
8:00 Aus AW%sT 1943 Jul
8:00 AW AW%sT
好。这真是太棒了....但它也不正确。
......不幸的是,python也是如此。
olson时间数据库充满了类似的值(4小时15分钟,5小时20分钟等)。非常奇怪。
从技术上讲,我并不关心确切的时区是什么,只要其普遍一致;不幸的是,事实并非如此。进行(例如)API调用并将时区传递到(正确地)使用GMT + 8时区的远程服务时,当时区转换为UTC进行处理时,会导致值之间略有差异。
即。要绝对清楚,转换为UTC时,这两个值不同的时间:
不快:
server_time = datetime.utcnow()
delta = tz.utcoffset(server_time)
print(delta)
收率:
8:00:00
很明显,pytz内部确实知道正确的时区偏移。它只是生成附加了错误值的输出。
所以,最后:如何生成附加正确时区的日期时间?
答案 0 :(得分:0)
长话短说,pytz默认为不正确的时区,而datetime.replace()不执行转换:
import pytz
from datetime import datetime
fmt = '%Y-%m-%d %H:%M:%S %Z%z'
tz = pytz.timezone('Australia/Perth')
timestamp = 1416387060
print(tz)
# Correct way
utctime = pytz.utc.localize(datetime.utcfromtimestamp(timestamp))
print(utctime.strftime(fmt))
astimezone = utctime.astimezone(tz)
print(astimezone.strftime(fmt))
localtime = tz.normalize(astimezone)
print(localtime.strftime(fmt))
# Incorrect way
incorrect = datetime.utcfromtimestamp(timestamp).replace(tzinfo=tz)
print(incorrect.strftime(fmt))
您可以在pytz中讨论的各种错误中阅读更多相关内容: