Python夏令时

时间:2010-05-21 09:45:16

标签: python time dst

如何检查夏令时是否有效?

6 个答案:

答案 0 :(得分:60)

您可以使用time.localtime并查看返回值中的tm_isdst标记。

>>> import time
>>> time.localtime()
(2010, 5, 21, 21, 48, 51, 4, 141, 0)
>>> _.tm_isdst
0

使用time.localtime(),您可以在任意时间内询问相同的问题,以查看DST是否(或之)对您当前的时区有效。

答案 1 :(得分:3)

如果您在笔记本电脑上运行代码,则可接受的答案很好,但是大多数 python应用程序在使用UTC作为本地时间的服务器上运行,因此它们 根据公认的答案,绝对不会在夏令时。

第二个问题是,不同地区在 不同的日期和时间。因此,即使您的时间很明确,例如 datetime.utcnow(),可能是一个时区的夏令时,但不是 在另一个。

那么我们能做的最好的就是告诉DST期间是否发生了给定时间 特定的时区,我可以找到的最佳方法已经 由pytz localize函数实现,我们可以使用它来获取 非常好的答案,可以在我们的笔记本电脑和服务器上使用。

import pytz

from datetime import datetime

def is_dst(dt=None, timezone="UTC"):
    if dt is None:
        dt = datetime.utcnow()
    timezone = pytz.timezone(timezone)
    timezone_aware_date = timezone.localize(dt, is_dst=None)
    return timezone_aware_date.tzinfo._dst.seconds != 0

一些例子

>>> is_dst() # it is never DST in UTC
False
>>> is_dst(datetime(2019, 1, 1), timezone="US/Pacific")
False
>>> is_dst(datetime(2019, 4, 1), timezone="US/Pacific")
True
>>> is_dst(datetime(2019, 3, 10, 2), timezone="US/Pacific")
NonExistentTimeError
>>> is_dst(datetime(2019, 11, 3, 1), timezone="US/Pacific")
AmbiguousTimeError

在我们的is_dst函数中,我们将is_dst=None指定为 timezone.localize,这将导致无聊的时间抛出错误。您 可以使用is_dst=False来忽略这些错误,并为这些错误返回False 时间。

答案 2 :(得分:0)

扩展@Greg Hewgill上面的答案,再加上当地时区(在pip install tzlocal的帮助下),你得到:

import time
from datetime import datetime, timedelta
from tzlocal import get_localzone

def to_local(dt):
    """From any timezone to local datetime - also cope with DST"""
    localtime = time.localtime()
    if localtime.tm_isdst:
        utctime = time.gmtime()
        hours_delta = timedelta(hours=(localtime.tm_hour - utctime.tm_hour))
        dt = dt - hours_delta

    return dt.replace(tzinfo=get_localzone())

答案 3 :(得分:0)

假设您要在datetime上执行此操作

使用pytz使其了解时区,然后检查其dst属性:

import datetime
import pytz

def is_dst(dt,timeZone):
   aware_dt = timeZone.localize(dt)
   return aware_dt.dst() != datetime.timedelta(0,0)

timeZone = pytz.timezone("Europe/London")

dt = datetime.datetime(2019,8,2)
is_dst(dt,timeZone)
True

dt = datetime.datetime(2019,2,2)
is_dst(dt,timeZone)
False

答案 4 :(得分:0)

以上都不对我有帮助,所以我找到了自己的解决方法。

我涉及到https://gist.github.com/dpapathanasiou/09bd2885813038d7d3eb中实现的逻辑,尽管仍然存在问题,但是它显然在现实生活中不起作用:(

目前我在以色列,我们在月底移动时钟, 而在澳大利亚,他们已经移动了时钟。 对于TrueAsia/Jerusalem,所有代码都返回Australia/Sydney

最终,我使用了外部第三方API https://worldtimeapi.org/-通过该API分析utc_offset是否为11小时(而不是10:05)。

from requests import get as Get

is_dst = True
try:
    tz_check = Get('https://worldtimeapi.org/api/timezone/Australia/Sydney')
    is_dst = tz_check.json().get('utc_offset') == '+11:00'
except Exception as e:
    print('!!! Error getting timezone', e)

我同意这是一个私人案件,但我希望这可以对某人有所帮助:)

答案 5 :(得分:0)

我会将此作为对上面@mehtunguh 回答的评论发布,但我目前的声誉级别不允许我发表评论。

我认为省略 is_dst 参数时编写的 dt 函数可能存在问题。

当省略 dt 参数时,dt 被设置为 datetime.utcnow(),它返回一个 naive 表示当前 UTC 的日期时间时间。当它传递给 pytz.localize 时,生成的本地化时间不是指定时区中的当前时间,而是具有相同小时的本地时间,分,秒,作为当前 UTC 时间。

因此,例如,当我写这篇文章时,它是美国/东部时区的美国东部时间上午 10:50,datetime.utcnow() 返回带有 hour=15minute=50 的日期时间值。正如所写的那样,当作为 is_dst(timezone='US/Eastern') 调用时,is_dst 不会检查美国东部时间上午 10:50 的当前本地时间是否在夏令时,而是检查美国东部时间下午 3:50 是否在夏令时时间。

我认为 is_dst 应该编码如下:

import datetime
import pytz

def is_dst(dt=None, timezone='UTC'):
    timezone = pytz.timezone(timezone)
    if dt is None:
        dt = datetime.datetime.now(datetime.timezone.utc)
    if dt.tzinfo is None:
        tz_aware_dt = timezone.localize(dt, is_dst=None)
    else:
        tz_aware_dt = dt.astimezone(timezone)
    return tz_aware_dt.tzinfo._dst.seconds != 0

此版本允许将 naive 日期时间值或 时区感知 日期时间值作为 { {1}} 参数。当 dt 参数被省略时,它使用当前 UTC 时间的时区感知版本,以便当它本地化到指定的时区时,它代表该时区中的当前时间。