From 01b42845c3974da7b79b738f05399c34f87372c8 Mon Sep 17 00:00:00 2001
From: Edward Betts <edward@4angle.com>
Date: Mon, 1 Jul 2024 22:22:01 +0300
Subject: [PATCH] Move some functions into a utils module

---
 agenda/types.py | 42 +++++++++++-------------------------------
 agenda/utils.py | 23 +++++++++++++++++++++++
 2 files changed, 34 insertions(+), 31 deletions(-)
 create mode 100644 agenda/utils.py

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)
+    )