diff --git a/src/ifcopenshell-python/ifcopenshell/api/cost/add_cost_schedule.py b/src/ifcopenshell-python/ifcopenshell/api/cost/add_cost_schedule.py index d85534bb83..19f0762b69 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/cost/add_cost_schedule.py +++ b/src/ifcopenshell-python/ifcopenshell/api/cost/add_cost_schedule.py @@ -17,7 +17,7 @@ # along with IfcOpenShell. If not, see . import ifcopenshell.api.root -import ifcopenshell.util.date +import ifcopenshell.api.sequence from datetime import datetime from typing import Optional @@ -58,17 +58,5 @@ def add_cost_schedule( predefined_type=predefined_type, name=name, ) - if file.schema == "IFC2X3": - cost_schedule.UpdateDate = createIfcDateAndTime(file, datetime.now()) - else: - cost_schedule.UpdateDate = ifcopenshell.util.date.datetime2ifc(datetime.now(), "IfcDateTime") + cost_schedule.UpdateDate = ifcopenshell.api.sequence.add_date_time(file, datetime.now()) return cost_schedule - - -def createIfcDateAndTime(file: ifcopenshell.file, dt: datetime): - ifc_dt = file.create_entity("IfcDateAndTime") - ifc_dt.DateComponent = file.create_entity( - "IfcCalendarDate", **ifcopenshell.util.date.datetime2ifc(dt, "IfcCalendarDate") - ) - ifc_dt.TimeComponent = file.create_entity("IfcLocalTime", **ifcopenshell.util.date.datetime2ifc(dt, "IfcLocalTime")) - return ifc_dt diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/__init__.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/__init__.py index b0bf2344b7..5d48666ea7 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/sequence/__init__.py +++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/__init__.py @@ -23,6 +23,7 @@ managing recurring facility maintenance schedules. """ from .. import wrap_usecases +from .add_date_time import add_date_time from .add_task import add_task from .add_task_time import add_task_time from .add_time_period import add_time_period @@ -70,6 +71,7 @@ from .unassign_sequence import unassign_sequence wrap_usecases(__path__, __name__) __all__ = [ + "add_date_time", "add_task", "add_task_time", "add_time_period", diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_date_time.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_date_time.py new file mode 100644 index 0000000000..96017a0807 --- /dev/null +++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_date_time.py @@ -0,0 +1,59 @@ +# IfcOpenShell - IFC toolkit and geometry engine +# Copyright (C) 2021 Dion Moult +# +# This file is part of IfcOpenShell. +# +# IfcOpenShell is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# IfcOpenShell is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with IfcOpenShell. If not, see . + +import ifcopenshell.util.date +from datetime import datetime +from typing import Union + + +def add_date_time(file: ifcopenshell.file, dt: datetime) -> Union[str, ifcopenshell.entity_instance]: + """Add a new date time. + + Depending on ``file``'s schema method will: + - IFC2X3 - create IfcDateAndTime entity + - IFC4+ - create IfcDatetime formatted string + + :param dt: datetime to convert to IFC. + :return: IfcDateAndTime entity or IfcDatetime string. + + Example: + + .. code:: python + + dt = datetime(2025, 3, 1, 12, 31, 24) + datetime_ifc = ifcopenshell.api.sequence.add_date_time(self.file, dt) + + # IFC2X3: #1=IfcDateAndTime(#2,#3) + # IFC4+: "2025-03-01T12:31:24" + print(datetime_ifc) + + """ + + if file.schema == "IFC2X3": + ifc_dt = file.create_entity("IfcDateAndTime") + calendar_date_data = ifcopenshell.util.date.datetime2ifc(dt, "IfcCalendarDate") + assert isinstance(calendar_date_data, dict) + ifc_dt.DateComponent = file.create_entity("IfcCalendarDate", **calendar_date_data) + local_time_data = ifcopenshell.util.date.datetime2ifc(dt, "IfcLocalTime") + assert isinstance(local_time_data, dict) + ifc_dt.TimeComponent = file.create_entity("IfcLocalTime", **local_time_data) + return ifc_dt + + dt_str = ifcopenshell.util.date.datetime2ifc(dt, "IfcDateTime") + assert isinstance(dt_str, str) + return dt_str diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_plan.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_plan.py index 2cb4f05ec6..7754446882 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_plan.py +++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_plan.py @@ -19,7 +19,7 @@ import ifcopenshell.api.root import ifcopenshell.api.project import ifcopenshell.api.owner.settings -import ifcopenshell.util.date +import ifcopenshell.api.sequence from datetime import datetime, time from typing import Optional, Union @@ -65,11 +65,11 @@ def add_work_plan( predefined_type=predefined_type, name=name, ) - work_plan.CreationDate = ifcopenshell.util.date.datetime2ifc(datetime.now(), "IfcDateTime") + work_plan.CreationDate = ifcopenshell.api.sequence.add_date_time(file, datetime.now()) user = ifcopenshell.api.owner.settings.get_user(file) if user: work_plan.Creators = [user.ThePerson] - work_plan.StartTime = ifcopenshell.util.date.datetime2ifc(start_time, "IfcDateTime") + work_plan.StartTime = ifcopenshell.api.sequence.add_date_time(file, datetime.now()) context = file.by_type("IfcContext")[0] ifcopenshell.api.project.assign_declaration( diff --git a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_schedule.py b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_schedule.py index 1c964486ef..35fa1052ce 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_schedule.py +++ b/src/ifcopenshell-python/ifcopenshell/api/sequence/add_work_schedule.py @@ -20,7 +20,7 @@ import ifcopenshell.api.root import ifcopenshell.api.project import ifcopenshell.api.aggregate import ifcopenshell.api.owner.settings -import ifcopenshell.util.date +import ifcopenshell.api.sequence from datetime import time from datetime import datetime from typing import Union, Optional @@ -81,17 +81,11 @@ def add_work_schedule( predefined_type=predefined_type, name=name, ) - if file.schema == "IFC2X3": - work_schedule.CreationDate = createIfcDateAndTime(file, datetime.now()) - else: - work_schedule.CreationDate = ifcopenshell.util.date.datetime2ifc(datetime.now(), "IfcDateTime") + work_schedule.CreationDate = ifcopenshell.api.sequence.add_date_time(file, datetime.now()) user = ifcopenshell.api.owner.settings.get_user(file) if user: work_schedule.Creators = [user.ThePerson] - if file.schema == "IFC2X3": - work_schedule.StartTime = createIfcDateAndTime(file, start_time) - else: - work_schedule.StartTime = ifcopenshell.util.date.datetime2ifc(start_time, "IfcDateTime") + work_schedule.StartTime = ifcopenshell.api.sequence.add_date_time(file, start_time) if object_type: work_schedule.ObjectType = object_type if work_plan: @@ -110,12 +104,3 @@ def add_work_schedule( relating_context=context, ) return work_schedule - - -def createIfcDateAndTime(file: ifcopenshell.file, dt: datetime): - ifc_dt = file.create_entity("IfcDateAndTime") - ifc_dt.DateComponent = file.create_entity( - "IfcCalendarDate", **ifcopenshell.util.date.datetime2ifc(dt, "IfcCalendarDate") - ) - ifc_dt.TimeComponent = file.create_entity("IfcLocalTime", **ifcopenshell.util.date.datetime2ifc(dt, "IfcLocalTime")) - return ifc_dt diff --git a/src/ifcopenshell-python/test/api/sequence/test_add_date_time.py b/src/ifcopenshell-python/test/api/sequence/test_add_date_time.py new file mode 100644 index 0000000000..3b5d5ac15c --- /dev/null +++ b/src/ifcopenshell-python/test/api/sequence/test_add_date_time.py @@ -0,0 +1,44 @@ +# IfcOpenShell - IFC toolkit and geometry engine +# Copyright (C) 2021 Dion Moult +# +# This file is part of IfcOpenShell. +# +# IfcOpenShell is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# IfcOpenShell is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with IfcOpenShell. If not, see . + +import ifcopenshell.util +import ifcopenshell.util.date +import test.bootstrap +import ifcopenshell.api.sequence +from datetime import datetime + + +class TestAddDateTime(test.bootstrap.IFC4): + def test_run(self): + dt = datetime(2025, 3, 1, 12, 31, 24) + res = ifcopenshell.api.sequence.add_date_time(self.file, dt) + if self.file.schema == "IFC2X3": + assert isinstance(res, ifcopenshell.entity_instance) + assert res.is_a("IfcDateAndTime") + assert ifcopenshell.util.date.ifc2datetime(res) == dt + print(res) + else: + assert res == "2025-03-01T12:31:24" + + +class TestAddDateTimeIFC2X3(test.bootstrap.IFC2X3, TestAddDateTime): + pass + + +class TestAddDateTimeIFC4X3(test.bootstrap.IFC4X3, TestAddDateTime): + pass