Подтвердить что ты не робот

Синхронизация даты/времени с сокращенным названием часового пояса в Python?

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

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

4b9b3361

Ответ 1

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

Ответ 2

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

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

Ответ 3

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

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

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

Ответ 4

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

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

Ответ 5

Я использовал 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'))