diff --git a/src/lib/utilities/format-date.test.ts b/src/lib/utilities/format-date.test.ts index 896d1e8328..74866c3dd4 100644 --- a/src/lib/utilities/format-date.test.ts +++ b/src/lib/utilities/format-date.test.ts @@ -79,7 +79,7 @@ describe('formatDate', () => { ).toContain('custom'); }); - it('should format relative time with days instead of months if flexibleUnits is not enabled', () => { + it('should format relative time with days instead of months for past dates if flexibleUnits is not enabled', () => { const currentDate = new Date(); const pastDate = currentDate.setDate(currentDate.getDate() - 90); let formattedDate = formatDate(pastDate, 'local', { @@ -92,6 +92,45 @@ describe('formatDate', () => { expect(formattedDate).toEqual('90 days ago'); }); + it('should format relative time with days instead of months for future dates if flexibleUnits is not enabled', () => { + const currentDate = new Date(); + const futureDate = currentDate.setDate(currentDate.getDate() + 90); + let formattedDate = formatDate(futureDate, 'local', { + relative: true, + flexibleUnits: true, + }); + expect(formattedDate).toEqual('3 months from now'); + + formattedDate = formatDate(futureDate, 'local', { relative: true }); + expect(formattedDate).toEqual('90 days from now'); + }); + + it('should not format relative time with days if less than a day for past dates even if flexibleUnits is enabled', () => { + const currentDate = new Date(); + const pastDate = currentDate.setHours(currentDate.getHours() - 23); + let formattedDate = formatDate(pastDate, 'local', { + relative: true, + flexibleUnits: true, + }); + expect(formattedDate).toEqual('23 hours ago'); + + formattedDate = formatDate(pastDate, 'local', { relative: true }); + expect(formattedDate).toEqual('23 hours ago'); + }); + + it('should not format relative time with days if less than a day for future dates even if flexibleUnits is enabled', () => { + const currentDate = new Date(); + const futureDate = currentDate.setHours(currentDate.getHours() + 23); + let formattedDate = formatDate(futureDate, 'local', { + relative: true, + flexibleUnits: true, + }); + expect(formattedDate).toEqual('23 hours from now'); + + formattedDate = formatDate(futureDate, 'local', { relative: true }); + expect(formattedDate).toEqual('23 hours from now'); + }); + it('should shorten format for local and other timezones', () => { expect(formatDate(date, 'local', { abbrFormat: true })).toEqual( '2022-04-13 16:29:35 PM', diff --git a/src/lib/utilities/format-date.ts b/src/lib/utilities/format-date.ts index d24a9df340..e5184b033d 100644 --- a/src/lib/utilities/format-date.ts +++ b/src/lib/utilities/format-date.ts @@ -1,4 +1,9 @@ -import { formatDistanceToNowStrict, parseISO, parseJSON } from 'date-fns'; +import { + differenceInHours, + formatDistanceToNowStrict, + parseISO, + parseJSON, +} from 'date-fns'; import * as dateTz from 'date-fns-tz'; // `build` script fails on importing some of named CommonJS modules import { @@ -29,7 +34,8 @@ export function formatDate( date = timestampToDate(date); } - const isFutureDate = new Date(date).getTime() - Date.now() > 0; + const currentDate = Date.now(); + const isFutureDate = new Date(date).getTime() - currentDate > 0; const { relative = false, relativeLabel = isFutureDate ? 'from now' : 'ago', @@ -49,7 +55,10 @@ export function formatDate( if (relative) return ( formatDistanceToNowStrict(parsed, { - ...(!flexibleUnits && { unit: 'day' }), + ...(!flexibleUnits && + Math.abs(differenceInHours(currentDate, parsed)) > 24 && { + unit: 'day', + }), }) + ` ${relativeLabel}` ); return dateTz.format(parsed, format);