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 date string: Best way to parse string containing UTC
https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat or https://dateutil.readthedocs.io/en/stable/parser.html#dateutil.parser.parse More on reddit.com
🌐 r/learnpython
6
1
January 19, 2022
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 Datetime in Python with timezone - Stack Overflow
How do I parse this date and time with the time zone? date_time=datetime.strptime("2017-06-04T01:00:00+04:00", '%Y-%m-%dT%H:%M:%S%Z') I am getting error like ValueError: time data '2017-06-04T01... More on stackoverflow.com
🌐 stackoverflow.com
🌐
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.
🌐
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?

🌐
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.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.
Find elsewhere
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)
🌐
dateutil
dateutil.readthedocs.io › en › stable › parser.html
parser — dateutil 3.9.0 documentation - Read the Docs
ignoretz – If set True, time zones in parsed strings are ignored and a naive datetime object is returned. ... Additional time zone names / aliases which may be present in the string. This argument maps time zone names (and optionally offsets from those time zones) to time zones. This parameter can be a dictionary with timezone aliases mapping time zone names to time zones or a function taking two parameters (tzname and tzoffset) and returning a time zone.
🌐
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?
December 17, 2024 - 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 ...
🌐
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
🌐
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);
🌐
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 ...
🌐
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:
🌐
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>)
🌐
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....
🌐
Pandas
pandas.pydata.org › pandas-docs › stable › reference › api › pandas.to_datetime.html
pandas.to_datetime — pandas 3.0.1 documentation
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);