mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 01:41:57 +00:00
Update to ifcopenshell.util.date for handling of IfcDuration with python and import of Planned Durations from P6 .xml exports in blenderBIM
This commit is contained in:
@@ -1,6 +1,4 @@
|
||||
import ifcopenshell.util.date
|
||||
from datetime import datetime
|
||||
from datetime import timedelta
|
||||
|
||||
class Usecase:
|
||||
def __init__(self, file, **settings):
|
||||
|
||||
@@ -154,7 +154,8 @@ class Data:
|
||||
continue
|
||||
if "Start" in key or "Finish" in key or key == "StatusTime":
|
||||
data[key] = ifcopenshell.util.date.ifc2datetime(value)
|
||||
# TODO parse duration
|
||||
elif key == "ScheduleDuration":
|
||||
data[key] = ifcopenshell.util.date.ifc2datetime(value)
|
||||
cls.task_times[task_time.id()] = data
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -13,4 +13,7 @@ class Usecase:
|
||||
if "Start" in name or "Finish" in name or name == "StatusTime":
|
||||
if value:
|
||||
value = ifcopenshell.util.date.datetime2ifc(value, "IfcDateTime")
|
||||
if name == "ScheduleDuration":
|
||||
if value:
|
||||
value = ifcopenshell.util.date.datetime2ifc(value, "IfcDuration")
|
||||
setattr(self.settings["task_time"], name, value)
|
||||
|
||||
@@ -1,6 +1,39 @@
|
||||
import datetime
|
||||
from re import findall
|
||||
|
||||
# https://gist.github.com/spatialtime/c1924a3b178b4fe721fe406e0bf1a1dc
|
||||
import re
|
||||
from datetime import timedelta
|
||||
|
||||
|
||||
def format_duration(td):
|
||||
s = td.seconds
|
||||
ms = td.microseconds
|
||||
if ms != 0: # Round microseconds to milliseconds.
|
||||
ms /= 1000000
|
||||
ms = round(ms,3)
|
||||
s += ms
|
||||
return "P{}DT{}S".format(td.days,s)
|
||||
|
||||
def parse_duration(iso_duration):
|
||||
m = re.match(r'^P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)D)?T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:.\d+)?)S)?$',
|
||||
iso_duration)
|
||||
if m is None:
|
||||
raise ValueError("invalid ISO 8601 duration string")
|
||||
days = 0
|
||||
hours = 0
|
||||
minutes = 0
|
||||
seconds = 0.0
|
||||
if m[3]:
|
||||
days = int(m[3])
|
||||
if m[4]:
|
||||
hours = int(m[4])
|
||||
if m[5]:
|
||||
minutes = int(m[5])
|
||||
if m[6]:
|
||||
seconds = float(m[6])
|
||||
return timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds)
|
||||
|
||||
|
||||
def duration2dict(duration):
|
||||
results = {}
|
||||
@@ -11,7 +44,7 @@ def duration2dict(duration):
|
||||
|
||||
def ifc2datetime(element):
|
||||
if isinstance(element, str) and element[0] == "P": # IfcDuration
|
||||
return duration2dict(element)
|
||||
return parse_duration(element)
|
||||
elif isinstance(element, str) and element[2] == ":": # IfcTime
|
||||
return datetime.time.fromisoformat(element)
|
||||
elif isinstance(element, str) and ":" in element: # IfcDateTime
|
||||
@@ -39,8 +72,10 @@ def ifc2datetime(element):
|
||||
|
||||
|
||||
def datetime2ifc(dt, ifc_type):
|
||||
if isinstance(dt, str):
|
||||
if isinstance(dt, str) and ifc_type != "IfcDuration":
|
||||
dt = datetime.datetime.fromisoformat(dt)
|
||||
if ifc_type == "IfcDuration":
|
||||
return format_duration(dt)
|
||||
if ifc_type == "IfcTimeStamp":
|
||||
return int(dt.timestamp())
|
||||
elif ifc_type == "IfcDateTime":
|
||||
|
||||
Reference in New Issue
Block a user