As of Python 3.7, datetime.datetime.fromisoformat() can handle your format:

>>> import datetime
>>> datetime.datetime.fromisoformat('2012-11-01T04:16:13-04:00')
datetime.datetime(2012, 11, 1, 4, 16, 13, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=72000)))

In older Python versions you can't, not without a whole lot of painstaking manual timezone defining.

Python versions before version 3.9 do not include a timezone database, because it would be outdated too quickly. Instead, for those versions Python relied on external libraries, which can have a far faster release cycle, to provide properly configured timezones for you.

As a side-effect, this means that timezone parsing also needs to be an external library. If dateutil is too heavy-weight for you, use iso8601 instead, it'll parse your specific format just fine:

>>> import iso8601
>>> iso8601.parse_date('2012-11-01T04:16:13-04:00')
datetime.datetime(2012, 11, 1, 4, 16, 13, tzinfo=<FixedOffset '-04:00'>)

iso8601 is a whopping 4KB small. Compare that tot python-dateutil's 148KB.

As of Python 3.2 Python can handle simple offset-based timezones, and %z will parse -hhmm and +hhmm timezone offsets in a timestamp. That means that for a ISO 8601 timestamp you'd have to remove the : in the timezone:

>>> from datetime import datetime
>>> iso_ts = '2012-11-01T04:16:13-04:00'
>>> datetime.strptime(''.join(iso_ts.rsplit(':', 1)), '%Y-%m-%dT%H:%M:%S%z')
datetime.datetime(2012, 11, 1, 4, 16, 13, tzinfo=datetime.timezone(datetime.timedelta(-1, 72000)))

The lack of proper ISO 8601 parsing was being tracked in Python issue 15873 (since migrated to GitHub issue #60077).

Answer from Martijn Pieters on Stack Overflow
Top answer
1 of 7
167

As of Python 3.7, datetime.datetime.fromisoformat() can handle your format:

>>> import datetime
>>> datetime.datetime.fromisoformat('2012-11-01T04:16:13-04:00')
datetime.datetime(2012, 11, 1, 4, 16, 13, tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=72000)))

In older Python versions you can't, not without a whole lot of painstaking manual timezone defining.

Python versions before version 3.9 do not include a timezone database, because it would be outdated too quickly. Instead, for those versions Python relied on external libraries, which can have a far faster release cycle, to provide properly configured timezones for you.

As a side-effect, this means that timezone parsing also needs to be an external library. If dateutil is too heavy-weight for you, use iso8601 instead, it'll parse your specific format just fine:

>>> import iso8601
>>> iso8601.parse_date('2012-11-01T04:16:13-04:00')
datetime.datetime(2012, 11, 1, 4, 16, 13, tzinfo=<FixedOffset '-04:00'>)

iso8601 is a whopping 4KB small. Compare that tot python-dateutil's 148KB.

As of Python 3.2 Python can handle simple offset-based timezones, and %z will parse -hhmm and +hhmm timezone offsets in a timestamp. That means that for a ISO 8601 timestamp you'd have to remove the : in the timezone:

>>> from datetime import datetime
>>> iso_ts = '2012-11-01T04:16:13-04:00'
>>> datetime.strptime(''.join(iso_ts.rsplit(':', 1)), '%Y-%m-%dT%H:%M:%S%z')
datetime.datetime(2012, 11, 1, 4, 16, 13, tzinfo=datetime.timezone(datetime.timedelta(-1, 72000)))

The lack of proper ISO 8601 parsing was being tracked in Python issue 15873 (since migrated to GitHub issue #60077).

2 of 7
75

Here is the Python Doc for datetime object using dateutil package..

from dateutil.parser import parse

get_date_obj = parse("2012-11-01T04:16:13-04:00")
print get_date_obj
🌐
GeeksforGeeks
geeksforgeeks.org › python › convert-string-to-datetime-in-python-with-timezone
Convert string to datetime in Python with timezone - GeeksforGeeks
July 23, 2025 - Explanation: string s is parsed ... and timezone. dateutil.parser.parse() from the python-dateutil library automatically detects and parses date formats without requiring a specified format....
Discussions

Parse "Z" timezone suffix in datetime - Ideas - Discussions on Python.org
This is already opened as BPO 35829 but I wanted to ask about it over here for discussion. Problem Statement The function datetime.fromisoformat() parses a datetime in ISO-8601, format: >>> datetime.fromisoformat('2019-08-28T14:34:25.518993+00:00') datetime.datetime(2019, 8, 28, 14, 34, 25, ... More on discuss.python.org
🌐 discuss.python.org
10
August 28, 2019
datetime - How to parse dates with -0400 timezone string in Python? - Stack Overflow
It seems that previous versions of Python may have supported a %z format tag in strptime for the trailing timezone specification, but 2.6.x seems to have removed that. What's the right way to parse this string into a datetime object? ... >>> from dateutil.parser import parse >>> d = ... More on stackoverflow.com
🌐 stackoverflow.com
Parsing date/time string with timezone abbreviated name in Python? - Stack Overflow
By far the easiest route (though ... timezone from the zoneinfo database. 2009-11-10T02:48:19.363Z+00:00 ... pytz brings the Olson tz database into Python. This library allows accurate and cross platform timezone calculations using Python 2.3 or higher. It also solves the issue of ambiguous times at the end of daylight savings, which you can read more about in the Python Library Reference (datetime.tzinfo). Amost all of the Olson timezones are supported. ... i am curious, how does one parse "Sat, 11/01/09 ... More on stackoverflow.com
🌐 stackoverflow.com
python - How to preserve timezone when parsing date/time strings with strptime()? - Stack Overflow
Your time string is similar to the time format in rfc 2822 (date format in email, http headers). You could parse it using only stdlib: >>> from email.utils import parsedate_tz >>> parsedate_tz('Tue Jun 22 07:46:22 EST 2010') (2010, 6, 22, 7, 46, 22, 0, 1, -1, -18000) See solutions that yield timezone-aware datetime objects for various Python ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Reddit
reddit.com › r/learnpython › parse date string: best way to parse string containing utc
r/learnpython on Reddit: Parse date string: Best way to parse string containing UTC
January 19, 2022 -

Hi.

Consider this text string: 2021-01-01 01:01:00 UTC.

What's the best way of parsing this into a date object in Python 3? I could remove the "UTC" from the text, and then use something like datetime.strptime(date_string, format), but isn't there an easier way, like doesn't Python already have support for parseing strings like these?

🌐
Python documentation
docs.python.org › 3 › library › datetime.html
datetime — Basic date and time types
Because naive datetime objects ... an object representing a specific timestamp in UTC is by calling datetime.fromtimestamp(timestamp, tz=timezone.utc)....
🌐
Rip Tutorial
riptutorial.com › parsing a string into a timezone aware datetime object
Python Language Tutorial => Parsing a string into a timezone aware...
UTC offset in the form +HHMM or -HHMM (empty string if the object is naive). ... For other versions of Python, you can use an external library such as dateutil, which makes parsing a string with timezone into a datetime object is quick.
🌐
Python.org
discuss.python.org › ideas
Parse "Z" timezone suffix in datetime - Ideas - Discussions on Python.org
August 28, 2019 - This is already opened as BPO 35829 but I wanted to ask about it over here for discussion. Problem Statement The function datetime.fromisoformat() parses a datetime in ISO-8601, format: >>> datetime.fromisoformat('2019-08-28T14:34:25.518993+00:00') datetime.datetime(2019, 8, 28, 14, 34, 25, 518993, tzinfo=datetime.timezone.utc) The timezone offset in my example is +00:00, i.e. UTC.
Top answer
1 of 6
135

You can use the parse function from dateutil:

>>> from dateutil.parser import parse
>>> d = parse('2009/05/13 19:19:30 -0400')
>>> d
datetime.datetime(2009, 5, 13, 19, 19, 30, tzinfo=tzoffset(None, -14400))

This way you obtain a datetime object you can then use.

As answered, dateutil2.0 is written for Python 3.0 and does not work with Python 2.x. For Python 2.x dateutil1.5 needs to be used.

2 of 6
62

%z is supported in Python 3.2+:

>>> from datetime import datetime
>>> datetime.strptime('2009/05/13 19:19:30 -0400', '%Y/%m/%d %H:%M:%S %z')
datetime.datetime(2009, 5, 13, 19, 19, 30,
                  tzinfo=datetime.timezone(datetime.timedelta(-1, 72000)))

On earlier versions:

from datetime import datetime

date_str = '2009/05/13 19:19:30 -0400'
naive_date_str, _, offset_str = date_str.rpartition(' ')
naive_dt = datetime.strptime(naive_date_str, '%Y/%m/%d %H:%M:%S')
offset = int(offset_str[-4:-2])*60 + int(offset_str[-2:])
if offset_str[0] == "-":
   offset = -offset
dt = naive_dt.replace(tzinfo=FixedOffset(offset))
print(repr(dt))
# -> datetime.datetime(2009, 5, 13, 19, 19, 30, tzinfo=FixedOffset(-240))
print(dt)
# -> 2009-05-13 19:19:30-04:00

where FixedOffset is a class based on the code example from the docs:

from datetime import timedelta, tzinfo

class FixedOffset(tzinfo):
    """Fixed offset in minutes: `time = utc_time + utc_offset`."""
    def __init__(self, offset):
        self.__offset = timedelta(minutes=offset)
        hours, minutes = divmod(offset, 60)
        #NOTE: the last part is to remind about deprecated POSIX GMT+h timezones
        #  that have the opposite sign in the name;
        #  the corresponding numeric value is not used e.g., no minutes
        self.__name = '<%+03d%02d>%+d' % (hours, minutes, -hours)
    def utcoffset(self, dt=None):
        return self.__offset
    def tzname(self, dt=None):
        return self.__name
    def dst(self, dt=None):
        return timedelta(0)
    def __repr__(self):
        return 'FixedOffset(%d)' % (self.utcoffset().total_seconds() / 60)
Find elsewhere
🌐
dateutil
dateutil.readthedocs.io › en › stable › parser.html
parser — dateutil 3.9.0 documentation - Read the Docs
If a time zone is omitted, a timezone-naive datetime is returned. If any other elements are missing, they are taken from the datetime.datetime object passed to the parameter default. If this results in a day number exceeding the valid number of days per month, the value falls back to the end of the month. Additional resources about date/time string formats can be found below: A summary of the international standard date and time notation ... Parse a string in one of the supported formats, using the parserinfo parameters.
🌐
Readthedocs
dateparser.readthedocs.io › en › latest
dateparser – python parser for human readable dates — DateParser 1.3.0 documentation
>>> parse('2 hours ago -0500') datetime.datetime(2017, 3, 10, 15, 59, 30, 193431, tzinfo=<StaticTzInfo 'UTC\-05:00'>) If date has no timezone name/abbreviation or offset, you can specify it using TIMEZONE setting.
🌐
Python Guides
pythonguides.com › convert-a-string-to-datetime-in-python
Convert Python String to Datetime with Timezone
September 23, 2025 - from dateutil import parser import pytz # Example timestamp string with timezone info timestamp_str = "September 23, 2025 2:30 PM EST" # Step 1: Parse string directly dt_parsed = parser.parse(timestamp_str) # Step 2: Convert to another timezone (e.g., Pacific Time) pacific = pytz.timezone("America/Los_Angeles") dt_pacific = dt_parsed.astimezone(pacific) print("Parsed datetime:", dt_parsed) print("Converted to Pacific Time:", dt_pacific) You can see the output in the screenshot below. This method is my favorite when dealing with user input or messy log files. I don’t need to specify the forma
🌐
Stack Abuse
stackabuse.com › converting-strings-to-datetime-in-python
Converting Strings to datetime in Python
June 21, 2023 - As you can see, all of the date formats were successfully parsed! If we don't provide the timezone info then, it automatically converts it to UTC. So, it is important to note that we must provide the to_timezone and naive parameters if the time is not in UTC. Arrow is another library for dealing with datetime in Python. And like before with maya, it also figures out the datetime format automatically. Once interpreted, it returns a Python datetime object from the arrow object. To easily convert a string ...
🌐
PYnative
pynative.com › home › python › python datetime › python string to datetime using strptime()
Python String to DateTime using Strptime() [5 Ways] – PYnative
December 5, 2021 - from datetime import datetime # ... as timedelta (+/-) or with the timezone names to the datetime object using the %z and %Z format directives....
🌐
Iditect
iditect.com › faq › python › how-to-preserve-timezone-when-parsing-datetime-strings-with-strptime-in-python.html
How to preserve timezone when parsing date/time strings with strptime() in python?
February 27, 2023 - This code snippet demonstrates parsing a date/time string with timezone information using %z format specifier in strptime() function, preserving the timezone in the resulting datetime object. ... Description: Users may specifically look for ways to ensure that the timezone offset is preserved ...
🌐
Inventive HQ
inventivehq.com › home › blog › python datetime format: strftime, strptime & date conversion examples
Python Datetime Format: strftime, strptime & Date Conversion Examples
November 6, 2025 - from datetime import datetime # ISO 8601 format iso_string = "2023-07-11T14:30:00" iso_datetime = datetime.fromisoformat(iso_string) # With timezone info iso_with_tz = "2023-07-11T14:30:00-04:00" datetime_with_tz = datetime.fromisoformat(iso_with_tz) Copy · When working with datetime parsing, always handle potential errors:
🌐
alpharithms
alpharithms.com › home › tutorials › converting between strings and datetime objects in python
Converting Between Strings and Datetime Objects in Python - αlphαrithms
April 11, 2024 - The above references and general use of the strptime method provides the groundwork for converting strings to datetime objects in Python. The essential steps of this process are as follows: ... Below is a slightly more complex example in which ...
🌐
Pandas
pandas.pydata.org › docs › reference › api › pandas.to_datetime.html
pandas.to_datetime — pandas 3.0.1 documentation - PyData |
See also: pandas general documentation about timezone conversion and localization. ... The strftime to parse time, e.g. "%d/%m/%Y". See strftime documentation for more information on choices, though note that "%f" will parse all the way up to nanoseconds. You can also pass: “ISO8601”, to parse any ISO8601 time string (not necessarily in exactly the same format);
Top answer
1 of 6
66

dateutil's parser.parse() accepts as keyword argument tzinfos a dictionary of the kind {'EST': -5*3600} (that is, matching the zone name to GMT offset in seconds). So assuming we have that, we can do:

>>> 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

Regarding the content of tzinfos, here is how i populated mine:

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

ps. per @Hank Gay time zone naming is not clearly defined. To form my table i used http://www.timeanddate.com/library/abbreviations/timezones/ and http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations . I looked at each conflict and resolved conflicts between obscure and popular names towards the popular (more used ones). There was one - IST - that was not as clear cut (it can mean Indian Standard Time, Iran Standard Time, Irish Standard Time or Israel Standard Time), so i left it out of the table - you may need to chose what to add for it based on your location. Oh - and I left out the Republic of Kiribati with their absurd "look at me i am first to celebrate New Year" GMT+13 and GMT+14 time zones.

2 of 6
14

That probably won't work because those abbreviations aren't unique. See this page for details. You might wind up just having to manually handle it yourself if you're working with a known set of inputs.

🌐
Cheat Sheets
cheat.readthedocs.io › en › latest › python › timezones.html
Timezones in Python — Dan's Cheat Sheets 1 documentation
So here’s one of the problems - we don’t KNOW what timezone this date/time is from, we only know the current offset from UTC. So, the best we can do is to figure out the corresponding time in UTC, then create an aware object in UTC. We know this time is 240 minutes less than the corresponding UTC time, so: >>> import time >>> time_seconds = time.mktime(dt.timetuple()) >>> time_seconds -= 60*minutes >>> utc_time = datetime.datetime.fromtimestamp(time_seconds, pytz.utc) >>> utc_time datetime.datetime(2012, 7, 3, 22, 11, 3, tzinfo=<UTC>)
🌐
Medium
medium.com › @generativeai.saif › how-to-convert-a-string-to-a-date-in-python-complete-guide-for-2025-bd5ece07c57c
How to Convert a String to a Date in Python: Complete Guide for 2025 | by Saif Ali | Medium
April 6, 2025 - For robust timezone handling, you’ll typically use the pytz library: from datetime import datetime import pytz # Parse a string with timezone information timezone_string = "2025-04-02 14:30:45+05:30" timezone_aware = datetime.strptime(tim...