Skip to content

Commit 2147948

Browse files
committed
Fix bug where MS project durations expressed in hours were not parsed correctly
1 parent 97c660f commit 2147948

1 file changed

Lines changed: 14 additions & 1 deletion

File tree

src/ifc4d/ifc4d/msp2ifc.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def parse_xml(self):
4646
self.ns = {"pr": project.tag[1:].partition("}")[0]}
4747
self.project["Name"] = project.findtext("pr:Name", namespaces=self.ns) or "Unnamed"
4848
self.project["CalendarUID"] = project.findtext("pr:CalendarUID", namespaces=self.ns) or None
49+
self.project["MinutesPerDay"] = project.findtext("pr:MinutesPerDay", namespaces=self.ns) or None
4950
self.outline_level = 0
5051
self.outline_parents = {}
5152
self.parse_task_xml(project)
@@ -66,6 +67,11 @@ def parse_relationship_xml(self, task):
6667
return relationships
6768

6869
def parse_task_xml(self, project):
70+
if self.project["MinutesPerDay"]:
71+
hours_per_day = int(self.project["MinutesPerDay"]) / 60
72+
else:
73+
hours_per_day = 8
74+
6975
for task in project.find("pr:Tasks", self.ns):
7076
task_id = task.find("pr:UID", self.ns).text
7177
task_index_level = task.find("pr:OutlineLevel", self.ns).text
@@ -79,13 +85,20 @@ def parse_task_xml(self, project):
7985
self.outline_level = outline_level
8086
self.outline_parents[outline_level] = task_id
8187

88+
# Microsoft Project stores durations in terms of hours.
89+
duration = ifcopenshell.util.date.ifc2datetime(task.find("pr:Duration", self.ns).text)
90+
hours = duration.days * 24
91+
hours += duration.seconds / 60 / 60
92+
# Let's convert it into days, where days is the appropriate hours per day
93+
duration = timedelta(days=hours / float(hours_per_day))
94+
8295
self.tasks[task_id] = {
8396
"Name": task.find("pr:Name", self.ns).text,
8497
"OutlineNumber": task.find("pr:OutlineNumber", self.ns).text,
8598
"OutlineLevel": outline_level,
8699
"Start": datetime.datetime.fromisoformat(task.find("pr:Start", self.ns).text),
87100
"Finish": datetime.datetime.fromisoformat(task.find("pr:Finish", self.ns).text),
88-
"Duration": ifcopenshell.util.date.ifc2datetime(task.find("pr:Duration", self.ns).text),
101+
"Duration": duration,
89102
"Priority": task.find("pr:Priority", self.ns).text,
90103
"CalendarUID": task.find("pr:CalendarUID", self.ns).text,
91104
"PredecessorTasks": relationships if relationships else None,

0 commit comments

Comments
 (0)