【问题标题】:Is there an easy way to get the current time difference between the current timezone and UTC in Python?有没有一种简单的方法可以在 Python 中获取当前时区和 UTC 之间的当前时差?
【发布时间】:2013-10-10 06:55:44
【问题描述】:

我的目的只是输出一个时区字符串,如电子邮件中使用的 -0700。具体来说,我希望它反映确切的时区,包括夏令时。这意味着我会在夏天在加利福尼亚得到 -0700,冬天在加利福尼亚得到 -0800,在中国总是得到 +0800(没有夏令时)。

我觉得很难有两个原因:

  1. Python 整数除法与 C99 和普通 C/C++ 实现不同,总是朝下舍入而不是零。 (这对于涉及像 -xx30 这样的时区的计算很重要)。
  2. struct_time.tm_isdst 和 time.daylight 不反映夏令时是否生效。

我最终得到了如下代码。它比我预期的要长(尤其是 Python!):

import math
import time

def my_divide(dividend, divisor):
    if dividend < 0:
        if divisor < 0:
            diff_sign = False
        else:
            diff_sign = True
    else:
        if divisor >= 0:
            diff_sign = False
        else:
            diff_sign = True
    if diff_sign:
        return (int(math.ceil(1.0 * dividend / divisor)), dividend % -divisor)
    else:
        return (int(math.floor(1.0 * dividend / divisor)), dividend % divisor)

def my_timezone():
    gt = time.gmtime()
    lt = time.localtime()
    lt_write = list(lt)
    lt_write[8] = 0  # is_dst
    lt = time.struct_time(lt_write)
    seconds = time.mktime(lt) - time.mktime(gt)
    (hours, minutes) = my_divide(seconds, 3600)
    minutes = abs(minutes) // 60
    return '%(hours)+03d%(minutes)02d' % {'hours': hours, 'minutes': minutes}

谁有更好的实现?

【问题讨论】:

  • 使用 datetime 和 pytz pytz.sourceforge.net
  • @monkut:对于只是当前机器时区偏移量,这是矫枉过正。
  • @Martjin:我想我在测试struct_time 时犯了一个错误。这实际上是我现在建议的解决方案。
  • 谢谢,我不知道time 知道夏令时。

标签: python timezone timezone-offset


【解决方案1】:

您可以使用time.timezonetime.altzone 值。

这些提供:

本地(非 DST)时区的偏移量,以 UTC 以西的秒数为单位(西欧大部分地区为负,美国为正,英国为零)

本地 DST 时区的偏移量,以 UTC 以西的秒数(如果已定义)。如果当地 DST 时区在 UTC 以东(如在西欧,包括英国),则这是负数。仅在 daylight 非零时使用。

正如time.altzone 的文档所解释的那样,当time.daylight 不为零时使用后者,但前提是当前时间是夏令时:

import time

def my_timezone():
    is_dst = time.daylight and time.localtime().tm_isdst
    offset = time.altzone if is_dst else time.timezone
    westerly = offset > 0
    minutes, seconds = divmod(abs(offset), 60)
    hours, minutes = divmod(minutes, 60)
    return '{}{:02d}{:02d}'.format('-' if westerly else '+', hours, minutes)

以秒为基数,divmod() 此处不应出现舍入错误。

对于我的英国夏季位置,这给出了:

>>> my_timezone()
'+0100'

【讨论】:

  • time.daylight 是一个问题(继承自 C)。它全年都不会改变。 IE。即使在冬天你也会得到+0100。不过还是谢谢。
  • 如果您将time.daylight 替换为time.localtime().tm_isdst,您的方法确实有效。请您更新您的答案以便我标记它吗?
  • @Martjin:根据单一 Unix 规范,“如果夏令时转换永远不应用于正在使用的时区,则 tzset() 函数还将外部变量日光设置为 0;否则非-零。” pubs.opengroup.org/onlinepubs/7908799/xsh/tzset.html
  • @Martjin:那我们同意了吗?我实际上是在争论我们应该使用struct_time.tm_isdst,而不是使用time.daylight。您的代码目前使用后者。
  • @YongweiWu:现在我们来到了困惑所在,事实证明我在这一点上是错误的。 :-D
猜你喜欢
  • 2014-04-15
  • 1970-01-01
  • 2015-11-27
  • 2017-05-31
  • 2011-01-07
  • 2010-10-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多