如何检查夏令时是否有效?
答案 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中实现的逻辑,尽管仍然存在问题,但是它显然在现实生活中不起作用:(
目前我在以色列,我们在月底移动时钟,
而在澳大利亚,他们已经移动了时钟。
对于True
和Asia/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=15
和 minute=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 时间的时区感知版本,以便当它本地化到指定的时区时,它代表该时区中的当前时间。