Из часового пояса и времени UTC получите разницу в секундах по местному времени в этот момент времени
Это должно быть очень просто, но я не могу понять это на Python.
Я хочу иметь функцию, которая принимает два аргумента, время UTC в секундах и имя зоныinfo, например "Европа/Вена" , и возвращает смещение в секунд от локального времени и UTC для этого момента времени.
В C это будет:
/* ... code to to set local time to the time zone I want to compare against,
not shown here. Then call function below to get difference vs localtime.
Hardly an ideal solution,
but just to demonstrate what I want in a "lingua franca" (C): */
int get_diff_vs_localtime(const time_t original_utc_time)
{
struct tm* ts;
ts = localtime(&original_utc_time);
return mktime(ts) - original_utc_time;
}
Я думаю, мой вопрос действительно сводится к: "учитывая часовой пояс Olson (пример" Европа/Стокгольм") и время UTC, что является местным временем?
Ответы
Ответ 1
Предполагая "время UTC в секундах" означает временную метку POSIX. Чтобы преобразовать его в Стокгольмское время:
from datetime import datetime
import pytz
tz = pytz.timezone('Europe/Stockholm')
utc_dt = datetime.utcfromtimestamp(posix_timestamp).replace(tzinfo=pytz.utc)
dt = tz.normalize(utc_dt.astimezone(tz))
print(dt.strftime('%Y-%m-%d %H:%M:%S %Z%z'))
tz.normalize()
не требуется, если исходный часовой пояс UTC (как в этом случае).
Более простой альтернативой является использование параметра fromtimestamp()
tz
для преобразования "секунд с эпохи" в локальное время:
from datetime import datetime
import pytz
tz = pytz.timezone('Europe/Stockholm')
dt = datetime.fromtimestamp(posix_timestamp, tz)
print(dt.strftime('%Y-%m-%d %H:%M:%S %Z%z'))
Оба примера дают одинаковый результат.
Если локальная машина использует "правильные" часовые пояса, то для преобразования временной метки POSIX, полученной от внешнего источника в UTC, можно использовать явную формулу:
from datetime import datetime, timedelta
import pytz
utc_dt = datetime(1970, 1, 1, tzinfo=pytz.utc) + timedelta(seconds=posix_timestamp)
Последняя формула может также поддерживать более широкий диапазон дат (менее вероятные проблемы с датами до 1970 года, после 2038 или 3000 лет).
Если временная метка исходит от локального "правильного" источника, тогда вместо этого следует использовать первые два примера (они называются "right" time.gmtime()
).
Ответ 2
Вы можете использовать pytz и datetime сделать что-то таким образом:
from datetime import datetime
from pytz import timezone
def get_diff(now, tzname):
tz = timezone(tzname)
utc = timezone('UTC')
utc.localize(datetime.now())
delta = utc.localize(now) - tz.localize(now)
return delta
Что для следующего примера...
now = datetime.utcnow()
print(now)
tzname = 'Europe/Stockholm'
delta = get_diff(now, tzname)
print(delta)
now_in_stockholm = now + delta
print(now_in_stockholm)
... выходы:
2012-10-02 14:38:56.547475
2:00:00
2012-10-02 16:38:56.547475
Ответ 3
Я думаю, мой вопрос действительно сводится к: "учитывая часовой пояс Олсона (пример" Европа/Стокгольм") и время UTC, каково местное время?
Если я правильно понимаю вашу проблему:
from pytz import timezone
import datetime, time
tz = timezone('Asia/Kuwait')
utc_dt = datetime.datetime.utcfromtimestamp(time.time())
utc_dt + tz.utcoffset(utc_dt)
>>> tz.utcoffset(utc_dt).seconds
10800
>>> tz
<DstTzInfo 'Asia/Kuwait' LMT+3:12:00 STD>
>>> utc_dt + tz.utcoffset(utc_dt)
datetime.datetime(2012, 10, 2, 17, 13, 53, 504322)
>>> utc_dt
datetime.datetime(2012, 10, 2, 14, 13, 53, 504322)
Ответ 4
Это довольно старый, но я не мог найти отличный ответ, поэтому вот что я придумал:
from datetime import datetime
local = datetime.now()
utc = datetime.utcnow()
int((local - utc).days * 86400 + round((local - utc).seconds, -1))
Возвращает:
-21600
потому что я (сейчас) 21600 секунд (6 часов) позади UTC.
Примечание: вторая дата, рассчитанная (в этом случае UTC), должна быть округлена, так как при каждом расчете есть очень маленькая разница во времени.