在Python中获取计算机的UTC偏移量

73
在Python中,如何找到计算机设置的UTC时间偏移量?
10个回答

109

time.timezone:

import time

print -time.timezone

它打印出UTC偏移量(为考虑夏令时,请参见time.altzone)的秒数:

is_dst = time.daylight and time.localtime().tm_isdst > 0
utc_offset = - (time.altzone if is_dst else time.timezone)

UTC偏移量的定义方式为:“要获取本地时间,请将UTC偏移量添加到UTC时间中。”

在Python 3.3+中,如果基础C库支持,则存在tm_gmtoff属性

utc_offset = time.localtime().tm_gmtoff

注意:在某些边缘情况下,time.daylight可能会给出错误的结果。
如果Python 3.3+上可用,tm_gmtoff将自动被datetime使用:
from datetime import datetime, timedelta, timezone

d = datetime.now(timezone.utc).astimezone()
utc_offset = d.utcoffset() // timedelta(seconds=1)

为了获取当前UTC偏移量并解决time.daylight问题,即使tm_gmtoff不可用,可以使用@jts的建议来减去本地时间和UTC时间:

import time
from datetime import datetime

ts = time.time()
utc_offset = (datetime.fromtimestamp(ts) -
              datetime.utcfromtimestamp(ts)).total_seconds()

为了获取过去/未来日期的UTC偏移量,可以使用“pytz”时区:
from datetime import datetime
from tzlocal import get_localzone # $ pip install tzlocal

tz = get_localzone() # local timezone 
d = datetime.now(tz) # or some other local date 
utc_offset = d.utcoffset().total_seconds()

它在夏令时转换期间工作,即使本地时区在过去/未来的日期有不同的UTC偏移量也能正常工作,例如,在2010-2015年期间的Europe/Moscow时区。

3
很好,干净整洁。 - Rockallite
1
非常有帮助。谢谢,J.F. - Ivan X
1
@mattst total_seconds() 函数可在 Python 2.7 中使用,而且可以在之前的 Python 版本中轻松模拟它 - jfs
难以置信Python没有utc2local(...)local2utc(...)。很高兴@jfs来拯救!点赞! - RayLuo
1
@RayLuo 这取决于您的具体意思。这是一个 utc2local 的实现 - jfs
显示剩余6条评论

34

gmtime()函数将返回UTC时间,而localtime()函数将返回本地时间,因此两者相减应该给出UTC偏移量。

引自https://pubs.opengroup.org/onlinepubs/009695399/functions/gmtime.html

gmtime()函数应将指向计时器指定的自纪元以来的秒数的时间转换为分解时间,表示为协调世界时(UTC)。

因此,尽管名称为gmtime(),该函数返回UTC时间。


4
将它们相减会出现 TypeError:不支持的操作数类型:'-:'time.struct_time'和'time.struct_time'。您实际上想表达什么? - rakslice
5
rakslice,尝试一下: calendar.timegm(time.gmtime()) - calendar.timegm(time.localtime()) - Casey Perkins
8
@JasonTyler 提供了一个避免时区问题的方法:t = localtime(); timegm(t) - timegm(gmtime(mktime(t)))。请注意,这个方法不改变原始含义,只是更易于理解。 - jfs
1
@Kirby:gmtime()始终返回UTC。虽然有时候GMT!=UTC,但这不是这种情况。 - jfs
1
@Kirby - GMT是一个时区,而UTC是一个时间标准。此外,无论是UTC还是GMT都不会因为夏令时(DST)而改变。(然而,一些使用GMT的国家在夏令时期间会切换到不同的时区) - EvgenyKolyakov
显示剩余2条评论

6

我喜欢:

>>> strftime('%z')
'-0700'

我先尝试了JTS的答案,但是结果是错误的。现在我处于-0700时区,但是它告诉我我在-0800时区。不过在做减法之前,我必须进行一些转换,所以也许这个答案比错误更加不完整。


2
'%z' 在 Python 中不被支持(在某些系统上可能有效,您可以使用 time.localtime().tm_gmtoff 代替,以获取 UTC 偏移量作为数字而不是字符串)。结果('%z')应与 @jts 的答案相同。如果您有不同的看法,请包含您的代码。 - jfs
import timetime0 = time.time() utc_time = time.mktime(time.gmtime(time0)) local_time = time.mktime(time.localtime(time0)) offset = local_time - utc_time print(offset / (60 * 60)) 输出结果为 -8。 - dstromberg
1
  1. 不要把代码放在评论里,请更新您的答案。
  2. 在这里使用mktime()是不正确的,请使用calendar.timegm()datetime()来找到差异。
- jfs
2
@dstromberg 我认为这是最好的方法)我喜欢它!我的解决方案是:int(datetime.now().astimezone().strftime("%z")[0:3]) - storenth

3

时间模块中有一个时区偏移量,以“UTC西部秒数”的整数形式给出。

import time
time.timezone

3
这不包括夏令时调整。 - dspeyer

3
您可以使用datetimedateutil库将偏移量作为timedelta对象获取:
>>> from datetime import datetime
>>> from dateutil.tz import tzlocal
>>>
>>> # From a datetime object
>>> current_time = datetime.now(tzlocal())
>>> current_time.utcoffset()
datetime.timedelta(seconds=7200)
>>> current_time.dst()
datetime.timedelta(seconds=3600)
>>>
>>> # From a tzlocal object
>>> time_zone = tzlocal()
>>> time_zone.utcoffset(datetime.now())
datetime.timedelta(seconds=7200)
>>> time_zone.dst(datetime.now())
datetime.timedelta(seconds=3600)
>>>
>>> print('Your UTC offset is {:+g}'.format(current_time.utcoffset().total_seconds()/3600))
Your UTC offset is +2

1
hours_delta = (time.mktime(time.localtime()) - time.mktime(time.gmtime())) / 60 / 60

GMT不等于UTC。GMT有夏令时,而UTC没有。 - Kirby
1
实际上,GMT与UTC是相同的。在英国,我们采用英国夏令时(BST)来进行夏令时调整。例如可以参考 https://greenwichmeantime.com/what-is-gmt/ ,其中写道“ GMT(夏令时永不适用)”。 - IpsRich

0

创建带有UTC校正时区的Unix时间戳

这个简单的函数将使您轻松地从MySQL/PostgreSQL数据库的date对象中获取当前时间。

def timestamp(date='2018-05-01'):
    return int(time.mktime(
        datetime.datetime.strptime( date, "%Y-%m-%d" ).timetuple()
    )) + int(time.strftime('%z')) * 6 * 6

示例输出

>>> timestamp('2018-05-01')
1525132800
>>> timestamp('2018-06-01')
1527811200

0
对我起作用的是这样做的:
timezone_offset = (datetime.now(tz(DESIRED_TIMEZONE)).utcoffset().total_seconds()) / 3600

通过这种方式,我能够获取任意时区的UTC偏移量,而不仅仅是机器的时区(可能是一个配置错误的虚拟机)。

-1

这里是一些Python3代码,只导入了datetime和time模块。希望对你有所帮助。

>>> from datetime import datetime
>>> import time
>>> def date2iso(thedate):
...     strdate = thedate.strftime("%Y-%m-%dT%H:%M:%S")
...     minute = (time.localtime().tm_gmtoff / 60) % 60
...     hour = ((time.localtime().tm_gmtoff / 60) - minute) / 60
...     utcoffset = "%.2d%.2d" %(hour, minute)
...     if utcoffset[0] != '-':
...         utcoffset = '+' + utcoffset
...     return strdate + utcoffset
... 
>>> date2iso(datetime.fromtimestamp(time.time()))
'2015-04-06T23:56:30-0400'

-4
这对我有效:
if time.daylight > 0:
        return time.altzone
    else:
        return time.timezone

在我的答案中类似的代码中,[time.localtime().tm_isdst > 0]是不正确的。 - jfs
抱歉,您的帖子太长且详细,以至于我没有理解它是相同的答案。我的帖子肯定是相同解决方案的简短版本。 - Alecs
1
不,代码是错误的。time.daylight并不表示当前是否处于夏令时。它只表示当地时间可能有夏令时调整。这就是为什么你需要调用time.localtime().tm_isdst的原因。 - jfs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接