diff --git a/program/filters.py b/program/filters.py
index af8421a919ffd1607b6c29dff3c70cec61654275..1c771bfab3631a1a474a4d71dc1d6498dff08899 100644
--- a/program/filters.py
+++ b/program/filters.py
@@ -300,6 +300,13 @@ class ActiveFilterSet(StaticFilterHelpTextMixin, filters.FilterSet):
 class VirtualTimeslotFilterSet(filters.FilterSet):
     start = filters.IsoDateTimeFilter(method="filter_noop")
     end = filters.IsoDateTimeFilter(method="filter_noop")
+    cut_at_range_boundaries = filters.BooleanFilter(
+        help_text=(
+            "If true guarantees that the first and last program entry match the requested range"
+            "even if these entries earlier or end later."
+        ),
+        method="filter_noop",
+    )
     include_virtual = filters.BooleanFilter(
         help_text="Include virtual timeslot entries (default: false).",
         method="filter_noop",
@@ -320,6 +327,7 @@ class VirtualTimeslotFilterSet(filters.FilterSet):
                 start=filter_data["start"],
                 end=filter_data["end"],
                 include_virtual=filter_data["include_virtual"],
+                cut_at_range_boundaries=filter_data["cut_at_range_boundaries"],
             )
         )
 
diff --git a/program/services.py b/program/services.py
index baba59fa17f5cf17b42d26b10c0c9f2b5b3edb7f..d1a17fe27b4ac2c50f536dc62013c5615b893d1e 100644
--- a/program/services.py
+++ b/program/services.py
@@ -717,26 +717,31 @@ def generate_program_entries(
     start: datetime | None,
     end: datetime | None,
     include_virtual: bool,
+    cut_at_range_boundaries: bool,
 ) -> Iterator[ProgramEntry]:
     """Gets list of timerange entries between the given `timerange_start` and `timerange_end`.
 
     Include virtual timerange entries if requested."""
 
-    def create_entry(start: datetime, end: datetime, show: Show, timeslot: TimeSlot | None = None):
+    def create_entry(
+        starts_at: datetime, ends_at: datetime, show: Show, timeslot: TimeSlot | None = None
+    ):
+        entry_id = f"{starts_at.isoformat()}...{ends_at.isoformat()}"
+        if cut_at_range_boundaries:
+            starts_at = max(starts_at, start)
+            ends_at = min(ends_at, end)
         return ProgramEntry(
-            id=f"{start.isoformat()}...{end.isoformat()}",
-            start=start,
-            end=end,
+            id=entry_id,
+            start=starts_at,
+            end=ends_at,
             timeslot=timeslot,
             show=show,
         )
 
     def create_timeslot_entry(timeslot: TimeSlot):
         return create_entry(
-            # Ensure the program entry never starts before the requested start
-            # and never ends after the requested end.
-            max(timeslot.start, start),
-            min(timeslot.end, end),
+            timeslot.start,
+            timeslot.end,
             timeslot.schedule.show,
             timeslot,
         )