views:

1384

answers:

5

Following on from my previous question: http://stackoverflow.com/questions/508727/python-time-to-age

I have now come across a problem regarding the timezone, turns out that its not always going to be "+0200". So when strptime tries to parse it as such, it throws up an exception.

I thought about just chopping off the +0200 with [:-6] or whatever but is there a real way to do this with strptime?

I am using Python 2.5.2 if it matters.

>>> 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
+1  A: 

As far as I know, strptime() doesn't recognize numeric time zone codes. If you know that the string is always going to end with a time zone specification of that form (+ or - followed by 4 digits), just chopping it off and parsing it manually seems like a perfectly reasonable thing to do.

David Zaslavsky
+3  A: 

New in version 2.6.

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

Looks like this is implemented only in >= 2.6, I think you have to manually parse it.

I can't see another solution than to remove the time zone data.:

from datetime import timedelta,datetime
try:
    offset = int("Tue, 22 Jul 2008 08:17:41 +0300"[-5:])
catch:
    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
Georg
Once again, thanks gs and also David :)I guess I'll just have to chop the end off, don't wanna rely on 2.6 for this.
Ashy
+1  A: 

It seems that %Z corresponds to time zone names, not offsets.

For example, given:

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

I can parse:

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

Although it seems that it doesn't do anything with the time zone, merely observing that it exists and is valid:

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

I suppose if you wished, you could locate a mapping of offsets to names, convert your input, and then parse it. It might be simpler to just truncate your input, though.

John Fouhy
%Z is the timezone as a name, %z in houres.
Georg
If I try to use %z in strptime, I get:ValueError: 'z' is a bad directive in format '%z'
John Fouhy
+6  A: 

is there a real way to do this with strptime?

No, but since your format appears to be an RFC822-family date, you can read it much more easily using the email library instead:

>>> 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 = timezone offset from UTC in seconds)

bobince
Interesting, but then can I somehow work out the difference between two dates easily?
Ashy
If you're using datetime, create a datetime using the first six values of the resulting tuple, then compensate for the zone by subtracting a delta of the last value, eg. “datetime.datetime(*a[:6])-datetime.timedelta(seconds= a[-1])”. Then proceed to compare datetimes as in the previous question.
bobince
If you're using plain old ‘time’, use mktime() to go from a tuple of all but the last value to a numeric timestamp, then subtract the last value. Note that mktime gives you a timestamp based on your local server timezone not UTC, but that doesn't matter if you are merely comparing two timestamps.
bobince
A: 

Se puede utilizar la librería datetime que es muy útil:

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
Miuler
...Spanish, in my SO?
Beau Martínez