feat(dates): calendar-day date filters in the owner's display zone (#152) #178

Merged
cameron merged 2 commits from fix/calendar-day-date-filters into master 2026-10-17 03:25:05 +00:00
Owner

Closes the last open item on #152: clients filter by calendar day without doing any time-zone math.

Problem

The server side of #152 (true-instant filtering, PR #162) is done. Clients still built calendar-day ranges as device-local midnights, though: FileViewer's startOfDay/endOfDay, its presets and the custom picker. Whenever the phone's zone differs from the owner's display_tz (travel), a range shifts by the offset, so a photo can show inside a day in the grid but fall out of that day's filter.

Fix

/photos, /photos/exif and /photos/search/unified accept date_from_day / date_to_day (YYYY-MM-DD). date_view::apply_day_bounds turns them into the first day's start and the last day's end in the owner's display zone, the same days /memories groups by, using day_start_instant, so DST days are handled. Each day param replaces its instant counterpart, and an unparseable day is ignored. Requests without day params never read prefs.

date_from / date_to (instants) are unchanged and still right for windows around a moment (FileViewer's messages photo sheet; Apollo's track matching).

Also fixes the stale list_exif_summary doc comment (it still said date_taken), and documents the params in CLAUDE.md.

The client half is in FileViewer-React's fix/calendar-day-date-filters PR. Deploy this first: an older server ignores the day params and drops the date filter.

Tests

  • day_bounds_are_the_display_zone_day: July 5 for a NY owner vs a Tokyo owner, plus a 23-hour DST day.
  • day_bounds_replace_their_side_only_and_skip_bad_input: also checks prefs aren't read when no day param is given.
  • e2e: check_wall_clock.py now also asserts, for every fixture, that its display-zone day includes it and the days either side exclude it. I ran it against a fresh instance of this branch on another port: 97/97.
  • Full suite passes and clippy is clean.

🤖 Generated with Claude Code

Closes the last open item on #152: clients filter by calendar day without doing any time-zone math. ## Problem The server side of #152 (true-instant filtering, PR #162) is done. Clients still built calendar-day ranges as **device-local** midnights, though: FileViewer's `startOfDay`/`endOfDay`, its presets and the custom picker. Whenever the phone's zone differs from the owner's `display_tz` (travel), a range shifts by the offset, so a photo can show inside a day in the grid but fall out of that day's filter. ## Fix `/photos`, `/photos/exif` and `/photos/search/unified` accept **`date_from_day` / `date_to_day`** (`YYYY-MM-DD`). `date_view::apply_day_bounds` turns them into the first day's start and the last day's end in the owner's display zone, the same days `/memories` groups by, using `day_start_instant`, so DST days are handled. Each day param replaces its instant counterpart, and an unparseable day is ignored. Requests without day params never read prefs. `date_from` / `date_to` (instants) are unchanged and still right for windows around a moment (FileViewer's messages photo sheet; Apollo's track matching). Also fixes the stale `list_exif_summary` doc comment (it still said `date_taken`), and documents the params in CLAUDE.md. The client half is in FileViewer-React's `fix/calendar-day-date-filters` PR. **Deploy this first**: an older server ignores the day params and drops the date filter. ## Tests - `day_bounds_are_the_display_zone_day`: July 5 for a NY owner vs a Tokyo owner, plus a 23-hour DST day. - `day_bounds_replace_their_side_only_and_skip_bad_input`: also checks prefs aren't read when no day param is given. - **e2e:** `check_wall_clock.py` now also asserts, for every fixture, that its display-zone day includes it and the days either side exclude it. I ran it against a fresh instance of this branch on another port: **97/97**. - Full suite passes and clippy is clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
cameron added 2 commits 2026-10-17 03:24:52 +00:00
/photos, /photos/exif and unified search take date_from_day /
date_to_day (YYYY-MM-DD): the server turns them into the first day's
start and the last day's end in the owner's display zone, the same days
/memories groups by. Each replaces its instant counterpart. Clients stop
computing midnights in the device's zone, which drifted by the travel
offset whenever the phone's zone differed from display_tz.

e2e check: every fixture is included by its display-zone day and
excluded by the days either side.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cameron force-pushed fix/calendar-day-date-filters from ebafa0deca to 139de444af 2026-10-17 03:24:52 +00:00 Compare
cameron merged commit 200abf9a10 into master 2026-10-17 03:25:05 +00:00
cameron deleted branch fix/calendar-day-date-filters 2026-10-17 03:25:06 +00:00
Sign in to join this conversation.