34

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?

3

3 Answers 3

39

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 :)

Sign up to request clarification or add additional context in comments.

10 Comments

Thanks feynman21. I'm looking at the dateutil.parser documentation. What if I want to convert it back to an ISO format.
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.
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)).
For Python 3.3 and onward, you can use parsed_t.timestamp() to get the correct time.
@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.
|
28

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).

4 Comments

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
@user3426338: I've updated the answer to show how to convert the timestamp (number) back to ISO 8601 format string.
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.
@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.
0

Here is a solution in Python 3:

$ date +%s
1428030452
$ TZ=US/Pacific date -d @1428030452 '+%Y%m%d %H:%M:%S %z'
20150402 20:07:32 -0700
$ TZ=US/Eastern date -d @1428030452 '+%Y%m%d %H:%M:%S %z'
20150402 23:07:32 -0400
$ python3
>>> from datetime import datetime,timezone
>>> def iso2epoch(ts):
...     return int(datetime.strptime(ts[:-6],"%Y%m%d %H:%M:%S").replace(tzinfo=timezone.utc).timestamp()) - (int(ts[-2:])*60 + 60 * 60 * int(ts[-4:-2]) * int(ts[-5:-4]+'1'))
...
>>> iso2epoch("20150402 20:07:32 -0700")
1428030452
>>> iso2epoch("20150402 23:07:32 -0400")
1428030452
>>>

2 Comments

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.
Seems overly complicated --> (int(ts[-2:])*60 + 60 * 60 * int(ts[-4:-2]) * int(ts[-5:-4]+'1')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.