Quantcast
Channel: User Louis Maddox - Stack Overflow
Viewing all articles
Browse latest Browse all 51

Answer by Louis Maddox for Is there an easy way to convert ISO 8601 duration to timedelta?

$
0
0

Great question, obviously the "right" solution depends on your expectations for the input (a more reliable data source doesn't need as much input validation).

My approach to parse an ISO8601 duration timestamp only checks that the "PT" prefix is present and will not assume integer values for any of the units:

from datetime import timedeltadef parse_isoduration(isostring, as_dict=False):"""    Parse the ISO8601 duration string as hours, minutes, seconds"""    separators = {"PT": None,"W": "weeks","D": "days","H": "hours","M": "minutes","S": "seconds",    }    duration_vals = {}    for sep, unit in separators.items():        partitioned = isostring.partition(sep)        if partitioned[1] == sep:            # Matched this unit            isostring = partitioned[2]            if sep == "PT":                continue # Successful prefix match            dur_str = partitioned[0]            dur_val = float(dur_str) if "." in dur_str else int(dur_str)            duration_vals.update({unit: dur_val})        else:            if sep == "PT":                raise ValueError("Missing PT prefix")            else:                # No match for this unit: it's absent                duration_vals.update({unit: 0})    if as_dict:        return duration_vals    else:        return tuple(duration_vals.values())dur_isostr = "PT3H2M59.989333S"dur_tuple = parse_isoduration(dur_isostr)dur_dict = parse_isoduration(dur_isostr, as_dict=True)td = timedelta(**dur_dict)s = td.total_seconds()

>>> dur_tuple(0, 0, 3, 2, 59.989333)>>> dur_dict{'weeks': 0, 'days': 0, 'hours': 3, 'minutes': 2, 'seconds': 59.989333}>>> tddatetime.timedelta(seconds=10979, microseconds=989333)>>> s10979.989333

Viewing all articles
Browse latest Browse all 51

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>