<p>我逐渐地在这个答案的末尾提供了几种解决方案,这些方案试图解决以下问题:</p>
<ul>
<li>由于DST的utc偏移量</li>
<li>由于与DST无关的原因,本地时区可能具有不同的utc偏移量的过去日期。<code>dateutil</code>和stdlib解决方案在某些系统(尤其是Windows)上失败</li>
<li>DST期间的不明确时间(不知道<code>Arrow</code>是否提供了处理它的接口)</li>
<li>DST期间不存在的时间(相同)</li>
</ul>
<p>要查找给定时区中明天午夜(或其他固定时间)的POSIX时间戳,可以使用<a href="https://stackoverflow.com/q/373370/4279">How do I get the UTC time of “midnight” for a given timezone?</a>中的代码:</p>
<pre><code>from datetime import datetime, time, timedelta
import pytz
DAY = timedelta(1)
tz = pytz.timezone('America/Montreal')
tomorrow = datetime(2013, 11, 3).date() + DAY
midnight = tz.localize(datetime.combine(tomorrow, time(0, 0)), is_dst=None)
timestamp = (midnight - datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds()
</code></pre>
<p><code>dt.date()</code>方法为朴素对象和时区感知对象返回相同的初始日期<code>dt</code>。在</p>
<p>时间戳的显式公式用于支持python3.3之前的Python版本。否则,<code>.timestamp()</code>方法可以在python3.3+中使用。在</p>
<p>为了避免在DST转换期间解析输入日期时出现歧义,而这种歧义对于<code>.localize()</code>方法是不可避免的,除非您知道<code>is_dst</code>参数,您可以使用与日期一起存储的Unix时间戳:</p>
^{pr2}$
<p>要支持其他固定时间(不仅是午夜):</p>
<pre><code>tomorrow = local_dt.replace(tzinfo=None) + DAY # tomorrow, same time
dt_plus_day = tz.localize(tomorrow, is_dst=None)
timestamp = dt_plus_day.timestamp() # use the explicit formula before Python 3.3
</code></pre>
<p>如果结果日期不明确或不存在,<code>is_dst=None</code>将引发异常。为了避免出现异常,您可以选择最接近昨天的前一个日期的时间(相同的DST状态,即<code>is_dst=local_dt.dst()</code>):</p>
<pre><code>from datetime import datetime, time, timedelta
import pytz
DAY = timedelta(1)
tz = pytz.timezone('America/Montreal')
local_dt = datetime.fromtimestamp(timestamp_from_the_log, tz)
tomorrow = local_dt.replace(tzinfo=None) + DAY
dt_plus_day = tz.localize(tomorrow, is_dst=local_dt.dst())
dt_plus_day = tz.normalize(dt_plus_day) # to detect non-existent times
timestamp = (dt_plus_day - datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds()
</code></pre>
<p><code>.localize()</code>尊重给定的时间,即使它不存在,因此需要<code>.normalize()</code>来确定时间。如果<code>normalize()</code>方法更改其输入(在本例中检测到不存在的时间)以与其他代码示例保持一致,则可以在此处引发异常。在</p>