mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-06 07:51:47 +00:00
See #2783. Duration parsing no longer uses isodate to remain faithful to formatting.
This commit is contained in:
@@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import isodate
|
import isodate
|
||||||
import isodate.duration
|
|
||||||
from re import findall
|
from re import findall
|
||||||
from dateutil import parser
|
from dateutil import parser
|
||||||
from typing import Literal, Union, Any, overload
|
from typing import Literal, Union, Any, overload
|
||||||
@@ -70,32 +69,26 @@ def ifc2datetime(element):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def readable_ifc_duration(string: str) -> str:
|
def readable_ifc_duration(duration):
|
||||||
"""Convert ISO duration to more readable string format.
|
if "T" in duration:
|
||||||
|
period_duration, time_duration = duration.split("T")
|
||||||
|
period_duration = period_duration[1:]
|
||||||
|
else:
|
||||||
|
period_duration = duration[1:]
|
||||||
|
time_duration = ""
|
||||||
|
|
||||||
Examples:
|
result = []
|
||||||
- "P2Y3M1W4DT5H45M30S" -> "2 y 3 m 1 w 4 d 5 h 45 m 30 s"
|
for designator in ("Y", "M", "W", "D"):
|
||||||
- "P2Y3MT30S" -> "2 y 3 m 30 s"
|
if designator in period_duration:
|
||||||
"""
|
value, period_duration = period_duration.split(designator)
|
||||||
duration = isodate.parse_duration(string, as_timedelta_if_possible=False)
|
result.append(f"{value}{designator}")
|
||||||
assert isinstance(duration, isodate.duration.Duration)
|
|
||||||
|
|
||||||
final_string = ""
|
if time_duration:
|
||||||
final_string += f"{duration.years} y " if duration.years else ""
|
for designator in ("H", "M", "S"):
|
||||||
final_string += f"{duration.months} m " if duration.months else ""
|
if designator in time_duration:
|
||||||
|
value, time_duration = time_duration.split(designator)
|
||||||
# Duration stores all other components as timedelta.
|
result.append(f"{value}{designator.lower()}")
|
||||||
tdelta = duration.tdelta
|
return " ".join(result)
|
||||||
weeks, days = divmod(tdelta.days, 7)
|
|
||||||
final_string += f"{weeks} w " if weeks else ""
|
|
||||||
final_string += f"{days} d " if days else ""
|
|
||||||
hours, seconds = divmod(tdelta.seconds, 3600)
|
|
||||||
minutes, seconds = divmod(seconds, 60)
|
|
||||||
final_string += f"{hours} h " if hours else ""
|
|
||||||
final_string += f"{minutes} m " if minutes else ""
|
|
||||||
final_string += f"{seconds} s" if seconds else ""
|
|
||||||
|
|
||||||
return final_string
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import test.bootstrap
|
|||||||
import ifcopenshell.util.date as subject
|
import ifcopenshell.util.date as subject
|
||||||
|
|
||||||
|
|
||||||
class TestIsoDuration:
|
class TestReadableIFCDuration():
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
assert subject.readable_ifc_duration("P2Y3M1W4DT5H45M30S") == "2 y 3 m 1 w 4 d 5 h 45 m 30 s"
|
assert subject.readable_ifc_duration("P2Y3M1W4DT5H45M30S") == "2Y 3M 1W 4D 5h 45m 30s"
|
||||||
assert subject.readable_ifc_duration("P2Y3MT30S") == "2 y 3 m 30 s"
|
assert subject.readable_ifc_duration("PT40H") == "40h"
|
||||||
|
|||||||
Reference in New Issue
Block a user