Converting ISO 8601 date time to seconds in Python

36,378

Solution 1

If you want to get the seconds since epoch, you can use python-dateutil to convert it to a datetime object and then convert it so seconds using the strftime method. Like so:

>>> import dateutil.parser as dp
>>> t = '1984-06-02T19:05:00.000Z'
>>> parsed_t = dp.parse(t)
>>> t_in_seconds = parsed_t.timestamp()
>>> t_in_seconds
'455051100'

So you were halfway there :)

Solution 2

Your date is UTC time in RFC 3339 format, you could parse it using only stdlib:

from datetime import datetime

utc_dt = datetime.strptime('1984-06-02T19:05:00.000Z', '%Y-%m-%dT%H:%M:%S.%fZ')

# Convert UTC datetime to seconds since the Epoch
timestamp = (utc_dt - datetime(1970, 1, 1)).total_seconds()
# -> 455051100.0

See also Converting datetime.date to UTC timestamp in Python

How do I convert it back to ISO 8601 format?

To convert POSIX timestamp back, create a UTC datetime object from it, and format it using .strftime() method:

from datetime import datetime, timedelta

utc_dt = datetime(1970, 1, 1) + timedelta(seconds=timestamp)
print(utc_dt.strftime('%Y-%m-%dT%H:%M:%S.%fZ'))
# -> 1984-06-02T19:05:00.000000Z

Note: It prints six digits after the decimal point (microseconds). To get three digits, see Formatting microseconds to 2 decimal places (in fact converting microseconds into tens of microseconds).

Share:
36,378

Related videos on Youtube

Zaynaib Giwa
Author by

Zaynaib Giwa

I am a full stack developer who has interests in data journalism and data visualization.If you ever want to do a collaboration just contact me via twitter @AmazingSpeciali or LinkedIn.

Updated on December 20, 2020

Comments

  • Zaynaib Giwa
    Zaynaib Giwa over 3 years

    I am trying to add two times together. The ISO 8601 time stamp is '1984-06-02T19:05:00.000Z', and I would like to convert it to seconds. I tried using the Python module iso8601, but it is only a parser.

    Any suggestions?

  • Zaynaib Giwa
    Zaynaib Giwa over 9 years
    Thanks feynman21. I'm looking at the dateutil.parser documentation. What if I want to convert it back to an ISO format.
  • chunpoon
    chunpoon over 9 years
    check this out. datetime.isoformat() should have what you are looking for. So you should first convert the string back to a datetime object using strptime and then call isoformat on that object.
  • Zaynaib Giwa
    Zaynaib Giwa over 9 years
    stackoverflow.com/questions/3401428/… Thank you so much for your help.
  • Zaynaib Giwa
    Zaynaib Giwa over 9 years
    Do you by any chance know how to convert it back to ISO 8601 format? So far anotherTime = datetime.datetime.fromtimestamp(timestamp).isoformat() but it does format .000Z. Any suggestions? I tried multiple things but all I got were errors
  • jfs
    jfs over 9 years
    @user3426338: I've updated the answer to show how to convert the timestamp (number) back to ISO 8601 format string.
  • Beni Cherniavsky-Paskin
    Beni Cherniavsky-Paskin almost 8 years
    Impressively short pure stdlib TZ-aware parsing! Alas, it's not ISO 8601 format (see example in question or run date --iso-8601=ns). The ISO standard allows tons of formats so strptime is hopeless, but parsing just ±hh:mm, Z timezone formats (the RFC3339 subset) would be good enough in many cases.
  • Beni Cherniavsky-Paskin
    Beni Cherniavsky-Paskin almost 8 years
    This only parses Z suffix, doesn't deal with ±hh:mm timezones. %f annoyingly refuses to parse more than 6 fractional digits (rare but legal in both ISO 8601 and RFC 3339) e.g. as printed by date --iso-8601=ns.
  • jfs
    jfs almost 8 years
    @BeniCherniavsky-Paskin yes, it is correct (moreover %z in Python 3 understands only hhmm utc offset—no colon :). There is no way to parse even rfc 3339 (a profile of rfc 8601) using only stdlib (see the question I've linked above). Though sometimes, parsing Z is all you need as in the example in the question.
  • jfs
    jfs over 7 years
    parsed_t.strftime('%s') is wrong. parsed_t.tzinfo == tzutc() but .strftime('%s') always uses the local timezone even if it is available (it may and does differ in your case from utc). The correct answer is 455051100, not 455047500 (check datetime.utcfromtimestamp(455051100)).
  • Blairg23
    Blairg23 over 7 years
    Such a simple, elegant solution!
  • Kieleth
    Kieleth over 6 years
    Adding to @jfs comment: watch out if you're not using UTC timezone in the ISO, since strftime('%s') might bite you painfully: >>> parser.parse('2018-01-10T16:23:47-08:00').strftime('%s') '1515630227' >>> parser.parse('2018-01-10T16:23:47-00:00').strftime('%s') '1515630227'
  • user1609012
    user1609012 almost 6 years
    For Python 3.3 and onward, you can use parsed_t.timestamp() to get the correct time.
  • k-den
    k-den about 4 years
    What if you'd like the seconds as an integer instead of a string (without an additional conversion.) Is there a way instead of strftime?
  • jfs
    jfs over 3 years
    @user1609012: beware, if parsed_t is not time zone aware then timestamp() may produce incorrect result: it interprets naive datetime as local time that may differ from the desired time zone such as UTC.
  • Pavneet Singh
    Pavneet Singh over 3 years
    The above solution does not actually check the Z value to convert to GMT. If you paste the above t_in_seconds returned in the results to an epoch converter it returns Saturday, 2 June 1984 18:05:00 in GMT. so it's either not timezone aware or does not consider daylight savings.
  • Ian Smith
    Ian Smith over 2 years
    Seems overly complicated --> (int(ts[-2:])*60 + 60 * 60 * int(ts[-4:-2]) * int(ts[-5:-4]+'1')