fix: incorrect 24h time detection for non-AM/PM locales#29036
fix: incorrect 24h time detection for non-AM/PM locales#29036Akash504-ai wants to merge 4 commits into
Conversation
|
Welcome to Cal.diy, @Akash504-ai! Thanks for opening this pull request. A few things to keep in mind:
A maintainer will review your PR soon. Thanks for contributing! |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
packages/lib/timeFormat.test.ts (1)
12-39: Consider broadening test coverage.The PR description lists
h24/h11and the cached-localStorage early-return paths as expected behavior, but onlyh23/h12are exercised. Worth adding cases for completeness:
hourCycle === "h24"→truehourCycle === "h11"→falsehourCycle === undefined→false(safe fallback)localStorage.getItemreturning"true"/"false"→ returns cached value without invokingIntl.DateTimeFormat- After computing,
localStorage.setItemis called with the derived boolean stringAlso consider
vi.resetAllMocks()instead ofvi.restoreAllMocks()if you want thevi.fn()instances from thevi.mockfactory to have their call history cleared between tests —restoreAllMocksonly restores spies created withvi.spyOn.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/lib/timeFormat.test.ts` around lines 12 - 39, Add tests exercising the missing hourCycle values and the localStorage cache paths: extend timeFormat.test.ts to assert isBrowserLocale24h() returns true for hourCycle "h24" and false for "h11", false when resolvedOptions().hourCycle is undefined, and verify that when localStorage.getItem returns "true" or "false" the function returns that cached boolean without calling Intl.DateTimeFormat; also assert that when the value is computed the code calls localStorage.setItem with the stringified boolean. Replace vi.restoreAllMocks() with vi.resetAllMocks() in beforeEach to clear mock call history between tests so vi.mock factory fns are reset.packages/lib/timeFormat.ts (1)
1-6: Update the stale file header comment.The header still describes the old AM/
'01 h'string-detection approach, which no longer matches the newhourCycle-based implementation. Worth refreshing so future readers aren't misled.📝 Proposed update
/* - * Detects navigator locale 24h time preference - * It works by checking whether hour output contains AM ('1 AM' or '01 h') - * based on the user's preferred language - * defaults to 'en-US' (12h) if no navigator language is found + * Detects navigator locale 24h time preference using + * Intl.DateTimeFormat().resolvedOptions().hourCycle so it works + * for locales whose AM/PM markers don't contain "M" (e.g. ja, zh, ko). */🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/lib/timeFormat.ts` around lines 1 - 6, The header comment at the top of packages/lib/timeFormat.ts is outdated (mentions AM/'01 h' string-detection) and should be replaced with a short, accurate description that the module detects the user's 24h/12h preference using Intl.DateTimeFormat().resolvedOptions().hourCycle (falling back to navigator.language or 'en-US' when unavailable) and explains the default behavior; update the top-of-file comment to reference the hourCycle-based implementation and navigator.language fallback so future readers aren't misled.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/lib/timeFormat.test.ts`:
- Around line 17-39: The test uses three `as any` casts when mocking
Intl.DateTimeFormat; replace them with proper types by making the mock
implementation return a correctly typed object (e.g., implement resolvedOptions
on a Partial<Intl.DateTimeFormat> and cast to Intl.DateTimeFormat, or declare
the mock function signature as (): Intl.DateTimeFormat => ...) so the
spyOn(mock) satisfies Intl.DateTimeFormatConstructor without using `any`; apply
this change to both tests that mock Intl.DateTimeFormat and keep the assertions
against isBrowserLocale24h() unchanged.
In `@packages/lib/timeFormat.ts`:
- Around line 45-48: The code unnecessarily casts resolvedOptions() to any to
read hourCycle; remove the cast and use the proper typed value by declaring
hourCycle via const hourCycle = formatter.resolvedOptions().hourCycle (letting
TypeScript infer the type "h11" | "h12" | "h23" | "h24" | undefined) and keep
the existing is24h check (const is24h = hourCycle === "h23" || hourCycle ===
"h24"); update any surrounding logic that assumed a loose type to use this typed
hourCycle instead.
---
Nitpick comments:
In `@packages/lib/timeFormat.test.ts`:
- Around line 12-39: Add tests exercising the missing hourCycle values and the
localStorage cache paths: extend timeFormat.test.ts to assert
isBrowserLocale24h() returns true for hourCycle "h24" and false for "h11", false
when resolvedOptions().hourCycle is undefined, and verify that when
localStorage.getItem returns "true" or "false" the function returns that cached
boolean without calling Intl.DateTimeFormat; also assert that when the value is
computed the code calls localStorage.setItem with the stringified boolean.
Replace vi.restoreAllMocks() with vi.resetAllMocks() in beforeEach to clear mock
call history between tests so vi.mock factory fns are reset.
In `@packages/lib/timeFormat.ts`:
- Around line 1-6: The header comment at the top of packages/lib/timeFormat.ts
is outdated (mentions AM/'01 h' string-detection) and should be replaced with a
short, accurate description that the module detects the user's 24h/12h
preference using Intl.DateTimeFormat().resolvedOptions().hourCycle (falling back
to navigator.language or 'en-US' when unavailable) and explains the default
behavior; update the top-of-file comment to reference the hourCycle-based
implementation and navigator.language fallback so future readers aren't misled.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 908b7d8c-88af-416d-af63-5dcf758e38d3
📒 Files selected for processing (2)
packages/lib/timeFormat.test.tspackages/lib/timeFormat.ts
|
Thanks for the PR! please add before and after video demo. reopen once it's added. |
|
Added demo video and code reference screenshot. Reopening for review. |
|
@romitg2 I have added the requested video (demonstrating behavior) along with a code reference screenshot. Could you please reopen the PR for review? |
|
This PR has been marked as stale due to inactivity. If you're still working on it or need any help, please let us know or update the PR to keep it active. |
What does this PR do?
Fixes incorrect 24h time detection for locales that do not use "AM/PM" with "M" (e.g., Japanese, Chinese, Korean).
Previously, detection relied on string matching:
This assumes 12h formats always include "AM/PM", which is not true.
For example (Japanese locale):
Even though this is a 12-hour format, it does not contain "AM/PM", so:
This leads to incorrect 24h detection.
This PR replaces the logic with:
which provides a reliable and locale-safe way to detect 12h/24h formats.
Visual Demo
The attached video demonstrates:
Event.types._.Cal.com.-.Brave.2026-04-27.10-50-36.online-video-cutter.com.mp4
Exact problem in your code :
Mandatory Tasks
How should this be tested?
Run:
Expected: