Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert a datetime.timedelta into ISO 8601 duration in Python?

Given a datetime.timedelta, how to convert it into a string of ISO 8601 duration format?

Ex,

>>> iso8601(datetime.timedelta(0, 18, 179651))
'PT18.179651S'
like image 846
Drake Guan Avatar asked Nov 27 '14 10:11

Drake Guan


2 Answers

This is a function from Tin Can Python project (Apache License 2.0) that can do the conversion:

def iso8601(value):
    # split seconds to larger units
    seconds = value.total_seconds()
    minutes, seconds = divmod(seconds, 60)
    hours, minutes = divmod(minutes, 60)
    days, hours = divmod(hours, 24)
    days, hours, minutes = map(int, (days, hours, minutes))
    seconds = round(seconds, 6)

    ## build date
    date = ''
    if days:
        date = '%sD' % days

    ## build time
    time = u'T'
    # hours
    bigger_exists = date or hours
    if bigger_exists:
        time += '{:02}H'.format(hours)
    # minutes
    bigger_exists = bigger_exists or minutes
    if bigger_exists:
      time += '{:02}M'.format(minutes)
    # seconds
    if seconds.is_integer():
        seconds = '{:02}'.format(int(seconds))
    else:
        # 9 chars long w/leading 0, 6 digits after decimal
        seconds = '%09.6f' % seconds
    # remove trailing zeros
    seconds = seconds.rstrip('0')
    time += '{}S'.format(seconds)
    return u'P' + date + time

E.g.

>>> iso8601(datetime.timedelta(0, 18, 179651))
'PT18.179651S'
like image 120
manlio Avatar answered Sep 26 '22 09:09

manlio


Although the datetime module contains an implementation for a ISO 8601 notation for datetime or date objects, it does not currently (Python 3.7) support the same for timedelta objects. However, the isodate module (pypi link) has functionality to generate a duration string in ISO 8601 notation:

In [15]: import isodate, datetime

In [16]: print(isodate.duration_isoformat(datetime.datetime.now() - datetime.datetime(1985, 8, 13, 15)))
P12148DT4H20M39.47017S

which means 12148 days, 4 hours, 20 minutes, 39.47017 seconds.

like image 33
gerrit Avatar answered Sep 26 '22 09:09

gerrit