I want to write a function that takes a string and returns True if it is a valid ISO-8601 datetime--precise to microseconds, including a timezone offset--False otherwise.
I have found other questions that provide different ways of parsing datetime strings, but I want to return True in the case of ISO-8601 format only. Parsing doesn't help me unless I can get it to throw an error for formats that don't match ISO-8601.
(I am using the nice arrow library elsewhere in my code. A solution that uses arrow would be welcome.)
EDIT: It appears that a general solution to "is this string a valid ISO 8601 datetime" does not exist among the common Python datetime packages.
So, to make this question narrower, more concrete and answerable, I will settle for a format string that will validate a datetime string in this form:
'2016-12-13T21:20:37.593194+00:00'
Currently I am using:
format_string = '%Y-%m-%dT%H:%M:%S.%f%z'
datetime.datetime.strptime(my_timestamp, format_string)
This gives:
ValueError: time data '2016-12-13T21:20:37.593194+00:00' does not match format '%Y-%m-%dT%H:%M:%S.%f%z'
The problem seems to lie with the colon in the UTC offset (+00:00). If I use an offset without a colon (e.g. '2016-12-13T21:20:37.593194+0000'), this parses properly as expected. This is apparently because datetime's %z token does not respect the UTC offset form that has a colon, only the form without, even though both are valid per the spec.
Given the constraints you've put on the problem, you could easily solve it with a regular expression.
If you need to pass all variations of ISO 8601 it will be a much more complicated regular expression, but it could still be done. If you also need to validate the numeric ranges, for example verifying that the hour is between 0 and 23, you can put parentheses into the regular expression to create match groups then validate each group.