Parsing an arbitrary ISO 8601 timestamp with minimal libraries
suggest changePython has only limited support for parsing ISO 8601 timestamps. For strptime
you need to know exactly what format it is in. As a complication the stringification of a datetime
is an ISO 8601 timestamp, with space as a separator and 6 digit fraction:
str(datetime.datetime(2016, 7, 22, 9, 25, 59, 555555))
# '2016-07-22 09:25:59.555555'
but if the fraction is 0, no fractional part is output
str(datetime.datetime(2016, 7, 22, 9, 25, 59, 0))
# '2016-07-22 09:25:59'
But these 2 forms need a different format for strptime
. Furthermore, strptime' does not support at all parsing minute timezones that have a
:in it, thus
2016-07-22 09:25:59+0300can be parsed, but the standard format
2016-07-22 09:25:59+03:00` cannot.
There is a single-file library called iso8601
which properly parses ISO 8601 timestamps and only them.
It supports fractions and timezones, and the T
separator all with a single function:
import iso8601
iso8601.parse_date('2016-07-22 09:25:59')
# datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<iso8601.Utc>)
iso8601.parse_date('2016-07-22 09:25:59+03:00')
# datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<FixedOffset '+03:00' ...>)
iso8601.parse_date('2016-07-22 09:25:59Z')
# datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<iso8601.Utc>)
iso8601.parse_date('2016-07-22T09:25:59.000111+03:00')
# datetime.datetime(2016, 7, 22, 9, 25, 59, 111, tzinfo=<FixedOffset '+03:00' ...>)
If no timezone is set, iso8601.parse_date
defaults to UTC. The default zone can be changed with default_zone
keyword argument. Notably, if this is None
instead of the default, then those timestamps that do not have an explicit timezone are returned as naive datetimes instead:
iso8601.parse_date('2016-07-22T09:25:59', default_timezone=None)
# datetime.datetime(2016, 7, 22, 9, 25, 59)
iso8601.parse_date('2016-07-22T09:25:59Z', default_timezone=None)
# datetime.datetime(2016, 7, 22, 9, 25, 59, tzinfo=<iso8601.Utc>)