Форматировать timedelta как строку смещения часового пояса

В качестве входных данных у меня есть две строки временных меток: одна — местное время, другая — тот же момент времени UTC. Я хочу получить разницу между ними (в основном, чтобы получить смещение местного часового пояса) в виде строки в определенном формате, например. +1100 или -0500.

import datetime

local = '2018-01-31 18:34:42.172'

utc = '2018-01-31 23:34:42.172'

local_dt = datetime.datetime.strptime(local, '%Y-%m-%d %H:%M:%S.%f')

utc_dt = datetime.datetime.strptime(utc, '%Y-%m-%d %H:%M:%S.%f')

offset_timedelta = local_dt - utc_dt

offset = offset_timedelta.total_seconds() / 3600

offset
Out[8]: -5.0

Используя timedelta, я могу получить смещение как float (например, -5.0 выше). Оттуда я, вероятно, могу создать функцию для преобразования этого числа с плавающей запятой в строку в нужном мне формате, но мне любопытно, есть ли какой-либо метод datetime/timedelta или форматирование, которое мне не хватает, или какой-либо строковый формат, который выполнял бы работу с более чистым кодом и более эффективным.

Любая помощь будет оценена по достоинству.

отредактируйте, так как я вижу, что мой вопрос не ясен: есть ли способ получить «-0500», который мне нужен (строка в этом конкретном формате, а не с плавающей запятой), либо с помощью библиотеки даты и времени, либо с помощью форматирования строки?


person rstk    schedule 03.02.2018    source источник
comment
Добавьте его в функцию, если хотите очистить свой код!   -  person Alex    schedule 04.02.2018


Ответы (1)


На самом деле вы уже сделали всю работу. Но вы можете использовать модуль dateutil, чтобы скрыть беспорядочные детали:

>>> local = '2018-01-31 18:34:42.172'
>>> utc = '2018-01-31 23:34:42.172'

>>> from dateutil import parser, relativedelta
>>> tzh=relativedelta.relativedelta(parser.parse(local), parser.parse(utc))
>>> tzh
relativedelta(hours=-5)

Чтобы отформатировать его так, как вы хотите:

>>> f"{tzh.hours:+03d}{abs(tzh.minutes):02d}"
'-0500'

Или Python с 2.6 по 3.5:

>>> "{hours:+03d}{minutes:02d}".format(hours=tzh.hours, minutes=abs(tzh.minutes))
'-0500'

Модуля dateutil нет в стандартной библиотеке, но его стоит скачать. Он может сделать гораздо больше, чем это.

person BoarGules    schedule 03.02.2018
comment
Я сделал большую часть работы, но не всю, так как моя проблема состоит в том, чтобы получить смещение в виде строки в определенном формате :) Я отредактировал свой пост, так как вопрос явно не ясен: есть ли способ получить -0500 I нужно (строка в этом конкретном формате, а не с плавающей запятой), либо с помощью библиотеки datetime, либо с форматированием строки? Спасибо за подсказку dateutil, обязательно проверю! - person rstk; 04.02.2018
comment
@rstk: немного расширил ответ. Сначала я не понял, что вопрос был в форматировании. Что показывает, что я не прочитал его достаточно внимательно. - person BoarGules; 04.02.2018
comment
спасибо за обновление, это помогло, я использовал подобное форматирование в своем коде и получил тот же результат. Теперь проблема с этим решением заключается в том, что оно отлично работает только с часовыми поясами, которые указаны в час. Есть некоторые часовые пояса, которые находятся на 30 или 45 минут. Если смещение равно -3:30, мы получим -0350, а не -0330. Вот почему я задался вопросом, может быть, есть какой-то трюк с датой и временем или другое форматирование, которое правильно справляется с этим. - person rstk; 04.02.2018
comment
Теперь я вижу, что вы тем временем снова отредактировали его, вы тоже поняли проблему. :) Но для отрицательного некруглого часового пояса все равно не годится (получил -04-30, а не -0430). - person rstk; 04.02.2018
comment
Совершенно верно, я тестировал его только со смещением на восток от UTC. Я забыл о Ньюфаундленде (хотя я думал, что это -0330, а не -0430). Исправлено сейчас. Использование abs(minutes) безопасно, потому что в этом случае знак часов и минут всегда будет совпадать. - person BoarGules; 04.02.2018