0

I am trying to convert ISO8601 time format to seconds/unix/epoch time in python with just using the standard library.

Time format = '2012-09-30T15:31:50.262-08:00'

Basically the time will be a string which it parses and converts it back to seconds.

Slicing and picking the values which we want is possible but is there any better way than this?

import datetime, time
def convert_enddate_to_seconds(self, ts):
    """Takes ISO 8601 format(string) and converts into epoch time."""
     dt = datetime.datetime.strptime(ts[:-7],'%Y-%m-%dT%H:%M:%S.%f')+\
                datetime.timedelta(hours=int(ts[-5:-3]),
                minutes=int(ts[-2:]))*int(ts[-6:-5]+'1')
    seconds = time.mktime(dt.timetuple()) + dt.microsecond/1000000.0
    return seconds
7
  • 1
    Is there any specific reason why you don't want to use dateutil? Commented Aug 31, 2012 at 22:38
  • I do not want to import a library just to convert the time. Commented Aug 31, 2012 at 22:39
  • 5
    The datetime module already comes with Python, you can simply import it without needing to download anything. It's difficult to use Python without being willing to use at least the builtin libraries. Commented Aug 31, 2012 at 22:51
  • The above implementation works but not as good as the dateutil and the xml.iso8601.parse Commented Aug 31, 2012 at 22:55
  • 4
    you're already importing datetime and time; why is dateutil any different? Why not do all the math yourself, too? Commented Aug 31, 2012 at 23:52

3 Answers 3

2

The final correct answer after Celada's answer. Below I have verified that the outputs of both the xml.iso8601.parse also returns the same result as the one generated by the function. Thanks to Celada for providing issues with the original code.

>>> import calendar, datetime, time 
>>> def convert_enddate_to_seconds(ts):
...   """Takes ISO 8601 format(string) and converts into epoch time."""
...   dt = datetime.datetime.strptime(ts[:-7],'%Y-%m-%dT%H:%M:%S.%f')-\
...       datetime.timedelta(hours=int(ts[-5:-3]),
...       minutes=int(ts[-2:]))*int(ts[-6:-5]+'1')
...   seconds = calendar.timegm(dt.timetuple()) + dt.microsecond/1000000.0
...   return seconds
... 
>>> import iso8601
>>> ts = '2012-09-30T15:31:50.262-08:00'
>>> iso8601.parse(ts)
1349047910.0
>>> convert_enddate_to_seconds(ts)
1349047910.26
>>> 
Sign up to request clarification or add additional context in comments.

Comments

1

For starters, you have at least 4 bugs in your sample code:

  • Your strptime format requires a decimal point and digits after the seconds but your sample input doesn't have that.
  • The ts[:-7] bit doesn't slice the end off the string correctly. ts[:-6] would seem more correct: you want to slice 6 characters off the end of the string (2 for the tz hour, 2 for the tz minute, 1 for the :, and 1 for the + or -).
  • You are adding the timezone offset where you should be subtracting it instead. You must subtract hours and minutes from a time given in an Eastern hemisphere timezone in order to get back to UTC, not add them.
  • You are using time.mktime() which assumes the timetuple is given in local time, but it's actually UTC. You need to use calendar.timegm() instead.

Here's your code updated to but the latter three problems. The first problem remains, because I did not know if you intended to force the presence of fractional seconds in the input string. You can adjust it further.

import datetime, time, calendar

def convert_enddate_to_seconds(ts):
    """Takes ISO 8601 format(string) and converts into epoch time."""
    dt = datetime.datetime.strptime(ts[:-6],'%Y-%m-%dT%H:%M:%S.%f')-\
                datetime.timedelta(hours=int(ts[-5:-3]),
                minutes=int(ts[-2:]))*int(ts[-6:-5]+'1')
    seconds = calendar.timegm(dt.timetuple()) + dt.microsecond/1000000.0
    return seconds

Using 2010-01-04T12:15:30.1+01:00 as test input, I get 1262603730.1 as output, which is correct.

As for your question: no, you are not likely to be able to get much more concise than that if you just confine yourself to the standard library.

2 Comments

I have edited the time format. Actually ISO 8601 is below. ts = '2012-09-30T15:31:50.262-08:00' This is the correct format. I have edited my original post. Thanks for pointing a few mistakes. The first two issues go away since I did a mistake in giving the input. Thanks for fixing the 3rd and the 4th issue.
I have edited my post with the final version of the code. Thanks Celada.
-1
from datetime import datetime, timezone

def convert_iso8601_to_epoch(ts):
    dt = datetime.fromisoformat(ts)
    # Convert to UTC timestamp (epoch seconds)
    return dt.timestamp()

ts = '2012-09-30T15:31:50.262-08:00'
epoch time = convert_iso8601_to_epoch(ts)
print(epoch_time)


1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.