Формат даты неправильное использование strptime

Возможный Дубликат:
Питон strptime() и часовые пояса?

'Saturday, December 22, 2012 1:22:24 PM EST' does not match format '%A, %B %d, %Y %I:%M:%s %p %Z'

Возможно, я отсутствую почти, кто-либо может определить, почему это не утверждает правильно?

3
добавлено отредактировано
Просмотры: 1

4 ответы

strptime() функция не может обращаться %Z часовой пояс, разбирающий очень хорошо. Только UTC и GMT действительно поддерживаются, и текущая стоимость time.tzname . Посмотрите strptime documenation:

Поддержка %Z директива основана на ценностях, содержавшихся в tzname и верен ли дневной свет . Из-за этого это определенное для платформы за исключением признания UTC и GMT, которые всегда известны (и считаются часовыми поясами неперехода на летнее время).

Удаляя EST часть вашего входа и %Z часть вашей строки формата заставляет вещи работать:

>>> import time
>>> time.strptime('Saturday, December 22, 2012 1:22:24 PM EST', '%A, %B %d, %Y %I:%M:%s %p %Z')
Traceback (most recent call last):
  File "", line 1, in 
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/_strptime.py", line 454, in _strptime_time
    return _strptime(data_string, format)[0]
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/_strptime.py", line 325, in _strptime
    (data_string, format))
ValueError: time data 'Saturday, December 22, 2012 1:22:24 PM EST' does not match format '%A, %B %d, %Y %I:%M:%s %p %Z'
>>> time.strptime('Saturday, December 22, 2012 1:22:24 PM', '%A, %B %d, %Y %I:%M:%s %p')
time.struct_time(tm_year=2012, tm_mon=12, tm_mday=22, tm_hour=13, tm_min=22, tm_sec=24, tm_wday=5, tm_yday=357, tm_isdst=-1)

или замена часового пояса EST с GMT :

>>> time.strptime('Saturday, December 22, 2012 1:22:24 PM GMT', '%A, %B %d, %Y %I:%M:%s %p %Z')
time.struct_time(tm_year=2012, tm_mon=12, tm_mday=22, tm_hour=13, tm_min=22, tm_sec=24, tm_wday=5, tm_yday=357, tm_isdst=0)

Чтобы разобрать последовательности с часовым поясом кроме time.tzname , GMT или UTC , пользуются различной библиотекой парсинга даты. dateutil library имеет превосходное parse function это обращается с часовыми поясами правильно:

>>> from dateutil.parser import parse
>>> parse('Saturday, December 22, 2012 1:22:24 PM EST', tzinfos={'EST': -18000})
datetime.datetime(2012, 12, 22, 13, 22, 24, tzinfo=tzoffset(u'EST', -18000))

Когда использование dateutil.parser.parse() , вы делаете , должны обеспечить ваши собственные погашения часового пояса для вашего формата все же.

2
добавлено
Анализатор даты даст правильный объект даты и времени только для вышеупомянутого случая. Но рассмотрите ниже случая, >>> разбор (' суббота, 13-12-11 13:22:24 EST' tzinfos = {' EST':-18000}) datetime.datetime (2011, 12, 13, 13, 22, 24, tzinfo=tzoffset (' EST'-18000))>>>>>>>>> разбор (' суббота, 09-12-11 13:22:24 EST' tzinfos = {' EST':-18000}) datetime.datetime (2011, 9, 12, 13, 22, 24, tzinfo=tzoffset (' EST'-18000)) . datetimeobject.date() отличается для обоих случай..
добавлено автор fewtalks, источник
@Marijn: Большой. Спасибо. Я didn' t знают этот dayfirst ключевое слово. Без этого я был полностью смущен. +1 для вашего объяснения.
добавлено автор fewtalks, источник
@PSivachandran: That' s, потому что дата неоднозначный . Есть месяцы № 13, таким образом, первый пример it' s ясный, что формат находится в заказе дневного года месяца, но второй может интерпретироваться и как дневной год месяца и как дневной год месяца. Дефолт должен разобрать даты как последнего, можно изменить это с dayfirst=True ключевое слово.
добавлено автор Martijn Pieters, источник

Поскольку @root предположил, что dateutil.parser - прочный способ разобрать дату, но просто для уточнения о проблеме здесь

Я просто видел код в _strptime.py, и кажется, что поддержанные часовые пояса

["utc", "gmt", time.tzname[0].lower()]

и в случае, если, текущий часовой пояс места действия поддерживает переход на летнее время, он приложил бы

time.tzname[0].lower() to the above list.

Таким образом, используя strptime, гарантируйте, что часовой пояс, на котором вы разбираете дату, поддерживает исходный часовой пояс

Вот код для справки

def __calc_timezone(self):
    # Set self.timezone by using time.tzname.
    # Do not worry about possibility of time.tzname[0] == timetzname[1]
    # and time.daylight; handle that in strptime .
    try:
        time.tzset()
    except AttributeError:
        pass
    no_saving = frozenset(["utc", "gmt", time.tzname[0].lower()])
    if time.daylight:
        has_saving = frozenset([time.tzname[1].lower()])
    else:
        has_saving = frozenset()
    self.timezone = (no_saving, has_saving)
1
добавлено

Можно спасти себе большую проблему и использование dateutil.

In [1]: from dateutil import parser

In [2]: parser.parse('Saturday, December 22, 2012 1:22:24 PM EST')
Out[2]: datetime.datetime(2012, 12, 22, 13, 22, 24)

Что касается двусмысленности, на которую указывает eumiro, вы могли добавить tzinfo аргумент:

In [3]: parser.parse('Saturday, December 22, 2012 1:22:24 PM EST',tzinfos={'EST':-5*3600})
Out[3]: datetime.datetime(2012, 12, 22, 13, 22, 24, tzinfo=tzoffset('EST', -18000))
1
добавлено
Проблема все еще там. Это игнорирует EST часовой пояс, (правильно, так как это может быть и американец и австралиец: timeanddate.com/library/abbreviations/timezones)
добавлено автор eumiro, источник
большой, didn' t знают о tzinfos .
добавлено автор eumiro, источник
eumiro - вы правы. Я думаю, что вы могли возможно добавить tzinfos аргумент, разбирая, чтобы обращаться с ним.
добавлено автор root, источник

Скорее всего, ваш часовой пояс места действия пуст, например, %Z оценивает, чтобы '' Можно проверить это:

>>> fmt = '%A, %B %d, %Y %I:%M:%s %p %Z'
>>> datetime.strptime(datetime.strftime(datetime.now(), fmt), fmt)
Traceback (most recent call last):
  File "", line 1, in 
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/_strptime.py", line 325, in _strptime
    (data_string, format))
ValueError: time data 'Friday, December 28, 2012 11:34:35 AM ' does not match format '%A, %B %d, %Y %I:%M:%s %p %Z'
0
добавлено