Skip to content

Commit

Permalink
Add more date utility functions
Browse files Browse the repository at this point in the history
  • Loading branch information
drebrez committed Apr 30, 2024
1 parent bb3fb12 commit c4c8a1a
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- added `dateIsFirstDayOfMonth`, `dateIsLeapYear`, `dateIsWeekend` and `getNextBusinessDate` utility functions

## [0.5.0] - 2024-03-15

### Added
Expand Down
69 changes: 68 additions & 1 deletion src/lib/date.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { dateIsValid, dateIsLastDayOfMonth, dateDifferenceInDays } from "./date";
import {
dateIsValid,
dateIsFirstDayOfMonth,
dateIsLastDayOfMonth,
dateIsLeapYear,
dateIsWeekend,
dateDifferenceInDays,
getNextBusinessDate,
} from "./date";

describe("date tests", () => {
test.each([
Expand All @@ -22,6 +30,14 @@ describe("date tests", () => {
expect(dateIsValid(date)).toBe(expected);
});

test.each([
[new Date(2015, 0, 1), true],
[new Date(2015, 1, 1), true],
[new Date(2015, 12, 30), false],
])("dateIsFirstDayOfMonth", (date, expected) => {
expect(dateIsFirstDayOfMonth(date)).toBe(expected);
});

test.each([
[new Date(2014, 12, 31), true],
[new Date(2014, 12, 30), false],
Expand All @@ -30,6 +46,34 @@ describe("date tests", () => {
expect(dateIsLastDayOfMonth(date)).toBe(expected);
});

test.each([
[new Date(2000, 0, 1), true],
[new Date(2004, 0, 1), true],
[new Date(2008, 0, 1), true],
[new Date(2009, 0, 1), false],
[new Date(2010, 0, 1), false],
[new Date(1900, 0, 1), false],
[new Date(2100, 0, 1), false],
[new Date(2200, 0, 1), false],
[new Date(2300, 0, 1), false],
[new Date(2400, 0, 1), true],
])("dateIsLeapYear", (date, expected) => {
expect(dateIsLeapYear(date)).toBe(expected);
});

test.each([
[new Date(2024, 0, 1), false], // Monday
[new Date(2024, 0, 2), false], // Tuesday
[new Date(2024, 0, 3), false], // Wednesday
[new Date(2024, 0, 4), false], // Thursday
[new Date(2024, 0, 5), false], // Friday
[new Date(2024, 0, 6), true], // Saturday
[new Date(2024, 0, 7), true], // Sunday
[new Date(2024, 0, 8), false], // Monday
])("dateIsWeekend", (date, expected) => {
expect(dateIsWeekend(date)).toBe(expected);
});

test.each([
[new Date(2014, 3, 15), new Date(2014, 3, 15), 0],
[new Date(2014, 3, 15), new Date(2014, 3, 16), 1],
Expand All @@ -38,7 +82,30 @@ describe("date tests", () => {
[new Date(2014, 3, 15, 23, 59), new Date(2014, 3, 16, 0, 0), 1],
[null as unknown as Date, new Date(), Number.NaN],
[new Date(), null as unknown as Date, Number.NaN],
[undefined as unknown as Date, new Date(), Number.NaN],
[new Date(), undefined as unknown as Date, Number.NaN],
[42 as unknown as Date, new Date(), Number.NaN],
[new Date(), 42 as unknown as Date, Number.NaN],
["2014-03-15" as unknown as Date, new Date(), Number.NaN],
[new Date(), "2014-03-15" as unknown as Date, Number.NaN],
])("dateDifferenceInDays", (dateFrom, dateTo, expected) => {
expect(dateDifferenceInDays(dateFrom, dateTo)).toBe(expected);
});

test.each([
[new Date(2024, 0, 1), new Date(2024, 0, 2)],
[new Date(2024, 0, 2), new Date(2024, 0, 3)],
[new Date(2024, 0, 3), new Date(2024, 0, 4)],
[new Date(2024, 0, 4), new Date(2024, 0, 5)],
[new Date(2024, 0, 5), new Date(2024, 0, 8)],
[new Date(2024, 0, 6), new Date(2024, 0, 8)],
[new Date(2024, 0, 7), new Date(2024, 0, 8)],
[new Date(2024, 0, 8), new Date(2024, 0, 9)],
[null as unknown as Date, new Date(Number.NaN)],
[undefined as unknown as Date, new Date(Number.NaN)],
[42 as unknown as Date, new Date(Number.NaN)],
["test" as unknown as Date, new Date(Number.NaN)],
])("getNextBusinessDate", (date, expected) => {
expect(getNextBusinessDate(date).getDate()).toBe(expected.getDate());
});
});
51 changes: 48 additions & 3 deletions src/lib/date.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
import { isDate, isValid, isLastDayOfMonth, differenceInCalendarDays } from "date-fns";
import {
isDate,
isValid,
isFirstDayOfMonth,
isLastDayOfMonth,
isLeapYear,
isWeekend,
differenceInCalendarDays,
addBusinessDays,
} from "date-fns";

/**
* Check whether the date is valid
Expand All @@ -9,13 +18,40 @@ export function dateIsValid(date: Date): boolean {
return isDate(date) && isValid(date);
}

/**
* Check whether the date is the first day of the month
* @param date The date
* @returns A boolean indicating whether the date is the first day of the month
*/
export function dateIsFirstDayOfMonth(date: Date): boolean {
return dateIsValid(date) && isFirstDayOfMonth(date);
}

/**
* Check whether the date is the last day of the month
* @param date The date
* @returns A boolean indicating whether the date is the last day of the month
*/
export function dateIsLastDayOfMonth(date: Date): boolean {
return isDate(date) && isLastDayOfMonth(date);
return dateIsValid(date) && isLastDayOfMonth(date);
}

/**
* Check whether the date is a leap year
* @param date The date
* @returns A boolean indicating whether the date is a leap year
*/
export function dateIsLeapYear(date: Date): boolean {
return dateIsValid(date) && isLeapYear(date);
}

/**
* Check whether the date is a weekend
* @param date The date
* @returns A boolean indicating whether the date is a weekend
*/
export function dateIsWeekend(date: Date): boolean {
return dateIsValid(date) && isWeekend(date);
}

/**
Expand All @@ -26,5 +62,14 @@ export function dateIsLastDayOfMonth(date: Date): boolean {
* @returns The difference in days between two dates
*/
export function dateDifferenceInDays(from: Date, to: Date): number {
return Math.abs(differenceInCalendarDays(from, to));
return dateIsValid(from) && dateIsValid(to) ? Math.abs(differenceInCalendarDays(from, to)) : Number.NaN;
}

/**
* Get the next business date
* @param date The date
* @returns The next business date
*/
export function getNextBusinessDate(date: Date): Date {
return dateIsValid(date) ? addBusinessDays(date, 1) : new Date(Number.NaN);
}

0 comments on commit c4c8a1a

Please sign in to comment.