Convert human-readable durations to seconds and back, with ISO 8601 support, in Python.
- A
Durationclass with full arithmetic (+,-,*,/), comparison (<,==,>, ...), and interop withdatetime.timedelta. - Parse strings like
"1h","20m","10s","1h3d5w","1.5h","-1h30m"into total seconds. - Parse and generate ISO 8601 durations (
"PT1H30M","P1Y2M3DT4H5M6S"). - Convert seconds back into human-readable strings or dictionaries.
- Handles single units, concatenated units, and space/comma-separated units.
- Supports decimal amounts and negative durations.
- 19 units from attoseconds to millennia, including fortnights and quarters.
- Preserves singular/plural formatting (
"1 Hour"vs"2 Hours"). - Fully typed,
mypy --strictclean. - Pip-installable via GitHub.
Install directly from GitHub:
pip install git+https://github.com/vszlx4/humantime.gitfrom humantime import Duration
d = Duration.from_string("1h 30m 10s")
print(d.seconds) # 5410.0
print(d) # "1 Hour, 30 Minutes, and 10 Seconds"
print(d.to_iso8601()) # "PT1H30M10S"
# Arithmetic
total = Duration.from_string("1h") + Duration.from_string("45m")
print(total) # "1 Hour and 45 Minutes"
# Comparison
print(Duration.from_string("2h") > Duration.from_string("90m")) # True
# timedelta interop
from datetime import timedelta
print(d.to_timedelta()) # datetime.timedelta object
print(Duration.from_timedelta(timedelta(hours=2))) # "2 Hours"
# ISO 8601
d2 = Duration.from_iso8601("P1DT2H30M")
print(d2) # "1 Day, 2 Hours, and 30 Minutes"
# Negative durations
neg = Duration.from_string("-1h30m")
print(neg) # "-1 Hour and 30 Minutes"
# Dict breakdown
print(d.to_dict()) # {'h': 1, 'm': 30, 's': 10}For a lighter-weight, function-based style:
from humantime import to_seconds, from_seconds
seconds = to_seconds("1h 30m 10s")
print(seconds) # 5410.0
readable = from_seconds(5410)
print(readable) # "1 Hour, 30 Minutes, and 10 Seconds"
dict_form = from_seconds(5410, style=False)
print(dict_form) # {'h': 1, 'm': 30, 's': 10}| Unit | Format |
|---|---|
| Attosecond | as, v |
| Femtosecond | fs, j |
| Picosecond | ps, p |
| Nanosecond | ns, n |
| Microsecond | mc, r |
| Millisecond | ms, i |
| Centisecond | cs, u |
| Decisecond | ds, t |
| Second | s |
| Minute | m |
| Hour | h |
| Day | d |
| Week | w |
| Fortnight | f |
| Month | mo, o |
| Quarter | q |
| Year | y |
| Decade | de, e |
| Century | ce, c |
| Millennium | ml, l |
- Concatenated units are supported (
"1h30m"). - Multiple units can be separated by spaces or commas (
"10m, 3h, 1y"). - Decimal amounts are supported (
"1.5h","2.25d"). - A leading
-negates the whole duration ("-1h30m"). - If
years_max=Trueinfrom_seconds/Duration.humanize, units above a year (decade, century, millennium) are excluded. style=Falseinfrom_secondsreturns a dictionary instead of a formatted string.- Unknown units raise
ParseErrorby default; passstrict=Falseto skip them instead. - Month, quarter, and year are fixed-length approximations (30/91.25/365 days), not calendar-aware — this applies to ISO 8601 conversion as well.
This project is licensed under the MIT License — see the LICENSE file for details.