Разбор строки даты / времени с сокращенным названием часового пояса в Python? - PullRequest
30 голосов
/ 09 ноября 2009

Я пытаюсь проанализировать строки меток времени, например "Sat, 11/01/09 8:00PM EST" в Python, но у меня возникают проблемы с поиском решения, которое будет обрабатывать сокращенный часовой пояс.

Я использую функцию dateutil parse(), но она не анализирует часовой пояс. Есть ли простой способ сделать это?

Ответы [ 5 ]

59 голосов
/ 22 января 2011

dateutil s parser.parse() принимает в качестве аргумента ключевого слова tzinfos словарь типа {'EST': -5*3600} (то есть сопоставление имени зоны со смещением по Гринвичу в секундах). Итак, предполагая, что у нас это есть, мы можем сделать:

>>> import dateutil.parser as dp
>>> s = 'Sat, 11/01/09 8:00PM'
>>> for tz_code in ('PST','PDT','MST','MDT','CST','CDT','EST','EDT'):
>>>     dt = s+' '+tz_code
>>>     print dt, '=', dp.parse(dt, tzinfos=tzd)

Sat, 11/01/09 8:00PM PST = 2009-11-01 20:00:00-08:00
Sat, 11/01/09 8:00PM PDT = 2009-11-01 20:00:00-07:00
Sat, 11/01/09 8:00PM MST = 2009-11-01 20:00:00-07:00
Sat, 11/01/09 8:00PM MDT = 2009-11-01 20:00:00-06:00
Sat, 11/01/09 8:00PM CST = 2009-11-01 20:00:00-06:00
Sat, 11/01/09 8:00PM CDT = 2009-11-01 20:00:00-05:00
Sat, 11/01/09 8:00PM EST = 2009-11-01 20:00:00-05:00
Sat, 11/01/09 8:00PM EDT = 2009-11-01 20:00:00-04:00

Что касается содержания tzinfos, вот как я заполнил мой:

tz_str = '''-12 Y
-11 X NUT SST
-10 W CKT HAST HST TAHT TKT
-9 V AKST GAMT GIT HADT HNY
-8 U AKDT CIST HAY HNP PST PT
-7 T HAP HNR MST PDT
-6 S CST EAST GALT HAR HNC MDT
-5 R CDT COT EASST ECT EST ET HAC HNE PET
-4 Q AST BOT CLT COST EDT FKT GYT HAE HNA PYT
-3 P ADT ART BRT CLST FKST GFT HAA PMST PYST SRT UYT WGT
-2 O BRST FNT PMDT UYST WGST
-1 N AZOT CVT EGT
0 Z EGST GMT UTC WET WT
1 A CET DFT WAT WEDT WEST
2 B CAT CEDT CEST EET SAST WAST
3 C EAT EEDT EEST IDT MSK
4 D AMT AZT GET GST KUYT MSD MUT RET SAMT SCT
5 E AMST AQTT AZST HMT MAWT MVT PKT TFT TJT TMT UZT YEKT
6 F ALMT BIOT BTT IOT KGT NOVT OMST YEKST
7 G CXT DAVT HOVT ICT KRAT NOVST OMSST THA WIB
8 H ACT AWST BDT BNT CAST HKT IRKT KRAST MYT PHT SGT ULAT WITA WST
9 I AWDT IRKST JST KST PWT TLT WDT WIT YAKT
10 K AEST ChST PGT VLAT YAKST YAPT
11 L AEDT LHDT MAGT NCT PONT SBT VLAST VUT
12 M ANAST ANAT FJT GILT MAGST MHT NZST PETST PETT TVT WFT
13 FJST NZDT
11.5 NFT
10.5 ACDT LHST
9.5 ACST
6.5 CCT MMT
5.75 NPT
5.5 SLT
4.5 AFT IRDT
3.5 IRST
-2.5 HAT NDT
-3.5 HNT NST NT
-4.5 HLV VET
-9.5 MART MIT'''

tzd = {}
for tz_descr in map(str.split, tz_str.split('\n')):
    tz_offset = int(float(tz_descr[0]) * 3600)
    for tz_code in tz_descr[1:]:
        tzd[tz_code] = tz_offset

пс. в соответствии с @Hank Gay название часового пояса четко не определено. Для формирования моей таблицы я использовал http://www.timeanddate.com/library/abbreviations/timezones/ и http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations. Я смотрел на каждый конфликт и разрешал конфликты между непонятными и популярными именами по отношению к популярным (более используемым). Был один - IST - который не был таким четким (это может означать Стандартное индийское время , Стандартное время Ирана , Стандартное ирландское время или Стандартное время Израиля ), поэтому я оставил его вне таблицы - вам может потребоваться выбрать, что добавить для него в зависимости от вашего местоположения. О - и я упустил Республику Кирибати с их абсурдным «посмотри на меня, я первый, чтобы праздновать Новый год» GMT + 13 и GMT + 14 часовых поясов.

11 голосов
/ 09 ноября 2009

Это, вероятно, не сработает, потому что эти сокращения не уникальны. Подробнее см. на этой странице . Возможно, вам придется самостоятельно справиться с этим вручную, если вы работаете с известным набором входов.

10 голосов
/ 23 января 2011

Вы можете попробовать модуль pytz: http://pytz.sourceforge.net/

pytz переносит базу данных Olson tz в Python. Эта библиотека позволяет точно и кроссплатформенный часовой пояс расчеты с использованием Python 2.3 или выше. Это также решает проблему неоднозначные времена в конце дневного света сбережения, о которых вы можете прочитать больше о в справочнике по библиотеке Python (Datetime.tzinfo).

Почти все часовые пояса Олсона поддерживается.

5 голосов
/ 10 ноября 2009

Функция parse () в dateutil не может обрабатывать часовые пояса. То, что я использовал, - это средство форматирования% Z и функция time.strptime (). Я понятия не имею, как она справляется с неоднозначностью в часовых поясах, но она, кажется, говорит о разнице между CDT и CST, и это все, что мне было нужно.

Справочная информация. Я храню резервные образы в каталогах, имена которых являются метками времени по местному времени, поскольку у меня дома нет часов по Гринвичу. Поэтому я использую time.strptime (d, r "% Y-% m-% dT% H:% M:% S_% Z"), чтобы проанализировать имена каталогов обратно в фактическое время для анализа возраста.

1 голос
/ 27 марта 2017

Я использовал pytz для генерации TZINFOS отображения:

from datetime import datetime as dt

import pytz

from dateutil.tz import gettz
from pytz import utc
from dateutil import parser


def gen_tzinfos():
    for zone in pytz.common_timezones:
        try:
            tzdate = pytz.timezone(zone).localize(dt.utcnow(), is_dst=None)
        except pytz.NonExistentTimeError:
            pass
        else:
            tzinfo = gettz(zone)

            if tzinfo:
                yield tzdate.tzname(), tzinfo

TZINFOS Использование

>>> TZINFOS = dict(gen_tzinfos())
>>> TZINFOS
{'+02': tzfile('/usr/share/zoneinfo/Antarctica/Troll'),
 '+03': tzfile('/usr/share/zoneinfo/Europe/Volgograd'),
 '+04': tzfile('Europe/Ulyanovsk'),
 '+05': tzfile('/usr/share/zoneinfo/Indian/Kerguelen'),              
...
 'WGST': tzfile('/usr/share/zoneinfo/America/Godthab'),
 'WIB': tzfile('/usr/share/zoneinfo/Asia/Pontianak'),
 'WIT': tzfile('/usr/share/zoneinfo/Asia/Jayapura'),
 'WITA': tzfile('/usr/share/zoneinfo/Asia/Makassar'),
 'WSDT': tzfile('/usr/share/zoneinfo/Pacific/Apia'),
 'XJT': tzfile('/usr/share/zoneinfo/Asia/Urumqi')}

parser Использование

>>> date_str = 'Sat, 11/01/09 8:00PM EST'
>>> tzdate = parser.parse(date_str, tzinfos=TZINFOS)
>>> tzdate.astimezone(utc)
datetime.datetime(2009, 11, 2, 1, 0, tzinfo=<UTC>)

Требуется преобразование UTC, поскольку для каждой аббревиатуры доступно много часовых поясов. Так как TZINFOS является dict, он имеет только последний часовой пояс на одну аббревиатуру. И вы, возможно, не получите тот, который ожидали до обращения.

>>> tzdate
datetime.datetime(2009, 11, 1, 20, 0, tzinfo=tzfile('/usr/share/zoneinfo/America/Port-au-Prince'))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...