Skip to content

docs(working-hours): state that hours are the physical location's local time - #2907

Merged
DonKoko merged 2 commits into
mainfrom
docs/working-hours-are-location-local
Aug 20, 2026
Merged

DonKoko merged 2 commits into
mainfrom
docs/working-hours-are-location-local

Conversation

@DonKoko

@DonKoko DonKoko commented Aug 20, 2026 •

Copy link
Copy Markdown
Contributor

Working hours describe when a physical place is open, so both the weekly times and the date overrides are absolute and location-local — never relative to whoever is looking. "Open 9–5" means 9–5 where the assets are; it does not become 2–10 because the person reading it is in another country.

The schema already says this on WorkingHours.weeklySchedule — "no timezone conversion … interpreted as local wall time, not UTC" — but nothing surfaced it to users or contributors, and it has caused confusion more than once.

The settings copy said the opposite

Set your working hours for each day of the week. Times will be displayed in your local format.

That reads as though hours are viewer-relative. Replaced with a statement that they are the location's local hours and are not converted for anyone. The booking form's working-hours info box gets the same note, since that is where the constraint is actually felt.

The rule

.claude/rules/working-hours-are-location-local.md records the semantics and — more usefully — which half is enforced and which isn't:

  • Dates: enforced. getOverrideDateKey() reads an override's day from UTC, because the column is @db.Date and Prisma hydrates it at UTC midnight. Formatting that instant in a local zone shifted it a day west of UTC, which made a "closed on the 24th" override match bookings on the 23rd.
  • Times: not enforced, knowingly. validateWorkingHours and getBookingDefaultStartEndTimes compare against the acting user's preference zone, so an Amsterdam org's 9–5 is judged in Tokyo wall time for a Tokyo user.

Why the second one is accepted rather than fixed

There is no Organization.timeZone / WorkingHours.timeZone to evaluate against, and in practice the people constrained by an org's working hours are at or near that location. Fixing it properly means storing the location's zone — migration, settings UI, backfill decision — which isn't worth it for the ~0.1% case of someone booking from another timezone.

The rule states that plainly so nobody re-files it as a bug or "fixes" it by threading more user-zone logic through working hours. If it ever does need solving, the answer is a stored location zone, not a different user-side zone.

Also corrects the note at prefsForDeclaredZone (added in #2896), which framed the same gap as a deferred product decision. It's the same rule reached from the client side, and now points at the rule file.

Scope

Copy and documentation only — no behaviour change. Typecheck clean; 127 tests pass across the booking, working-hours and date-fns suites.

Related: #2896 (decode direction), #2905 (produce direction).

Summary by CodeRabbit

  • Documentation
    • Clarified that working-hour dates use the physical location’s local calendar.
    • Documented that schedule times are based on the location’s wall-clock time and are not converted to the viewer’s timezone.
    • Added guidance explaining how working hours are represented during booking.
    • Updated internal documentation regarding timezone handling and future improvements.

…al time

Working hours describe when a physical place is open, so both the weekly times
and the date overrides are absolute and location-local — never relative to
whoever is looking. The schema already says this on `WorkingHours.weeklySchedule`
("no timezone conversion … interpreted as local wall time, not UTC"), but nothing
surfaced it to users or to contributors, and it has caused confusion before.

The Weekly Schedule settings copy actively said the opposite: "Times will be
displayed in your local format", which reads as though hours are viewer-relative.
Replaced with a statement that they are the location's local hours and are not
converted for anyone. The booking form's working-hours info box gains the same
note, since that is where the constraint is actually felt.

Adds `.claude/rules/working-hours-are-location-local.md` recording the semantics,
which half is enforced, and which is not:

- DATES are enforced — `getOverrideDateKey()` reads the override day from UTC
  because the column is `@db.Date` and Prisma hydrates it at UTC midnight;
  formatting that instant locally shifted it a day west of UTC.
- TIMES are not. `validateWorkingHours` and `getBookingDefaultStartEndTimes`
  compare against the acting user's preference zone, so an Amsterdam org's 9-5 is
  judged in Tokyo wall time for a Tokyo user.

That second gap is now an explicitly accepted risk rather than an open question.
There is no `Organization.timeZone` to evaluate against, and the people
constrained by an org's hours are at that location in practice; a stored location
zone (migration + settings UI + backfill) is not worth it for the ~0.1% case. The
rule says so plainly so nobody re-files it as a bug or "fixes" it by threading
more user-zone logic through working hours.

Also corrects the note at `prefsForDeclaredZone`, which framed the same gap as a
deferred product decision. It is the same rule reached from the client side, and
now points at the rule file.
@github-actions

Copy link
Copy Markdown

🩺 React Doctor — webapp

✅ No new findings on the files changed by this PR.

Run locally with pnpm webapp:doctor for a full scan, or cd apps/webapp && pnpm exec react-doctor . --diff for the same diff-only view.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d35fcc4371

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +172 to +174
<strong>local hours of your physical location</strong> — they are
not converted to anyone&apos;s timezone, so 9:00 means 9:00 on site
for everyone.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Don't promise location-local enforcement before it exists

When an organization member's stored timezone differs from the asset's physical location, this statement is false: validateWorkingHours extracts the booking's weekday and time using prefs.timeZone in forms-schema.ts (lines 77–82 and 303–307), and the default-time calculation does the same. Thus two users with different preferences can have the same 09:00–17:00 schedule applied in different zones, despite this UI promising that 09:00 means 09:00 on site for everyone. Reword this and the matching booking-form label to describe current behavior, or defer the claim until a location timezone is stored and enforced.

Useful? React with 👍 / 👎.

@coderabbitai

coderabbitai Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e7c64b53-3513-4c22-9257-9d8578627f58

📥 Commits

Reviewing files that changed from the base of the PR and between dd5f9f9 and d35fcc4.

📒 Files selected for processing (4)
  • .claude/rules/working-hours-are-location-local.md
  • apps/webapp/app/components/booking/forms/fields/dates.tsx
  • apps/webapp/app/components/working-hours/weekly-schedule-form.tsx
  • apps/webapp/app/utils/date-format.server.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review.


Walkthrough

The change documents location-local working-hour semantics, records existing timezone behavior as accepted risk, and updates booking and schedule UI text to identify physical-location local hours.

Changes

Location-local working-hours

Layer / File(s) Summary
Define semantics and accepted timezone behavior
.claude/rules/working-hours-are-location-local.md, apps/webapp/app/utils/date-format.server.ts
The rule defines location-local date and time semantics. Server documentation records the existing user-timezone behavior and the future stored-location-timezone requirement.
Surface location-local hours in the UI
apps/webapp/app/components/booking/forms/fields/dates.tsx, apps/webapp/app/components/working-hours/weekly-schedule-form.tsx
Booking and weekly schedule text identifies hours as physical-location local time and states that the schedule is not timezone-converted.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Merge Risk: ⚪ Minimal · up to d35fc

This PR clarifies that working hours use the physical location’s local time and updates related documentation; no actionable merge-blocking risk remains after normal checks and review.

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: documenting that working hours use the physical location's local time.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/working-hours-are-location-local

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@DonKoko
DonKoko merged commit 65a50bc into main Aug 20, 2026
9 checks passed
carlosvirreira added a commit to Shelf-nu/website-v2 that referenced this pull request Aug 24, 2026
…te's (#252)

* content: booking times follow your clock, working hours follow the site's

Triggered by:
  Shelf-nu/shelf.nu#2896
  Shelf-nu/shelf.nu#2905
  Shelf-nu/shelf.nu#2907
  Shelf-nu/shelf.nu#2908

The working-hours article never mentioned time zones at all, while the
date-preferences article told readers every timestamp follows their own
clock. Working hours are the one thing that does not: they are the local
hours of the physical location. #2907 put that in the product; this puts
it on the site.

The same article also sent readers to a Working Hours sidebar item that
does not exist, promised the picker greys out unavailable times, said
every day of a multi-day booking is checked, and offered an override edit
that was never built. All four corrected against source.

* content: the opening window is judged in the booker's zone, and an override is a date

CodeRabbit review on #252, both findings.

The 'everything else is a moment in time' claim was too broad: a closed-day
override is a calendar date, which the same article says two sections above.

On the second, the suggestion's premise did not hold, so the fix is different
from what was proposed. validateWorkingHours reads the weekday, the wall-clock
time and the date from prefs.timeZone (forms-schema.ts:303, :322), the booking
user's own preference. There is no site-local validation to apply, so matching
the site's zone is not optional decoration. The real hazard CodeRabbit was
pointing at is that the preference is account-wide, so the paragraph now states
the consequence, names the case where you should NOT change it, and quotes the
three refusal messages.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Carlos Virreira <macwhale@Carlos-MacBook-Pro.local>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant