Skip to content

Instantly share code, notes, and snippets.

@carlos-jenkins
Last active May 8, 2022 21:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carlos-jenkins/e4108166d438dfed1565c06e6bdbbc0e to your computer and use it in GitHub Desktop.
Save carlos-jenkins/e4108166d438dfed1565c06e6bdbbc0e to your computer and use it in GitHub Desktop.
Create and parse ISO8601 with Offset with standard library only in Python 3.5 and 3.6
# PARSING AN ISO8601 WITH OFFSET FORMATTED STRING USING A PYTHON VERSION PRIOR
# TO 3.7 WITH THE STANDARD LIBRARY ONLY
#
#
# For the formatting:
#
# This returns a datetime object with the timezone set to UTC.
# The internal time can now be interpreted as UTC.
#
# datetime.now(timezone.utc)
#
# This sets the timezone to local the timezone, whatever it is.
# The internal time can now be interpreted as an offset from UTC.
#
# .astimezone(tz=None)
#
# And this finally transforms the timezone aware object to a
# ISO8601 with offset string!
#
# .isoformat(timespec='microseconds')
#
# Now, for the parsing:
#
# Prior to Python 3.7, strptime() %z was only able to parse the timezone when
# using the ±HHMM[SS[.ffffff]] format. So, if you're stuck with a previous
# version (and if using Python 3.7 you should use datetime.fromisoformat())
#
# To workaround this limitation, we literally strip the last (first rightmost)
# colon using:
#
# ''.join(now.rsplit(':', 1))
#
# And that's enough to use datetime.strptime() to parse the date.
#
# NOTE: Tested in Python 3.6 and Python 3.5
>>> from datetime import datetime, timezone
>>> now = datetime.now(timezone.utc).astimezone(tz=None).isoformat()
>>> now
'2020-02-08T02:20:05.915407-06:00'
>>> datetime.strptime(''.join(now.rsplit(':', 1)), '%Y-%m-%dT%H:%M:%S.%f%z')
datetime.datetime(2020, 2, 8, 2, 20, 5, 915407, tzinfo=datetime.timezone(datetime.timedelta(-1, 64800)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment