Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
fix: keep same-month day durations monotonic
Relative date labels around the month boundary can currently move
backward in precision: a 25-day-old timestamp may render as "last month"
while a 27-day-old timestamp renders as "27 days ago". In sorted date
lists this makes newer items look older than later rows, even when the
underlying timestamps are ordered correctly.

Keep same-calendar-month day spans in days instead of promoting them
through the intermediate four-week representation to one month. Preserve
month rounding once the compared dates cross a calendar-month boundary.

Add regression coverage for the 25/26-day same-month cases so the labels
remain monotonic around the month boundary.
  • Loading branch information
thazhemadam committed Jun 29, 2026
commit dda2ab09195553ba3181bcab37a35259aa213ed4
6 changes: 4 additions & 2 deletions src/duration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,10 @@ export function roundToSingleUnit(duration: Duration, {relativeTo = Date.now()}:
const daysDiff = Math.abs(Math.round((Number(newDate) - Number(relativeTo)) / 86400000)) + monthDateCorrection
const monthsDiff = Math.abs(yearDiff * 12 + monthDiff)
if (daysDiff < 27) {
if (days >= 6) {
weeks += Math.round(days / 7)
const roundedWeeks = Math.round(days / 7)
// Keep same-calendar-month spans as days instead of rounding 4 weeks to a month.
if (days >= 6 && (roundedWeeks < 4 || monthsDiff > 0)) {
weeks += roundedWeeks
days = 0
} else {
days = daysDiff
Expand Down
7 changes: 5 additions & 2 deletions test/duration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,9 @@ suite('duration', function () {
['-P21D', '-P3W', {relativeTo: new Date('2023-07-01T00:00:00')}],
['P24D', 'P3W', {relativeTo: new Date('2023-07-01T00:00:00')}],
['-P24D', '-P3W', {relativeTo: new Date('2023-07-01T00:00:00')}],
['P24DT25H', 'P1M', {relativeTo: new Date('2023-07-01T00:00:00')}],
['P24DT25H', 'P25D', {relativeTo: new Date('2023-07-01T00:00:00')}],
['-P24DT25H', '-P1M', {relativeTo: new Date('2023-07-01T00:00:00')}],
['P25D', 'P1M', {relativeTo: new Date('2023-07-01T00:00:00')}],
['P25D', 'P25D', {relativeTo: new Date('2023-07-01T00:00:00')}],
['-P25D', '-P1M', {relativeTo: new Date('2023-07-01T00:00:00')}],
['P1M1D', 'P1M', {relativeTo: new Date('2023-07-02T00:00:00')}],
['-P1M1D', '-P1M', {relativeTo: new Date('2023-07-02T00:00:00')}],
Expand Down Expand Up @@ -365,6 +365,9 @@ suite('duration', function () {
['-P24D', [-3, 'week'], {relativeTo: '2023-01-01T00:00:00Z'}],
['P24DT25H', [1, 'month'], {relativeTo: '2023-01-15T00:00:00Z'}],
['P25D', [1, 'month'], {relativeTo: '2023-01-15T00:00:00Z'}],
['P25D', [25, 'day'], {relativeTo: '2023-07-01T00:00:00Z'}],
['-P25D', [-25, 'day'], {relativeTo: '2026-06-29T00:00:00Z'}],
['-P26D', [-26, 'day'], {relativeTo: '2026-06-29T00:00:00Z'}],
['-P35D', [-1, 'month'], {relativeTo: '2023-02-07T22:22:57Z'}],
['-P45D', [-1, 'month'], {relativeTo: '2023-02-17T22:22:57Z'}],
['-P55D', [-1, 'month'], {relativeTo: '2023-02-27T22:22:57Z'}],
Expand Down
Loading