Skip to content

Commit

Permalink
fix: 🐛 notification dates edge case
Browse files Browse the repository at this point in the history
due to manual date diffing, there were some weirdness with the dates displayed (such as a notification yesterday, but not 24 hours ago).
This fix (using date built-ins) ensures correct notification dates.

NOTE - need to port this on other platforms
  • Loading branch information
Prithpal-Sooriya committed Jun 7, 2024
1 parent 254ac95 commit 65f11f2
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 22 deletions.
48 changes: 41 additions & 7 deletions ui/helpers/utils/notification.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,35 +27,69 @@ import {
decimalToHex,
} from '../../../shared/modules/conversion.utils';

/**
* Checks if 2 date objects are on the same day
*
* @param currentDate
* @param dateToCheck
* @returns boolean if dates are same day.
*/
const isSameDay = (currentDate: Date, dateToCheck: Date) =>
currentDate.getFullYear() === dateToCheck.getFullYear() &&
currentDate.getMonth() === dateToCheck.getMonth() &&
currentDate.getDate() === dateToCheck.getDate();

/**
* Checks if a date is "yesterday" from the current date
*
* @param currentDate
* @param dateToCheck
* @returns boolean if dates were "yesterday"
*/
const isYesterday = (currentDate: Date, dateToCheck: Date) => {
const yesterday = new Date(currentDate);
yesterday.setDate(currentDate.getDate() - 1);
return isSameDay(yesterday, dateToCheck);
};

/**
* Checks if 2 date objects are in the same year.
*
* @param currentDate
* @param dateToCheck
* @returns boolean if dates were in same year
*/
const isSameYear = (currentDate: Date, dateToCheck: Date) =>
currentDate.getFullYear() === dateToCheck.getFullYear();

/**
* Formats a given date into different formats based on how much time has elapsed since that date.
*
* @param date - The date to be formatted.
* @returns The formatted date.
*/
export function formatMenuItemDate(date: Date) {
const elapsed = Math.abs(Date.now() - date.getTime());
const diffDays = elapsed / (1000 * 60 * 60 * 24);
const currentDate = new Date();

// E.g. Yesterday
if (diffDays < 1) {
// E.g. 12:21
if (isSameDay(currentDate, date)) {
return new Intl.DateTimeFormat('en', {
hour: 'numeric',
minute: 'numeric',
hour12: false,
}).format(date);
}

// E.g. 12:21
if (Math.floor(diffDays) === 1) {
// E.g. Yesterday
if (isYesterday(currentDate, date)) {
return new Intl.RelativeTimeFormat('en', { numeric: 'auto' }).format(
-1,
'day',
);
}

// E.g. 21 Oct
if (diffDays > 1 && diffDays < 365) {
if (isSameYear(currentDate, date)) {
return new Intl.DateTimeFormat('en', {
month: 'short',
day: 'numeric',
Expand Down
97 changes: 82 additions & 15 deletions ui/helpers/utils/notification.utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,98 @@ import {
} from './notification.util';

describe('formatMenuItemDate', () => {
beforeAll(() => {
jest.useFakeTimers();
jest.setSystemTime(new Date('2024-06-07T09:40:00Z'));
});

afterAll(() => {
jest.useRealTimers();
});

it('should format date as time if the date is today', () => {
const date = new Date();
const result = formatMenuItemDate(date);
expect(result).toMatch(/^\d{2}:\d{2}$/u);
const assertToday = (modifyDate?: (d: Date) => void) => {
const testDate = new Date();
modifyDate?.(testDate);
expect(formatMenuItemDate(testDate)).toMatch(/^\d{2}:\d{2}$/u);
};

// assert current date
assertToday();

// assert 1 hour ago
assertToday((testDate) => {
testDate.setHours(testDate.getHours() - 1);
return testDate;
});
});

it('should format date as "yesterday" if the date was yesterday', () => {
const date = new Date();
date.setDate(date.getDate() - 1);
const result = formatMenuItemDate(date);
expect(result).toBe('yesterday');
const assertYesterday = (modifyDate: (d: Date) => void) => {
const testDate = new Date();
modifyDate(testDate);
expect(formatMenuItemDate(testDate)).toBe('yesterday');
};

// assert exactly 1 day ago
assertYesterday((testDate) => {
testDate.setDate(testDate.getDate() - 1);
});

// assert almost a day ago, but was still yesterday
// E.g. if Today way 09:40AM, but date to test was 23 hours ago (yesterday at 10:40AM), we still want to to show yesterday
assertYesterday((testDate) => {
testDate.setDate(testDate.getDate() - 1);
testDate.setHours(testDate.getHours() + 1);
});
});

it('should format date as "DD Mon" if the date is this year but not today or yesterday', () => {
const date = new Date();
date.setMonth(date.getMonth() - 1);
const result = formatMenuItemDate(date);
expect(result).toMatch(/^\w{3} \d{1,2}$/u);
const assertMonthsAgo = (modifyDate: (d: Date) => Date | void) => {
let testDate = new Date();
testDate = modifyDate(testDate) ?? testDate;
expect(formatMenuItemDate(testDate)).toMatch(/^\w{3} \d{1,2}$/u);
};

// assert exactly 1 month ago
assertMonthsAgo((testDate) => {
testDate.setMonth(testDate.getMonth() - 1);
});

// assert 2 months ago
assertMonthsAgo((testDate) => {
testDate.setMonth(testDate.getMonth() - 2);
});

// assert almost a month ago (where it is a new month, but not 30 days)
assertMonthsAgo(() => {
// jest mock date is set in july, so we will test with month may
return new Date('2024-05-20T09:40:00Z');
});
});

it('should format date as "Mon DD, YYYY" if the date is not this year', () => {
const date = new Date();
date.setFullYear(date.getFullYear() - 1);
const result = formatMenuItemDate(date);
expect(result).toMatch(/^\w{3} \d{1,2}, \d{4}$/u);
const assertYearsAgo = (modifyDate: (d: Date) => Date | void) => {
let testDate = new Date();
testDate = modifyDate(testDate) ?? testDate;
expect(formatMenuItemDate(testDate)).toMatch(/^\w{3} \d{1,2}, \d{4}$/u);
};

// assert exactly 1 year ago
assertYearsAgo((testDate) => {
testDate.setFullYear(testDate.getFullYear() - 1);
});

// assert 2 years ago
assertYearsAgo((testDate) => {
testDate.setFullYear(testDate.getFullYear() - 2);
});

// assert almost a year ago (where it is a new year, but not 365 days ago)
assertYearsAgo(() => {
// jest mock date is set in 2024, so we will test with year 2023
return new Date('2023-11-20T09:40:00Z');
});
});
});

Expand Down

0 comments on commit 65f11f2

Please sign in to comment.