如何在python中将时间戳转换为具有正确时区的datetime?

2024-05-15 22:24:38 发布

您现在位置:Python中文网/ 问答频道 /正文

你会天真地期望这会奏效:

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转换为11月19日星期三16:51:00 GMT+8:00。在

……但事实并非如此。它打印:

^{pr2}$

澳大利亚/珀斯的时区不是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).

那么,派兹到底从哪里拉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也是。在

奥尔森时间数据库充满了像(4小时15分钟,5小时20分钟,等等)这样的值。真奇怪。在

从技术上讲,我不在乎确切的时区是什么,只要它是普遍一致的;不幸的是,它不是。对于时区(例如,在处理时区时,正确地将时区转换为8)和服务之间的差异(示例)。在

也就是说,当转换为UTC时,这两个值是不同的时间

  • 2014年11月19日星期三16:51:00 GMT+8:00
  • 2014年11月19日星期三16:51:00 GMT+7:43

令人恼火的是:

server_time = datetime.utcnow()
delta = tz.utcoffset(server_time)
print(delta)

产量:

8:00:00

所以很明显pytz内部知道正确的时区偏移量。它只是生成附加错误值的输出。在

最后,我要如何生成一个附加了正确时区的datetime?在


Tags: fromonlydatetimeservertimeruletimestampmar
1条回答
网友
1楼 · 发布于 2024-05-15 22:24:38

长话短说,pytz默认为错误的时区,并且日期时间.替换()不执行转换:

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中的各种Bug中了解更多关于这一点的内容,其中讨论了:

相关问题 更多 >