从日期和时区计算tm_isdst

时间:2012-11-19 12:49:58

标签: python time timezone

当我运行

time.strptime("2012-06-01 12:00:00 "+time.strftime("%Z"), "%Y-%m-%d %H:%M:%S %Z")

它为我创建了一个结构,但标志tm_isdst是错误的。在6月1日,DST处于活动状态,但无论我输入的是什么日期,tm_isdst标志始终设置为localtime()目前的状态。我需要知道DST在我输入的日期是否有效。

2 个答案:

答案 0 :(得分:2)

首先,不要在格式中加入time.strftime('%Z')。您告诉它当前的GMT偏移(包括夏令时关闭),并且[可能]使用它来设置tm_isdst。

如果没有这个,你应该得到一个tm_isdst=-1的结构:

>>> time1 = time.strptime("2012-06-01 12:00:00", "%Y-%m-%d %H:%M:%S")
>>> time1
time.struct_time(tm_year=2012, tm_mon=6, tm_mday=1, tm_hour=12, tm_min=0,
tm_sec=0, tm_wday=4, tm_yday=153, tm_isdst=-1)

现在,您可以将其传递给mktime,这将给定-1值," guess" DST值(我把"猜测"在引号中,因为它总是正确的,除了模糊的2AM情况)。这将以time()格式给出绝对时间。

>>> time.mktime([previous value]) # my timezone is US Eastern
1338566400.0

然后你可以用这个值调用localtime,它将有一个正确设置的DST标志:

>>> time.localtime(1338566400).tm_isdst
1

您也可以跳过strptime步骤并直接将值传递给mktime:

>>> time.mktime((2012,6,1,12,0,0,-1,-1,-1))
1338566400.0

答案 1 :(得分:0)

您的问题等同于如何将以字符串形式给出的本地时间转换为附加本地时区信息的本地时间:

from datetime import datetime
from pytz.exceptions import InvalidTimeError # $ pip install pytz
from tzlocal import get_localzone # $ pip install tzlocal

naive_dt = datetime.strptime("2012-06-01 12:00:00", "%Y-%m-%d %H:%M:%S")
local_tz = get_localzone()
try:
    local_dt = local_tz.localize(naive_dt, is_dst=None)
except InvalidTimeError as e:
    print("can't determine whether DST is active, reason: %s" % (e,))
else:
    assert local_dt.dst() is not None
    print("DST is %sactive" % ("" if local_dt.dst() else "not ",))

它使用Olson tz databasepytz模块),因此:

  • 适用于过去日期,因为与DST无关的原因,UTC偏移可能会有所不同。
  • 当无法确定DST时,它会检测到模糊或不存在的本地时间
  • 适用于Windows和* nix(tzlocal模块)

注意:mktime()-based solution shown in @Random832'a answer

import time

isdst = time.localtime(time.mktime(naive_dt.timetuple())).tm_isdst > 0
  • 如果操作系统不提供自己的历史时区数据库,它可能会默认为过去的日期提供错误的结果
  • 对于模糊或不存在的当地时间(在DST过渡期间),它可能会默默地提供错误的结果。