Есть ли простой способ получить текущую разницу во времени между текущим часовым поясом и UTC в Python?

Моя цель - просто вывести строку часового пояса, например -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}

У кого-нибудь есть лучшая реализация?

1 ответ

Решение

Вы можете использовать time.timezone а также time.altzone ценности.

Они обеспечивают:

Смещение местного (не летнего) часового пояса, в секундах к западу от 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'
Другие вопросы по тегам