fix(localization): parse date-only ISO strings as local midnight in relative date formatter (#20630)
## Summary Fixes #19634 ### Root Cause The ECMAScript spec treats date-only strings (`YYYY-MM-DD`) as **UTC midnight** when passed to `new Date()`. But `date-fns` comparison functions (`isToday`, `isYesterday`, `isTomorrow`) operate in **local time**. For users in UTC-negative timezones, UTC midnight April 14 is April 13 evening locally — so the label shows "Yesterday" instead of "Today". ### Fix In `formatDateISOStringToRelativeDate.ts`, detect date-only strings (length === 10) and append `T00:00:00` (no `Z`) to force local-time parsing: ```ts // Before const targetDate = new Date(isoDate); // After const targetDate = isoDate.length === 10 ? new Date(isoDate + 'T00:00:00') : new Date(isoDate); ``` Full datetime strings (with time component) are left unchanged — they already carry timezone information. ### Tests Added `formatDateISOStringToRelativeDate.test.ts` covering: - `Today` / `Yesterday` / `Tomorrow` labels for date-only strings - Regression case: date-only string parsed at local midnight (not UTC midnight) - Full datetime strings continue to work as before ## Before / After | Scenario | Before | After | |---|---|---| | `"2026-04-14"` viewed at UTC-5 on April 14 | Yesterday ❌ | Today ✓ | | `"2026-04-14"` viewed at UTC+0 on April 14 | Today ✓ | Today ✓ | | `"2026-04-14T12:00:00Z"` | Today ✓ | Today ✓ | --------- Co-authored-by: Marie Stoppa <marie@twenty.com>
This commit is contained in:
@@ -29,6 +29,7 @@ export { interpolateCommandMenuItemTemplate } from './command-menu-items/interpo
|
||||
export { resolveObjectMetadataLabel } from './command-menu-items/resolveObjectMetadataLabel';
|
||||
export { safeGetNestedProperty } from './command-menu-items/safeGetNestedProperty';
|
||||
export { computeDiffBetweenObjects } from './compute-diff-between-objects';
|
||||
export { isDateWithoutTime } from './date/isDateWithoutTime';
|
||||
export { isPlainDateAfter } from './date/isPlainDateAfter';
|
||||
export { isPlainDateBefore } from './date/isPlainDateBefore';
|
||||
export { isPlainDateBeforeOrEqual } from './date/isPlainDateBeforeOrEqual';
|
||||
|
||||
Reference in New Issue
Block a user