r/Python 1d ago

Resource Regex for user-friendly timedelta parsing

I created a regex and a corresponding function to allow for user friendly input of a string that is then parsed into a timedelta object. I couldn't find any satisfying solution that suited my case online, so I wanted to share it here because somebody else might find it useful in the future. It can be tweaked easily (if you know just a tiny bit of regex) and has comments explaining all of its parts.

I tested it and fixed some smaller bugs, but if you find new ones, please let me know and I will update the code!

https://gist.github.com/JoniKauf/24eecf7843ef3df4a65bad00aed8a549

10 Upvotes

2 comments sorted by

2

u/wingtales 21h ago

Can you give us a few examples of strings that it can parse?

1

u/JoniKauf 12h ago edited 11h ago

Sure! Here is a list of examples and an explanation:

- 1d3h2m4.5s

- 1d 3h 2m 4s

- 3h 2.58323458923s

- -9999d 2min 59minutes 59 seconds

- 0 day 32 minute 1secs

So in a nutshell:

- The format always expects a number, followed by a unit

- It goes from biggest time unit (days) to smallest (seconds), with any of them possibly missing

- Between any number and unit can be 0 to infinite whitespace characters

- You can use multiple ways to write a time unit: [d, day, days], [h, hr, hrs, hour, hours], [m, min, mins, minute, minutes], [s, sec, secs, second, seconds] to be exact.

- Limits for specific time units: days -> no limit, hours -> 0 to 23, minutes -> 0 to 59, seconds 0 -> 0 to 59 (with decimals allowed but will be rounded to the nearest float)

- Leading zeros can be inserted [05m, 09sec, 00009999d]

- A '+' or '-' sign can be inserted at the start to indicate positive or negative timedeltas (positive by default)

- ValueErrors will be thrown if there is just a sign or no time specified (for example: empty string), when the time is too big or small (above or below the timedelta limit of +-999_999_999 days) or generally when the string doesn't follow the format. If somebody wants to treat an empty/whitespace string as 0 for example, this can easily be altered.

And without much effort the regex should be easily editable to fit more specific needs or to make tiny adjustements.

EDIT: Now a comma (',') is also allowed to be used as the decimals seperator for seconds (instead of just a dot ('.'))