diff --git a/agenda/types.py b/agenda/types.py index 6d18909..a8f3a8f 100644 --- a/agenda/types.py +++ b/agenda/types.py @@ -12,28 +12,12 @@ from pycountry.db import Country import agenda from agenda import format_list_with_ampersand +from . import utils + StrDict = dict[str, typing.Any] DateOrDateTime = datetime.datetime | datetime.date -def as_date(d: DateOrDateTime) -> datetime.date: - """Convert datetime to date.""" - if isinstance(d, datetime.datetime): - return d.date() - assert isinstance(d, datetime.date) - return d - - -def as_datetime(d: DateOrDateTime) -> datetime.datetime: - """Date/time of event.""" - t0 = datetime.datetime.min.time() - return ( - d - if isinstance(d, datetime.datetime) - else datetime.datetime.combine(d, t0).replace(tzinfo=datetime.timezone.utc) - ) - - @dataclass class TripElement: """Trip element.""" @@ -106,18 +90,20 @@ class Trip: def end(self) -> datetime.date | None: """End date for trip.""" max_conference_end = ( - max(as_date(item["end"]) for item in self.conferences) + max(utils.as_date(item["end"]) for item in self.conferences) if self.conferences else datetime.date.min ) assert isinstance(max_conference_end, datetime.date) - arrive = [as_date(item["arrive"]) for item in self.travel if "arrive" in item] + arrive = [ + utils.as_date(item["arrive"]) for item in self.travel if "arrive" in item + ] travel_end = max(arrive) if arrive else datetime.date.min assert isinstance(travel_end, datetime.date) accommodation_end = ( - max(as_date(item["to"]) for item in self.accommodation) + max(utils.as_date(item["to"]) for item in self.accommodation) if self.accommodation else datetime.date.min ) @@ -314,7 +300,7 @@ class Trip: ) ) - return sorted(elements, key=lambda e: as_datetime(e.start_time)) + return sorted(elements, key=lambda e: utils.as_datetime(e.start_time)) def elements_grouped_by_day(self) -> list[tuple[datetime.date, list[TripElement]]]: """Group trip elements by day.""" @@ -325,7 +311,7 @@ class Trip: for element in self.elements(): # Extract the date part of the 'when' attribute - day = as_date(element.start_time) + day = utils.as_date(element.start_time) grouped_elements[day].append(element) # Sort elements within each day @@ -334,7 +320,7 @@ class Trip: key=lambda e: ( e.element_type == "check-in", # check-out elements last e.element_type != "check-out", # check-in elements first - as_datetime(e.start_time), # then sort by time + utils.as_datetime(e.start_time), # then sort by time ) ) @@ -403,13 +389,7 @@ class Event: @property def as_datetime(self) -> datetime.datetime: """Date/time of event.""" - d = self.date - t0 = datetime.datetime.min.time() - return ( - d - if isinstance(d, datetime.datetime) - else datetime.datetime.combine(d, t0).replace(tzinfo=datetime.timezone.utc) - ) + return utils.as_datetime(self.date) @property def has_time(self) -> bool: diff --git a/agenda/utils.py b/agenda/utils.py new file mode 100644 index 0000000..0324df3 --- /dev/null +++ b/agenda/utils.py @@ -0,0 +1,23 @@ +"""Utility functions.""" + +import datetime + +DateOrDateTime = datetime.datetime | datetime.date + + +def as_date(d: DateOrDateTime) -> datetime.date: + """Convert datetime to date.""" + if isinstance(d, datetime.datetime): + return d.date() + assert isinstance(d, datetime.date) + return d + + +def as_datetime(d: DateOrDateTime) -> datetime.datetime: + """Date/time of event.""" + t0 = datetime.datetime.min.time() + return ( + d + if isinstance(d, datetime.datetime) + else datetime.datetime.combine(d, t0).replace(tzinfo=datetime.timezone.utc) + )