research

split and calendar math

A paper on logit’s date model: why workout dates are stored as normalized day values, how Pacific time defines today, how Monday-first weeks and month grids are built, and how split templates become enforceable schedules.

1. Date-only storage without timezone drift

logit treats workout dates as calendar facts rather than timestamp moments. To keep a date stable across parsing, formatting, and timezone transitions, the stored date is normalized to a UTC-noon value for the intended year, month, and day.

dstore=UTC⁡(y,m,d,12:00)d_{\mathrm{store}} = \operatorname{UTC}(y, m, d, 12{:}00)dstore​=UTC(y,m,d,12:00)
Interpretation. The noon anchor keeps date-only records from drifting backward or forward when the surrounding environment crosses local timezone boundaries.

The product then formats and compares these values as normalized dates, not as wall clock times. That is why the schedule behaves like a calendar instead of like a timestamped event log.

2. Pacific "today" and parsed inputs

The app defines today from the Pacific calendar, not from the user's machine locale and not from UTC midnight. This keeps daily scheduling aligned with the product's intended operating timezone.

dtoday=dateParts⁡America/Los Angeles(now)d_{\mathrm{today}} = \operatorname{dateParts}_{\mathrm{America/Los\ Angeles}}(\text{now})dtoday​=datePartsAmerica/Los Angeles​(now)
Interpretation. The current Pacific date is extracted first, and only then converted into the normalized stored-date format.

When a user types an explicit YYYY-MM-DD date, logit preserves that exact calendar value if it parses cleanly. If parsing fails, the system falls back to the current normalized date rather than leaving the schedule in an undefined state.

3. Monday-first week and month-grid construction

Weeks start on Monday throughout the product. The dashboard's weekly summaries and the calendar grid both derive their start point from the same Monday-first rule.

offset=(utcDay+6) mod 7\mathrm{offset} = (\mathrm{utcDay} + 6) \bmod 7offset=(utcDay+6)mod7weekStart=d−offset\mathrm{weekStart} = d - \mathrm{offset}weekStart=d−offset
Interpretation. Sunday becomes offset six, Monday becomes offset zero, and every other weekday lands between them. The calendar grid then walks forward from the computed Monday start.

Month views use the same logic. The grid starts on the Monday that contains the first day of the month and extends to a fixed forty-two-day layout so the visual calendar stays structurally stable across months.

4. Split normalization and weekday integrity

A split is never stored as a partial or ambiguously ordered week. Incoming split payloads are normalized into a complete Monday-through-Sunday template. Missing days become explicit rest days, duplicate weekdays are rejected, and the final template is sorted into weekday order.

splitWeek=sort⁡ ⁣(providedDays∪defaultRestDays)\mathrm{splitWeek} = \operatorname{sort}\!\left(\mathrm{providedDays} \cup \mathrm{defaultRestDays}\right)splitWeek=sort(providedDays∪defaultRestDays)
Interpretation. The saved split is always a seven-day object with one slot per weekday. Structural ambiguity is removed before persistence.
ConditionNormalization result
Missing weekdayFilled as a Rest day with no exercises
Duplicate weekdayRejected before the split can be saved
Out-of-order weekdaysSorted back into Monday-through-Sunday order
Blank split nameFalls back to "Weekly Split"

5. Rest-day enforcement and preload logic

Once the split is normalized, it becomes actionable. If the selected day is a rest day, the logger is disabled for that date and workout creation is rejected. If the day is active, the logger preloads the configured workout type and exercise rows so the user starts from the planned template rather than from an empty form.

The same split seed also drives today's plan on the dashboard: no split yields a setup prompt, a rest day yields a recovery label, and an active day yields a count of planned exercises ready to preload.