我有以下代码:
import datetime
dt = 1546955400
print(datetime.datetime.fromtimestamp(dt))
当我在本地计算机上运行此代码时,我得到正确的(预期)时间,即
2019-01-08 15:50:00
。
但是我尝试在虚拟机上运行完全相同的代码,结果是
2019-01-08 13:50:00
(提前两个小时)。为什么会发生这种情况以及如何修复它,以便无论代码在哪里运行我总是得到第一个?
datetime.datetime.fromtimestamp()
返回本地时间。来自文档:
返回与 POSIX 时间戳对应的本地日期和时间,例如通过
返回。如果可选参数time.time()
为tz
或未指定,则时间戳将转换为平台的本地日期和时间,并且返回的 datetime 对象是 naive。None
时间戳值是相对于 UTC 时区 1970 年 1 月 1 日午夜的 UNIX epoch 值的偏移量(以秒为单位)。本地时间是系统范围内配置的相对于本地时区 UTC 的偏移量。
如果您的虚拟机产生意外结果,您需要配置操作系统的时区。或者,忽略时区并仅处理 UTC 时区的时间。对于时间戳,这意味着使用
datetime.datetime.utcfromtimestamp()
函数。 您的具体时间戳是 13:50 UTC:
>>> dt = 1546955400
>>> from datetime import datetime
>>> datetime.utcfromtimestamp(dt)
datetime.datetime(2019, 1, 8, 13, 50)
>>> print(_)
2019-01-08 13:50:00
因此您的虚拟机设置为 UTC 或 GMT 时区(后者当前为 UTC+0,直到切换到英国
夏令时时区 BST)。您的本地系统位于 UTC+2 时区,根据您的个人资料中指定的位置,该位置为 EEE,复活节欧洲时间。
另一个选项是通过传入tz
参数来创建时区感知时间戳。如果您有特定的 UTC 偏移量,只需为该偏移量创建一个
datetime.timezone()
实例:
utcplus2 = datetime.timezone(datetime.timedelta(hours=2))
datetime.datetime.fromtimestamp(dt, utcplus2)
但是,通常最好在各处的 UTC
datetime
实例上存储和操作,并且仅在向用户显示信息时转换为特定时区。这简化了日期时间处理,因为它可以让您避免许多时区极端情况和问题,例如混合来自不同时区和具有夏季和冬季时间区别的时区的日期时间信息。
ZoneInfo
,例如:
import re
from zoneinfo import ZoneInfo
from datetime import datetime
utc = datetime.now(ZoneInfo('UTC'))
print('Current time according to UTC:', utc)
time_stamp = utc.timestamp()
print('Current timestamp on UTC:', time_stamp)
milliseconds = re.sub(pattern=r'\.\d+', repl='000', string=str(time_stamp))
print('Current timestamp on UTC (milliseconds):', milliseconds)
from_timestamp = datetime.fromtimestamp(time_stamp, ZoneInfo('UTC'))
print('Reverse conversion timestamp to UTC time:', from_timestamp)
结果:
Current time according to UTC: 2024-09-22 16:54:40.678242+00:00
Current timestamp on UTC: 1727024080.678242
Current timestamp on UTC (milliseconds): 1727024080000
Reverse conversion timestamp to UTC time: 2024-09-22 16:54:40.678242+00:00