Python datetime 夏令时问题?

Python datetime day light saving issue?

我想知道为什么 delta 是 3601 秒,而它应该是 1 秒:

from datetime import datetime
from dateutil import tz

# Create eastern timezone
eastern = tz.gettz('America/New_York')

# 2017-03-12 01:59:59 in Eastern Time (EST)
spring_ahead_159am = datetime(2017, 3, 12, 1, 59, 59, tzinfo = eastern)

# 2017-03-12 03:00:00 in Eastern Time (EDT)
spring_ahead_3am = datetime(2017, 3, 12, 3, 0, 0, tzinfo = eastern)

(spring_ahead_3am - spring_ahead_159am).seconds
3601

请解释我做错了什么?为什么它不给我 1 秒的差异?

P.S:

请解释为什么这样做很容易: 让:

EST = timezone(timedelta(hours=-5))
EDT = timezone(timedelta(hours=-4))

spring_ahead_159am = datetime(2017, 3, 12, 1, 59, 59, tzinfo = EST)
spring_ahead_3am = datetime(2017, 3, 12, 3, 0, 0, tzinfo = EDT)
    
(spring_ahead_3am - spring_ahead_159am).seconds
1

这是日期时间对象的一个​​小怪癖。引用文档:

  1. 仅当两个操作数都是朴素的或两者都知道时,才定义从日期时间减去日期时间。如果一个知道而另一个天真,则会引发 TypeError。

    如果两者都是幼稚的,或者两者都知道并具有相同的 tzinfo 属性,则忽略 tzinfo 属性,结果是一个 timedelta 对象 t,使得 datetime2 + t == datetime1。在这种情况下没有进行时区调整。

你一定可以通过减去他们的 DST 组件得到你想要的:

>>> spring_ahead_3am - spring_ahead_3am.dst() - spring_ahead_159am + spring_ahead_159am.dst()
datetime.timedelta(seconds=1)

更新

考虑使用此功能,它可以跨时区和 DST 更改执行正确的操作:

def datesub( dt1, dt2 ):
    return datetime.timedelta( seconds=dt2.timestamp()-dt1.timestamp() )