diff --git a/agenda/data.py b/agenda/data.py
index ae050bd..db320e3 100644
--- a/agenda/data.py
+++ b/agenda/data.py
@@ -36,6 +36,7 @@ from . import (
     uk_holiday,
 )
 from .types import Event, StrDict
+from .utils import time_function
 
 here = dateutil.tz.tzlocal()
 
@@ -94,22 +95,6 @@ def find_events_during_stay(
     return overlapping_markets
 
 
-async def time_function(
-    name: str,
-    func: typing.Callable[..., typing.Coroutine[typing.Any, typing.Any, typing.Any]],
-    *args: typing.Any,
-    **kwargs: typing.Any,
-) -> tuple[str, typing.Any, float, Exception | None]:
-    """Time the execution of an asynchronous function."""
-    start_time, result, exception = time(), None, None
-    try:
-        result = await func(*args, **kwargs)
-    except Exception as e:
-        exception = e
-    end_time = time()
-    return name, result, end_time - start_time, exception
-
-
 def hide_markets_while_away(
     events: list[Event], accommodation_events: list[Event]
 ) -> None:
diff --git a/agenda/utils.py b/agenda/utils.py
index 00a4e50..656a60f 100644
--- a/agenda/utils.py
+++ b/agenda/utils.py
@@ -1,7 +1,9 @@
 """Utility functions."""
 
 import os
+import typing
 from datetime import date, datetime, timezone
+from time import time
 
 
 def as_date(d: datetime | date) -> date:
@@ -84,3 +86,19 @@ def make_waste_dir(data_dir: str) -> None:
     waste_dir = os.path.join(data_dir, "waste")
     if not os.path.exists(waste_dir):
         os.mkdir(waste_dir)
+
+
+async def time_function(
+    name: str,
+    func: typing.Callable[..., typing.Coroutine[typing.Any, typing.Any, typing.Any]],
+    *args: typing.Any,
+    **kwargs: typing.Any,
+) -> tuple[str, typing.Any, float, Exception | None]:
+    """Time the execution of an asynchronous function."""
+    start_time, result, exception = time(), None, None
+    try:
+        result = await func(*args, **kwargs)
+    except Exception as e:
+        exception = e
+    end_time = time()
+    return name, result, end_time - start_time, exception