python datetime 1968年以前的时间戳错误



我发现在datetime模块中计算时间戳的一些错误。

一天的第二秒不是86400.

是bug吗?还是有其他原因?

for n in range(2,2015):
ts1=datetime.fromisoformat(str(n).zfill(4)+'-01-01T00').timestamp()
ts2=datetime.fromisoformat(str(n+1).zfill(4)+'-01-01T00').timestamp()
days=(ts2-ts1)/24./3600.
if (days == 365) or (days == 366):
jul=365
if np.mod(n,4) == 0:
jul=366
if np.mod(n,100) == 0:
jul=365
if np.mod(n,400) == 0:
jul=366
if days != jul:
print(str(n).zfill(4)+'-01-01T00',days) #-> nothing OK
else:
#print(str(n).zfill(4)+'-01-01T00',days)
for d in range(-10,370):
ts=ts1+d*24.*3600.
iso1=datetime.fromtimestamp(ts).isoformat()
iso2=datetime.fromtimestamp(ts+24.*3600.).isoformat()
if (iso1[11:] != iso2[11:]):
print(iso1,iso2,
datetime.fromisoformat(iso2).timestamp()-datetime.fromisoformat(iso1).timestamp())
--------
1889-12-31T00:00:00 1890-01-01T00:02:08 86400.0
1904-11-30T00:00:00 1904-12-01T00:30:00 86400.0
1927-12-31T00:00:00 1927-12-31T23:30:00 84600.0
1931-12-31T00:00:00 1932-01-01T00:30:00 86400.0
1954-03-20T00:00:00 1954-03-20T23:00:00 82800.0
1961-08-09T00:00:00 1961-08-10T00:30:00 86400.0
1968-09-30T00:00:00 1968-10-01T00:30:00 86400.0

这不是一个bug,这是一个特性。您正在使用朴素的datetime对象(您没有设置时区),这意味着Python将默认认为它们表示本地时间。但是,timestamp()返回UNIX时间,它指向UTC。

的例子。我的机器设置为Europe/Berlin时区,该时区在2020年3月29日进行了DST更改。

from datetime import datetime, timezone
t0, t1 = datetime.fromisoformat("2020-03-29"), datetime.fromisoformat("2020-03-30")
t1.timestamp()-t0.timestamp()
# 82800.0

如果我做同样的事情,但指定我的datetime对象应该表示UTC,一切都像你期望的那样工作:

t0 = datetime.fromisoformat("2020-03-29").replace(tzinfo=timezone.utc)
t1 = datetime.fromisoformat("2020-03-30").replace(tzinfo=timezone.utc)
t1.timestamp()-t0.timestamp()
# 86400.0

旁注:还有Python的timedelta,它会给你wall time的区别。这里,两种情况下你都会得到1天的时差

t1-t0
# datetime.timedelta(days=1)

最新更新