mirror of
https://framagit.org/framasoft/framaspace/argos.git
synced 2025-04-28 18:02:41 +02:00
Add the ability to convert to days, hours, minutes
This commit is contained in:
parent
4935a025ce
commit
e540eee9b3
2 changed files with 51 additions and 17 deletions
|
@ -1,30 +1,41 @@
|
||||||
from typing import Literal
|
from typing import Literal
|
||||||
|
|
||||||
|
|
||||||
def string_to_duration(value: str, target: Literal["days", "hours"]):
|
def string_to_duration(value: str, target: Literal["days", "hours", "minutes"]):
|
||||||
"""Convert a string to a number of hours, or days"""
|
"""Convert a string to a number of hours, days or minutes"""
|
||||||
num = int("".join(filter(str.isdigit, value)))
|
num = int("".join(filter(str.isdigit, value)))
|
||||||
|
|
||||||
if target == "hours":
|
# It's not possible to convert from a smaller unit to a greater one:
|
||||||
reconvert = True
|
# - hours and minutes cannot be converted to days
|
||||||
|
# - minutes cannot be converted to hours
|
||||||
|
if (target == "days" and ("h" in value or "m" in value.replace("mo", ""))) or (
|
||||||
|
target == "hours" and "m" in value.replace("mo", "")
|
||||||
|
):
|
||||||
|
msg = (
|
||||||
|
"Durations cannot be converted from a smaller to a greater unit. "
|
||||||
|
f"(trying to convert '{value}' to {target})"
|
||||||
|
)
|
||||||
|
raise ValueError(msg, value)
|
||||||
|
|
||||||
|
# Consider we're converting to minutes, do the eventual multiplication at the end.
|
||||||
if "h" in value:
|
if "h" in value:
|
||||||
if target == "days":
|
num = num * 60
|
||||||
raise ValueError("Invalid duration value", value)
|
|
||||||
num = num
|
|
||||||
reconvert = False
|
|
||||||
elif "d" in value:
|
elif "d" in value:
|
||||||
num = num
|
num = num * 60 * 24
|
||||||
elif "w" in value:
|
elif "w" in value:
|
||||||
num = num * 7
|
num = num * 60 * 24 * 7
|
||||||
elif "m" in value:
|
elif "mo" in value:
|
||||||
num = num * 30
|
num = num * 60 * 24 * 30 # considers 30d in a month
|
||||||
elif "y" in value:
|
elif "y" in value:
|
||||||
num = num * 365
|
num = num * 60 * 24 * 365
|
||||||
|
elif "m" in value:
|
||||||
|
num = num
|
||||||
else:
|
else:
|
||||||
raise ValueError("Invalid duration value", value)
|
raise ValueError("Invalid duration value", value)
|
||||||
|
|
||||||
if target == "hours" and reconvert:
|
if target == "hours":
|
||||||
num = num * 24
|
num = num / 60
|
||||||
|
elif target == "days":
|
||||||
|
num = num / 60 / 24
|
||||||
|
|
||||||
return num
|
return num
|
||||||
|
|
|
@ -7,7 +7,7 @@ def test_string_to_duration_days():
|
||||||
assert string_to_duration("1d", target="days") == 1
|
assert string_to_duration("1d", target="days") == 1
|
||||||
assert string_to_duration("1w", target="days") == 7
|
assert string_to_duration("1w", target="days") == 7
|
||||||
assert string_to_duration("3w", target="days") == 21
|
assert string_to_duration("3w", target="days") == 21
|
||||||
assert string_to_duration("3m", target="days") == 90
|
assert string_to_duration("3mo", target="days") == 90
|
||||||
assert string_to_duration("1y", target="days") == 365
|
assert string_to_duration("1y", target="days") == 365
|
||||||
|
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
|
@ -22,7 +22,30 @@ def test_string_to_duration_hours():
|
||||||
assert string_to_duration("1d", target="hours") == 24
|
assert string_to_duration("1d", target="hours") == 24
|
||||||
assert string_to_duration("1w", target="hours") == 7 * 24
|
assert string_to_duration("1w", target="hours") == 7 * 24
|
||||||
assert string_to_duration("3w", target="hours") == 21 * 24
|
assert string_to_duration("3w", target="hours") == 21 * 24
|
||||||
assert string_to_duration("3m", target="hours") == 3 * 30 * 24
|
assert string_to_duration("3mo", target="hours") == 3 * 30 * 24
|
||||||
|
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
string_to_duration("1", target="hours")
|
string_to_duration("1", target="hours")
|
||||||
|
|
||||||
|
|
||||||
|
def test_string_to_duration_minutes():
|
||||||
|
assert string_to_duration("1m", target="minutes") == 1
|
||||||
|
assert string_to_duration("1h", target="minutes") == 60
|
||||||
|
assert string_to_duration("1d", target="minutes") == 60 * 24
|
||||||
|
assert string_to_duration("3mo", target="minutes") == 60 * 24 * 30 * 3
|
||||||
|
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
string_to_duration("1", target="minutes")
|
||||||
|
|
||||||
|
|
||||||
|
def test_conversion_to_greater_units_throws():
|
||||||
|
# hours and minutes cannot be converted to days
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
string_to_duration("1h", target="days")
|
||||||
|
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
string_to_duration("1m", target="days")
|
||||||
|
|
||||||
|
# minutes cannot be converted to hours
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
string_to_duration("1m", target="hours")
|
||||||
|
|
Loading…
Reference in a new issue