Как преобразовать дату и время формата ГГГГ-ММ-DDThh: мм: ssTZD в дату и время UTC?

#python #string #datetime

#python #строка #дата и время

Вопрос:

У меня есть строка формата YYYY-MM-DDThh:mm:ssTZD , где TZD есть -hh:mm или hh:mm . Пример: 2020-09-18T10:27:29-07:00 . Как я могу преобразовать это в дату и время UTC в python?

2020-09-18T10:27:29-07:00 это местное время. Я хочу преобразовать все местное время в дату и время UTC.

Что я пробовал :

 time = "2020-09-18T10:27:29-07:00"
datetime.fromisoformat(time).utcnow()
 

Похоже, это не работает

Комментарии:

1. Из модуля datetime импортируйте часовой пояс, затем вы можете преобразовать, как datetime.fromisoformat(t).astimezone(timezone.utc)

2. Это не работает. Если вы преобразуете время, указанное выше, в UTC оно все равно должно быть 2020-09-18T10:27:29. Но ваш способ дает UTC 7.

3. Вы имеете в виду, что это работает не так, как вы ожидаете ? — 10 часов при UTC-7 равно 17 часам при UTC 0, именно так работают смещения UTC.

4. Извините, то, что вы сделали, было правильным. Учитывает ли это сохранение в дневное время?

Ответ №1:

Как преобразовать?

Чтобы преобразовать временную метку со смещением UTC в UTC (смещение = 0), используйте

 from datetime import datetime, timezone

t = "2020-09-18T10:27:29-07:00"
t_UTC = datetime.fromisoformat(t).astimezone(timezone.utc)
# datetime.datetime(2020, 9, 18, 17, 27, 29, tzinfo=datetime.timezone.utc)
 

Как насчет переходов в летнее время?

Переходы на летнее время представлены в смещении UTC. Например, для часового пояса Америка / Лос-Анджелес переход в летнее время будет выглядеть так

 "2020-03-08T00:00:00-08:00"
"2020-03-08T01:00:00-08:00"
"2020-03-08T03:00:00-07:00"
"2020-03-08T04:00:00-07:00"
 

Используя приведенный выше код для преобразования в UTC, временные метки будут отображаться как

 "2020-03-08T08:00:00 00:00"
"2020-03-08T09:00:00 00:00"
"2020-03-08T10:00:00 00:00"
"2020-03-08T11:00:00 00:00"
 

Как я могу вернуть исходное смещение UTC?

Это означает преобразование UTC во время в определенном часовом поясе — так что для этого вам понадобится часовой пояс, особенно для обработки переходов в летнее время. Пример:

 from zoneinfo import ZoneInfo # Python 3.9; for Python <3.9 use dateutil.tz.gettz
    
l = ["2020-03-08T08:00:00 00:00", "2020-03-08T09:00:00 00:00",
     "2020-03-08T10:00:00 00:00", "2020-03-08T11:00:00 00:00"]

for t in l:
    print(datetime.fromisoformat(t).astimezone(ZoneInfo('America/Los_Angeles')))
    
2020-03-08 00:00:00-08:00
2020-03-08 01:00:00-08:00
2020-03-08 03:00:00-07:00
2020-03-08 04:00:00-07:00 
 

Ответ №2:

Пакет python python-dateutil сделает свое дело (документы):

 
from dateutil import parser

time = "2020-09-18T10:27:29-07:00"
result = parser.isoparse(time)

 

Установите dateutil с помощью

 pip install python-dateutil
 

Комментарии:

1. Он возвращает datetime.datetime(2020, 9, 18, 10, 27, 29, tzinfo=tzoffset(None, -25200)) , что я понимаю, что такое tzinfo здесь.

2. tzinfo смещен ли часовой пояс от UTC в секундах

3. Стандартная библиотека Python уже делает это эффективно, нет необходимости в сторонней библиотеке. Кроме того, OP хочет конвертировать, а не просто анализировать.

Ответ №3:

К сожалению, мой компьютер не смог найти версию dateutil для установки, чтобы проверить предыдущий ответ. Вот способ внедрения нового часового пояса в строку времени (ISO 8601) на Python, но его можно распространить и на другие языки (просто измените синтаксис). И я также извлекаю дату и время (с компьютера), вместо того, чтобы просто вводить строку. Затем преобразуйте его. Это особенно полезно для погодных, новостных, биржевых / криптографических API, где вы можете очень быстро собирать большое количество данных. Теперь вы можете преобразовать их время в гораздо более понятный формат. Нажмите здесь, чтобы ознакомиться с 50 наиболее популярными API из rapidapi.com

 import datetime#this library has the commands, you need to install the library if your compiler can't find it (pip install datetime or pip3 install datetime)
    
dt=datetime.datetime.utcnow().isoformat()
#dt = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S")#already in correct timezone
dt ='Z'#ADD A Z TO THE END FOR CORRECT ISO 8601
dt=dt[:19]#cut the string down to the minimum requirements

print(dt '  UTC  (ISO 8601 format)')

tiz=float(dt[11] dt[12])#hour is the 11th and 12th characters in this string
tiz-=8#Pacific Standard Time is UTC-8 (put  = if it's ahead instead of -=)
if tiz>23:#upper limit for hours is 23
    tiz-=24
else:
    if tiz<0:#lower limit for hours is 0
        tiz =24
tiz=int(tiz)
if tiz<10:
    #tiz=' ' str(tiz)#easier to read the hour w/out leading zero
    tiz='0' str(tiz)#leading zero necessary for ISO 8601
#print(tiz)#check the hour change because of the timezone
dt=dt[:11] tiz dt[13:]#replace the hour

print(dt '  UTC-8  (ISO 8601 format) Easier to read hour when summed with timezone already')

print('on ' dt[5:8] dt[8:10] '-' dt[0:4] ' (M-D-Y) at ' dt[11:19] ' (H:M:S)' '  UTC-8  Easier to distinguish month and day!')

if dt[7:9]=='01' or dt[7:9]==' 1':#ordinal numbers for days
    da='st'
else:
    if dt[7:9] == '02' or dt[7:9] == ' 2':
        da = 'nd'
    else:
        if dt[7:9] == '03' or dt[7:9] == ' 3':
            da = 'rd'
        else:
            da = 'th'
dtm=['Jan','Feb','Mrc','Apr','May','Jun','Jly','Aug','Sep','Oct','Nov','Dec']
dt=dt[0:5] dtm[(int(dt[5:7])-1)] dt[8:19]# convert month # to name

print('on ' dt[5:8] '-' dt[8:10] da '-' dt[0:4] ' at ' dt[11:20] '  UTC-8  Even easier to distinguish month and day!')#EASIER TO READ!
 

Вывод:
2020-12-25T02:33:04Z UTC (формат ISO 8601)
2020-12-25T18:33:04Z UTC-8 (формат ISO 8601) Легче читать час, когда суммируется с часовым поясом уже
12-25-2020 (M-D-Y) в 18:33:04 (H: M: S) UTC-8 Легче различать месяц и день!
25 декабря 2020 года в 18:33:04 UTC-8 Еще проще различать месяц и день!