7

Let's say I have a timezone like "2009-08-18 13:52:54-04". I can parse most of it using a line like this:

datetime.strptime(time_string, "%Y-%m-%d %H:%M:%S")

However, I can't get the timezone to work. There's a %Z that handles textual timezones ("EST", "UTC", etc) but I don't see anything that can parse "-04".

SilentGhost
  • 307,395
  • 66
  • 306
  • 293
mike
  • 46,876
  • 44
  • 102
  • 112
  • Dupe- [How do I translate a ISO 8601 datetime string into a Python datetime object?](http://stackoverflow.com/questions/969285/how-do-i-translate-a-iso-8601-datetime-string-into-a-python-datetime-object/3908349#3908349) (and the answer is `dateutil.parser.parse(datestring)` in both) – Yarin Mar 01 '12 at 15:05
  • related: [How to parse dates with -0400 timezone string in python?](http://stackoverflow.com/q/1101508/4279) – jfs Apr 17 '14 at 01:36

4 Answers4

24

Maybe you could use dateutil.parser.parse? That method is also mentioned on wiki.python.org/WorkingWithTime.

>>> from dateutil.parser import parse
>>> parse("2009-08-18 13:52:54-04")
datetime.datetime(2009, 8, 18, 13, 52, 54, tzinfo=tzoffset(None, -14400))

(is this question a duplicate?)

conny
  • 9,973
  • 6
  • 38
  • 47
3

use Babel, specifically parse_datetime.

iElectric
  • 5,633
  • 1
  • 29
  • 31
0

You can do that directrly on the constructor: class datetime.datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]]), tzinfo being a datetime.tzinfo dervided object.

tzinfo is an abstract base clase, meaning that this class should not be instantiated directly. You need to derive a concrete subclass, and (at least) supply implementations of the standard tzinfo methods needed by the datetime methods you use. The datetime module does not supply any concrete subclasses of tzinfo.

What you need to override is the utcoffset(self, dt) method.

Return offset of local time from UTC, in minutes east of UTC. If local time is west of UTC, this should be negative. Note that this is intended to be the total offset from UTC; for example, if a tzinfo object represents both time zone and DST adjustments, utcoffset() should return their sum. If the UTC offset isn't known, return None. Else the value returned must be a timedelta object specifying a whole number of minutes in the range -1439 to 1439 inclusive (1440 = 24*60; the magnitude of the offset must be less than one day). Most implementations of utcoffset() will probably look like one of these two:

return CONSTANT # fixed-offset class

return CONSTANT + self.dst(dt) # daylight-aware class

If utcoffset() does not return None, dst() should not return None either.

The default implementation of utcoffset() raises NotImplementedError.

Esteban Küber
  • 36,388
  • 15
  • 79
  • 97
0

I ran across the same issue recently and worked around it using this code:

gmt_offset_str = time_string[-3:]
gmt_offset_seconds = int(gmt_offset_str)*60*60
timestamp = time.strptime(time_string[:-4], '%Y-%m-%d %H:%M:%S')
return time.localtime(time.mktime(timestamp)-gmt_offset_seconds)

I would also be interested in a more elegant solution.

Dawie Strauss
  • 3,706
  • 3
  • 23
  • 26
  • 3
    Its a rather naïve solution. It works, but you will get ugly problems when working across daytime saving times and the ones that don't use it. Its better to use the built-in objects. – Esteban Küber Aug 19 '09 at 20:03
  • `mktime()` is incorrect here. Use `calendar.timegm()` instead. `email.utils.mktime_tz` from stdlib had the same bug before Python 2.7.4 – jfs Jan 13 '15 at 09:40