From 48a38dc2307b69d0c02adca029c0a2590269d95c Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Mon, 22 Jan 2024 14:50:48 +0100 Subject: [PATCH 1/6] create getLastBusinessDayOfMonth --- src/libs/DateUtils.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/libs/DateUtils.ts b/src/libs/DateUtils.ts index 1a10eb03a00e..6e56d19a89b4 100644 --- a/src/libs/DateUtils.ts +++ b/src/libs/DateUtils.ts @@ -730,6 +730,26 @@ function formatToSupportedTimezone(timezoneInput: Timezone): Timezone { }; } +/** + * Returns the latest business day of input date month + * + * param {Date} inputDate + * returns {number} + */ +function getLastBusinessDayOfMonth(inputDate: Date): number { + const currentDate = new Date(inputDate); + + // Set the date to the last day of the month + currentDate.setMonth(currentDate.getMonth() + 1, 0); + + // Loop backward to find the latest business day + while (currentDate.getDay() === 0 || currentDate.getDay() === 6) { + currentDate.setDate(currentDate.getDate() - 1); + } + + return currentDate.getDate(); +} + const DateUtils = { formatToDayOfWeek, formatToLongDateWithWeekday, @@ -774,6 +794,7 @@ const DateUtils = { getWeekEndsOn, isTimeAtLeastOneMinuteInFuture, formatToSupportedTimezone, + getLastBusinessDayOfMonth, }; export default DateUtils; From e3dfa0693cdaef4f91c701b7bde7325af68ab3af Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Mon, 22 Jan 2024 14:50:52 +0100 Subject: [PATCH 2/6] test getLastBusinessDayOfMonth --- tests/unit/DateUtilsTest.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/unit/DateUtilsTest.js b/tests/unit/DateUtilsTest.js index 7480da456d7f..17b25f24e327 100644 --- a/tests/unit/DateUtilsTest.js +++ b/tests/unit/DateUtilsTest.js @@ -213,4 +213,30 @@ describe('DateUtils', () => { }); }); }); + + describe('getLastBusinessDayOfMonth', () => { + const scenarios = [ + { + // Last business of May in 2025 + inputDate: new Date(2025, 4), + expectedResult: 30, + }, + { + // Last business of January in 2024 + inputDate: new Date(2024, 0), + expectedResult: 31, + }, + { + // Last business of September in 2023 + inputDate: new Date(2023, 8), + expectedResult: 29, + }, + ]; + + test.each(scenarios)('returns a last business day of an input date', ({inputDate, expectedResult}) => { + const lastBusinessDay = DateUtils.getLastBusinessDayOfMonth(inputDate); + + expect(lastBusinessDay).toEqual(expectedResult); + }); + }); }); From fa47c0da6c59f2b86adadc1b819c9f99d9a0ae7b Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Mon, 22 Jan 2024 16:18:07 +0100 Subject: [PATCH 3/6] re-test From 453de73dbdbad0dd979e6c1741225dbbea40e18a Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Mon, 22 Jan 2024 16:56:16 +0100 Subject: [PATCH 4/6] use date-fns --- src/libs/DateUtils.ts | 18 ++++++++++-------- tests/unit/DateUtilsTest.js | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/libs/DateUtils.ts b/src/libs/DateUtils.ts index 6e56d19a89b4..188e0e54afe8 100644 --- a/src/libs/DateUtils.ts +++ b/src/libs/DateUtils.ts @@ -5,9 +5,12 @@ import { eachDayOfInterval, eachMonthOfInterval, endOfDay, + endOfMonth, endOfWeek, format, formatDistanceToNow, + getDate, + getDay, getDayOfYear, isAfter, isBefore, @@ -737,17 +740,16 @@ function formatToSupportedTimezone(timezoneInput: Timezone): Timezone { * returns {number} */ function getLastBusinessDayOfMonth(inputDate: Date): number { - const currentDate = new Date(inputDate); + let currentDate = endOfMonth(inputDate); + const dayOfWeek = getDay(currentDate); - // Set the date to the last day of the month - currentDate.setMonth(currentDate.getMonth() + 1, 0); - - // Loop backward to find the latest business day - while (currentDate.getDay() === 0 || currentDate.getDay() === 6) { - currentDate.setDate(currentDate.getDate() - 1); + if (dayOfWeek === 0) { + currentDate = subDays(currentDate, 2); + } else if (dayOfWeek === 6) { + currentDate = subDays(currentDate, 1); } - return currentDate.getDate(); + return getDate(currentDate); } const DateUtils = { diff --git a/tests/unit/DateUtilsTest.js b/tests/unit/DateUtilsTest.js index 17b25f24e327..a8bdc6c6b7bc 100644 --- a/tests/unit/DateUtilsTest.js +++ b/tests/unit/DateUtilsTest.js @@ -214,7 +214,7 @@ describe('DateUtils', () => { }); }); - describe('getLastBusinessDayOfMonth', () => { + describe.only('getLastBusinessDayOfMonth', () => { const scenarios = [ { // Last business of May in 2025 From b2b2fdf5bef424cc708af7dce497d449d902cb5f Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Tue, 23 Jan 2024 11:14:18 +0100 Subject: [PATCH 5/6] minor improvements --- src/libs/DateUtils.ts | 2 +- tests/unit/DateUtilsTest.js | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/libs/DateUtils.ts b/src/libs/DateUtils.ts index 188e0e54afe8..526769723531 100644 --- a/src/libs/DateUtils.ts +++ b/src/libs/DateUtils.ts @@ -734,7 +734,7 @@ function formatToSupportedTimezone(timezoneInput: Timezone): Timezone { } /** - * Returns the latest business day of input date month + * Returns the last business day of given date month * * param {Date} inputDate * returns {number} diff --git a/tests/unit/DateUtilsTest.js b/tests/unit/DateUtilsTest.js index a8bdc6c6b7bc..be38eae9251d 100644 --- a/tests/unit/DateUtilsTest.js +++ b/tests/unit/DateUtilsTest.js @@ -217,23 +217,28 @@ describe('DateUtils', () => { describe.only('getLastBusinessDayOfMonth', () => { const scenarios = [ { - // Last business of May in 2025 + // Last business day of May in 2025 inputDate: new Date(2025, 4), expectedResult: 30, }, { - // Last business of January in 2024 + // Last business day of February in 2024 + inputDate: new Date(2024, 2), + expectedResult: 29, + }, + { + // Last business day of January in 2024 inputDate: new Date(2024, 0), expectedResult: 31, }, { - // Last business of September in 2023 + // Last business day of September in 2023 inputDate: new Date(2023, 8), expectedResult: 29, }, ]; - test.each(scenarios)('returns a last business day of an input date', ({inputDate, expectedResult}) => { + test.each(scenarios)('returns a last business day based on the input date', ({inputDate, expectedResult}) => { const lastBusinessDay = DateUtils.getLastBusinessDayOfMonth(inputDate); expect(lastBusinessDay).toEqual(expectedResult); From 86bbc8ae39c18c59ba62dcd45da59518254a3e3e Mon Sep 17 00:00:00 2001 From: Mykhailo Kravchenko Date: Tue, 23 Jan 2024 11:14:51 +0100 Subject: [PATCH 6/6] remove only --- tests/unit/DateUtilsTest.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/DateUtilsTest.js b/tests/unit/DateUtilsTest.js index be38eae9251d..a752eea1a990 100644 --- a/tests/unit/DateUtilsTest.js +++ b/tests/unit/DateUtilsTest.js @@ -214,7 +214,7 @@ describe('DateUtils', () => { }); }); - describe.only('getLastBusinessDayOfMonth', () => { + describe('getLastBusinessDayOfMonth', () => { const scenarios = [ { // Last business day of May in 2025