2009-02-08 7 views
22

Kontynuując poprzednie pytanie, Python time to age, natknąłem się na problem dotyczący strefy czasowej i okazuje się, że nie zawsze będzie to "+0200". Zatem gdy strptime próbuje go sparsować, rzuca wyjątek.Python time to age, part 2: timezones

Myślałem o odciąć +0200 z [: -6] lub cokolwiek, ale czy istnieje prawdziwy sposób, aby zrobić to z strptime?

Używam Pythona 2.5.2, jeśli to ważne.

>>> from datetime import datetime 
>>> fmt = "%a, %d %b %Y %H:%M:%S +0200" 
>>> datetime.strptime("Tue, 22 Jul 2008 08:17:41 +0200", fmt) 
datetime.datetime(2008, 7, 22, 8, 17, 41) 
>>> datetime.strptime("Tue, 22 Jul 2008 08:17:41 +0300", fmt) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.5/_strptime.py", line 330, in strptime 
    (data_string, format)) 
ValueError: time data did not match format: data=Tue, 22 Jul 2008 08:17:41 +0300 fmt=%a, %d %b %Y %H:%M:%S +0200 

Odpowiedz

28

New in version 2.6.

For a naive object, the %z and %Z format codes are replaced by empty strings.

Wygląda na to, że zaimplementowano to tylko w> = 2.6 i myślę, że musisz ręcznie je przeanalizować.

nie widzę innego rozwiązania niż usunięcie danych Strefa czasowa:

from datetime import timedelta,datetime 
try: 
    offset = int("Tue, 22 Jul 2008 08:17:41 +0300"[-5:]) 
except: 
    print "Error" 

delta = timedelta(hours = offset/100) 

fmt = "%a, %d %b %Y %H:%M:%S" 
time = datetime.strptime("Tue, 22 Jul 2008 08:17:41 +0200"[:-6], fmt) 
time -= delta 
+0

Raz zysk, dzięki gs, a także David :) Chyba będę musiał odciąć koniec, nie chcę polegać na 2.6. – Ashy

+0

Nie działa w strefach czasowych takich jak Wenezuela: -0430 – chachan

+0

@chachan: Ale trywialnie przystosowany. –

1

O ile mi wiadomo, strptime() nie rozpoznaje kody numeryczne strefę czasową. Jeśli wiesz, że ciąg znaków zawsze będzie kończyć się specyfikacją strefy czasowej tego formularza (+ lub - po którym następują 4 cyfry), samo cięcie i ręczne analizowanie wydaje się być zupełnie rozsądną rzeczą do zrobienia.

0

Wydaje się, że odpowiada% Z nazwami stref czasowych, a nie przesunięć.

Na przykład, biorąc pod uwagę:

>>> format = '%a, %d %b %Y %H:%M:%S %Z' 

mogę analizować:

>>> datetime.datetime.strptime('Tue, 22 Jul 2008 08:17:41 GMT', format) 
datetime.datetime(2008, 7, 22, 8, 17, 41) 

Chociaż wydaje się, że nie ma nic ze strefy czasowej zrobić, jedynie obserwując, że istnieje i jest ważny :

>>> datetime.datetime.strptime('Tue, 22 Jul 2008 08:17:41 NZDT', format) 
datetime.datetime(2008, 7, 22, 8, 17, 41) 

Przypuszczam, że jeśli chce, można znaleźć odwzorowanie przesunięć do nazw, konwertować swoje wejście, a następnie przeanalizuj go. Może jednak łatwiej jest po prostu skrócić wprowadzanie danych.

+0

% Z to strefa czasowa jako nazwa,% z w kategoriach. –

+6

Jeśli spróbuję użyć% z w strptime, otrzymam: ValueError: 'z' jest kiepską dyrektywą w formacie '% z' –

40

is there a real way to do this with strptime?

No, ale skoro Twój Format wydaje się datę RFC822 mieszkaniami, można go odczytać znacznie łatwiej przy użyciu biblioteki email zamiast:

>>> import email.utils 
>>> email.utils.parsedate_tz('Tue, 22 Jul 2008 08:17:41 +0200') 
(2008, 7, 22, 8, 17, 41, 0, 1, 0, 7200) 

(7200 = strefa czasowa przesunięcie od UTC w sekundy)

+0

Interesujące, ale czy mogę jakoś wyliczyć różnicę między dwoma datami? – Ashy

+6

Jeśli korzystasz z datetime, utwórz datetime przy użyciu pierwszych sześciu wartości wynikowej krotki, a następnie zrekompensuj strefę, odejmując deltę od ostatniej wartości, np. "Datetime.datetime (* a [: 6]) - datetime.timedelta (sekundy = a [-1])". Następnie przejdź do porównywania datetimes, tak jak w poprzednim pytaniu. – bobince

+2

Jeśli używasz zwykłego starego "czasu", użyj mktime(), aby przejść od krotki wszystkich oprócz ostatniej wartości do znacznika czasu, a następnie odejmij ostatnią wartość. Zauważ, że mktime podaje znacznik czasu oparty na strefie czasowej twojego lokalnego serwera, a nie na UTC, ale to nie ma znaczenia, jeśli porównujesz tylko dwa znaczniki czasu. – bobince

18

można użyć biblioteki dateutil co jest bardzo przydatne:

from datetime import datetime 
from dateutil.parser import parse 

dt = parse("Tue, 22 Jul 2008 08:17:41 +0200") 
## datetime.datetime(2008, 7, 22, 8, 17, 41, tzinfo=tzoffset(None, 7200)) <- dt 

print dt 
2008-07-22 08:17:41+02:00 
+0

Użyłem tego rozwiązania. –

+0

Nie wiedziałem o tym rozwiązaniu, po prostu przetestowałem: działa naprawdę świetnie! – user1151446