I prefer using the dateutil library for timezone handling and generally solid date parsing. If you were to get an ISO 8601 string like: 2010-05-08T23:41:54.000Z you'd have a fun time parsing that with strptime, especially if you didn't know up front whether or not the timezone was included. pyiso8601 has a couple of issues (check their tracker) that I ran into during my usage and it hasn't been updated in a few years. dateutil, by contrast, has been active and worked for me:
from dateutil import parser
yourdate = parser.parse(datestring)
I prefer using the dateutil library for timezone handling and generally solid date parsing. If you were to get an ISO 8601 string like: 2010-05-08T23:41:54.000Z you'd have a fun time parsing that with strptime, especially if you didn't know up front whether or not the timezone was included. pyiso8601 has a couple of issues (check their tracker) that I ran into during my usage and it hasn't been updated in a few years. dateutil, by contrast, has been active and worked for me:
from dateutil import parser
yourdate = parser.parse(datestring)
Since Python 3.7 and no external libraries, you can use the fromisoformat function from the datetime module:
datetime.datetime.fromisoformat('2019-01-04T16:41:24+02:00')
Python 2 doesn't support the %z format specifier, so it's best to explicitly use Zulu time everywhere if possible:
datetime.datetime.strptime("2007-03-04T21:08:12Z", "%Y-%m-%dT%H:%M:%SZ")
How to parse ISO 8601 date in Python? - TestMu AI Community
python - How do I parse an ISO 8601-formatted date and time? - Stack Overflow
Convert Date String in Filenames to ISO Date Format
What will be the golang equivalent of the ISO UTC timestamp in python `datetime.datetime.utcnow().isoformat()` ?
Q3. Why does the method strptime() fail on some ISO 8601 strings?
Q5. Can I convert an ISO 8601 string directly into UTC?
Q1. What does the Z mean in ISO 8601?
Videos
In Python 3.10 and earlier, datetime.fromisoformat only supported formats outputted by datetime.isoformat. This meant that many valid ISO 8601 strings could not be parsed, including the very common "Z" suffix (e.g. 2000-01-01T00:00:00Z).
I discovered today that 3.11 supports most ISO 8601 formats. I'm thrilled: I'll no longer have to use a third-party library to ingest ISO 8601 and RFC 3339 datetimes. This was one of my biggest gripes with Python's stdlib.
It's not 100% standards compliant, but I think the exceptions are pretty reasonable:
-
Time zone offsets may have fractional seconds.
-
The T separator may be replaced by any single unicode character.
-
Ordinal dates are not currently supported.
-
Fractional hours and minutes are not supported.
https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat
isoparse function from python-dateutil
The python-dateutil package has dateutil.parser.isoparse to parse not only RFC 3339 datetime strings like the one in the question, but also other ISO 8601 date and time strings that don't comply with RFC 3339 (such as ones with no UTC offset, or ones that represent only a date).
>>> import dateutil.parser
>>> dateutil.parser.isoparse('2008-09-03T20:56:35.450686Z') # RFC 3339 format
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686, tzinfo=tzutc())
>>> dateutil.parser.isoparse('2008-09-03T20:56:35.450686') # ISO 8601 extended format
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686)
>>> dateutil.parser.isoparse('20080903T205635.450686') # ISO 8601 basic format
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686)
>>> dateutil.parser.isoparse('20080903') # ISO 8601 basic format, date only
datetime.datetime(2008, 9, 3, 0, 0)
The python-dateutil package also has dateutil.parser.parse. Compared with isoparse, it is presumably less strict, but both of them are quite forgiving and will attempt to interpret the string that you pass in. If you want to eliminate the possibility of any misreads, you need to use something stricter than either of these functions.
Comparison with Python 3.7+’s built-in datetime.datetime.fromisoformat
dateutil.parser.isoparse is a full ISO-8601 format parser, but in Python ≤ 3.10 fromisoformat is deliberately not. In Python 3.11, fromisoformat supports almost all strings in valid ISO 8601. See fromisoformat's docs for this cautionary caveat. (See this answer).
Since Python 3.11, the standard library’s datetime.datetime.fromisoformat supports most valid ISO 8601 input (and some non-valid input, see docs). In earlier versions it only parses a specific subset, see the cautionary note at the end of the docs. If you are using Python 3.10 or earlier on strings that don't fall into that subset (like in the question), see other answers for functions from outside the standard library.
The current docs (so exceptions listed are still valid for Python 3.13):
classmethod
datetime.fromisoformat(date_string):Return a
datetimecorresponding to a date_string in any valid ISO 8601 format, with the following exceptions:
- Time zone offsets may have fractional seconds.
- The T separator may be replaced by any single unicode character.
- Fractional hours and minutes are not supported.
- Reduced precision dates are not currently supported (YYYY-MM, YYYY).
- Extended date representations are not currently supported (±YYYYYY-MM-DD).
- Ordinal dates are not currently supported (YYYY-OOO).
Examples:
>>> from datetime import datetime >>> datetime.fromisoformat('2011-11-04') datetime.datetime(2011, 11, 4, 0, 0) >>> datetime.fromisoformat('20111104') datetime.datetime(2011, 11, 4, 0, 0) >>> datetime.fromisoformat('2011-11-04T00:05:23') datetime.datetime(2011, 11, 4, 0, 5, 23) >>> datetime.fromisoformat('2011-11-04T00:05:23Z') datetime.datetime(2011, 11, 4, 0, 5, 23, tzinfo=datetime.timezone.utc) >>> datetime.fromisoformat('20111104T000523') datetime.datetime(2011, 11, 4, 0, 5, 23) >>> datetime.fromisoformat('2011-W01-2T00:05:23.283') datetime.datetime(2011, 1, 4, 0, 5, 23, 283000) >>> datetime.fromisoformat('2011-11-04 00:05:23.283') datetime.datetime(2011, 11, 4, 0, 5, 23, 283000) >>> datetime.fromisoformat('2011-11-04 00:05:23.283+00:00') datetime.datetime(2011, 11, 4, 0, 5, 23, 283000, tzinfo=datetime.timezone.utc) >>> datetime.fromisoformat('2011-11-04T00:05:23+04:00') datetime.datetime(2011, 11, 4, 0, 5, 23, tzinfo=datetime.timezone(datetime.timedelta(seconds=14400)))New in version 3.7.
Changed in version 3.11: Previously, this method only supported formats that could be emitted by date.isoformat() or datetime.isoformat().
If you only need dates, and not datetimes, you can use datetime.date.fromisoformat:
>>> from datetime import date
>>> date.fromisoformat("2024-01-31")
datetime.date(2024, 1, 31)
» pip install isodate