Search code examples
pythonpython-3.xpython-datetimeiso8601

Does datetime.isoformat() really conform to ISO-8601?


According to python docs, datetime.toisoformat() returns a string representing the date and time in ISO 8601 format, but the output format string may have UTC offset part formatted as +HH:MM[:SS[.ffffff]]. I looked and looked but I couldn't find anywhere that [:SS[.ffffff]] is part of the standard, and some 3rd party tools fail to parse string formatted in this way. This includes dateutil package, to which official python docs refer as "more full-featured ISO 8601 parser". Can someone explain what is going on, is python straight out lying to us in the docs? ;)

If I'm right, I guess python's docs should be updated to mention this, but another question then would be how to properly detect that given datetime object can be represented as valid ISO 8601 string. There is always the dirty option to check the output string but I wonder if something more elegant exists :) I tried:

  1. (dt.utcoffset().total_seconds() / 60).is_integer() is simple but I don't really trust checking how much float is close to integer in this way.
  2. dt.utcoffset().microseconds == 0 and dt.utcoffset().seconds % 60 == 0 seems less error prone but I am not sure if it's right according to modular arithmetic.

Any better ideas?

Thanks for help!


Solution

  • ISO 8601 only permits UTC offsets using hours and minutes. From the spec:

    4.2.5.2 Local time and the difference from UTC

    ...

    The difference between the time scale of local time and UTC shall be expressed in hours-and-minutes, or hours-only independent of the accuracy of the local time expression associated with it.

    So you're correct that datetime.isoformat doesn't always produce ISO 8601 compatible UTC offsets.