Initial commit
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
from datetime import datetime, time, timedelta
|
||||
from typing import List
|
||||
|
||||
|
||||
def get_day_night_splits(
|
||||
session_start: datetime,
|
||||
session_end: datetime,
|
||||
day_start_boundary: time,
|
||||
day_end_boundary: time,
|
||||
) -> List[dict]:
|
||||
"""
|
||||
Splits a sleep session into day and night segments based on boundaries.
|
||||
A segment is defined by [segment_start, segment_end] and its type (day/night).
|
||||
"""
|
||||
segments = []
|
||||
points = [session_start, session_end]
|
||||
|
||||
for offset in [0, 1]:
|
||||
base_date = session_start.date() + timedelta(days=offset)
|
||||
try:
|
||||
b1 = datetime.combine(base_date, day_start_boundary).replace(
|
||||
tzinfo=session_start.tzinfo
|
||||
)
|
||||
b2 = datetime.combine(base_date, day_end_boundary).replace(
|
||||
tzinfo=session_start.tzinfo
|
||||
)
|
||||
if session_start < b1 < session_end:
|
||||
points.append(b1)
|
||||
if session_start < b2 < session_end:
|
||||
points.append(b2)
|
||||
except (ValueError, AttributeError):
|
||||
continue
|
||||
|
||||
sorted_points = sorted(list(set(points)))
|
||||
|
||||
for i in range(len(sorted_points) - 1):
|
||||
seg_start = sorted_points[i]
|
||||
seg_end = sorted_points[i + 1]
|
||||
midpoint = seg_start + (seg_end - seg_start) / 2
|
||||
is_day = day_start_pattern(
|
||||
midpoint.time(), day_start_boundary, day_end_boundary
|
||||
)
|
||||
segments.append(
|
||||
{"start": seg_start, "end": seg_end, "type": "day" if is_day else "night"}
|
||||
)
|
||||
|
||||
return segments
|
||||
|
||||
|
||||
def day_start_pattern(current_time: time, start: time, end: time) -> bool:
|
||||
if start <= end:
|
||||
return start <= current_time < end
|
||||
else: # Spans midnight
|
||||
return current_time >= start or current_time < end
|
||||
|
||||
|
||||
from datetime import datetime, time, timedelta
|
||||
|
||||
|
||||
def minutes_after(dt: datetime, reference: time) -> float:
|
||||
"""Returns minutes after a reference time."""
|
||||
ref_delta = timedelta(hours=reference.hour, minutes=reference.minute)
|
||||
dt_delta = timedelta(hours=dt.hour, minutes=dt.minute)
|
||||
return (dt_delta - ref_delta).total_seconds() / 60.0
|
||||
Reference in New Issue
Block a user