在Python中,是否有一种简单的方法可以获取当前时区和UTC之间的当前时差?

在Python中,是否有一种简单的方法可以获取当前时区和UTC之间的当前时差?,python,timezone,timezone-offset,Python,Timezone,Timezone Offset,我的目的只是输出一个时区字符串,如电子邮件中使用的-0700。具体来说,我希望它能反映出准确的时区,包括夏令时。这意味着我将在加利福尼亚州夏季得到-0700,在加利福尼亚州冬季得到-0800,在中国总是+0800(无夏令时) 我觉得很难做到这一点有两个原因: Python整数除法与C99和普通C/C++实现不同,它总是向底部舍入,而不是向零舍入。(这对于涉及时区(如-xx30)的计算很重要) struct_time.tm_isdst和time.daylight不反映夏令时是否生效 我最终得到了如

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

我觉得很难做到这一点有两个原因:

  • Python整数除法与C99和普通C/C++实现不同,它总是向底部舍入,而不是向零舍入。(这对于涉及时区(如-xx30)的计算很重要)
  • struct_time.tm_isdst和time.daylight不反映夏令时是否生效
  • 我最终得到了如下代码。它比我预期的要长(尤其是Python!):

    导入数学
    导入时间
    定义我的除数(除数、除数):
    如果股息<0:
    如果除数小于0:
    差异符号=假
    其他:
    差异符号=真
    其他:
    如果除数>=0:
    差异符号=假
    其他:
    差异符号=真
    如果差异符号:
    收益率(整数(数学单元(1.0*被除数/除数)),被除数%-除数)
    其他:
    回报率(整数(数学下限(1.0*股息/除数)),股息/除数百分比)
    定义my_时区():
    gt=time.gmtime()
    lt=time.localtime()
    lt_write=列表(lt)
    lt_write[8]=0#is#dst
    lt=time.struct\u time(lt\u write)
    秒=time.mktime(lt)-time.mktime(gt)
    (小时,分钟)=我的除以(秒,3600)
    分钟=abs(分钟)//60
    返回“%”(小时)+03d%(分钟)02d“{hours':hours,'minutes':minutes}
    
    有谁有更好的实现吗?

    您可以使用和值

    这些条款规定:

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

    本地DST时区的偏移量,以UTC以西的秒为单位(如果已定义)。如果本地DST时区位于UTC东部(如西欧,包括英国),则为负值。仅当日光为非零时使用此选项

    正如
    time.altzone
    的文档所解释的,在非零时使用后者,但仅当当前时间为夏季时:

    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'
    

    使用datetime和pytz@monkut:仅用于当前机器时区偏移量,这太过分了。@Martjin:我想我在测试
    struct\u time
    时犯了一个错误。这实际上是我现在建议的解决方案。谢谢,我没有意识到
    time
    是dst感知的。
    time.daylight
    是一个问题(继承自C)。全年都不会改变。也就是说,即使在冬天你也会得到+0100。不过还是要谢谢你。如果你用
    time.localtime().tm_isdst
    替换
    time.daylight
    ,你的方法实际上是有效的。请更新您的答案,以便我标记它好吗?@Martjin:根据单一Unix规范,“如果在使用中的时区永远不应用夏令时转换,则tzset()函数还将外部变量daylight设置为0;否则为非零。”@Martjin:那么我们同意了吗?我实际上是在争论我们应该使用
    struct\u time.tm\u isdst
    ,而不是使用
    time.daylight
    。您的代码目前使用的是后者。@YongweiWu:现在我们到了混淆的地方,结果证明我在这一点上错了-D
    >>> my_timezone()
    '+0100'