Есть ли простой способ получить текущую разницу во времени между текущим часовым поясом и UTC в Python?
Моя цель - просто вывести строку часового пояса, например -0700, используемую в электронной почте. В частности, я хочу, чтобы он отражал точный часовой пояс, включая летнее время. Это означает, что летом я получу -0700 в Калифорнии, -0800 в Калифорнии зимой и всегда +0800 в Китае (без перехода на летнее время).
Мне трудно по двум причинам:
- Целочисленное деление Python, в отличие от C99 и обычных реализаций C/C++, всегда округляется к полу вместо нуля. (Это имеет значение для расчетов с использованием часового пояса, например -xx30).
- 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'