Skip to content

Commit c4dcf51

Browse files
committed
Add date utils from timeline project
1 parent 3bc6ef0 commit c4dcf51

File tree

4 files changed

+149
-0
lines changed

4 files changed

+149
-0
lines changed

src/utils/dateConstants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export const DATE_FORMAT = "YYYY-MM-DD";
2+
export const DATE_FORMAT_YEAR = "YYYY";

src/utils/dateUtils.test.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import {
2+
DATE_A,
3+
DATE_A_NEXT_DAY_STRING,
4+
INCLUSIVE_DATE_RANGE_A_TO_B,
5+
DATE_A_TEN_SEQUENTIAL_DAYS_STRINGS,
6+
DATE_B
7+
} from "./mockDateUtilsData";
8+
import {
9+
getOneDayAfter,
10+
getNSequentialDaysFromStart,
11+
getDateRangeInclusiveDayCount,
12+
isDateRangeValid
13+
} from "./dateUtils";
14+
import { DATE_FORMAT } from "./dateConstants";
15+
16+
describe("dateUtils", () => {
17+
describe("getOneDateAfter", () => {
18+
it("should return the next day", () => {
19+
const tomorrow = getOneDayAfter(DATE_A);
20+
21+
expect(tomorrow.format(DATE_FORMAT)).toBe(DATE_A_NEXT_DAY_STRING);
22+
});
23+
});
24+
25+
describe("getNSequentialDaysFromStart", () => {
26+
it("should return an array of moments with the specified length", () => {
27+
const dates = getNSequentialDaysFromStart(DATE_A, 10);
28+
29+
expect(dates).toHaveLength(DATE_A_TEN_SEQUENTIAL_DAYS_STRINGS.length);
30+
});
31+
32+
it("should return an array of the correct sequential dates", () => {
33+
const dates = getNSequentialDaysFromStart(DATE_A, 10);
34+
35+
dates.forEach((date, i) => {
36+
expect(date.format(DATE_FORMAT)).toBe(
37+
DATE_A_TEN_SEQUENTIAL_DAYS_STRINGS[i]
38+
);
39+
});
40+
});
41+
});
42+
43+
describe("getDateRangeInclusiveDayCount", () => {
44+
it("should return the diff between start and end dates, plus 1", () => {
45+
const range = getDateRangeInclusiveDayCount(DATE_A, DATE_B);
46+
47+
expect(range).toBe(INCLUSIVE_DATE_RANGE_A_TO_B);
48+
});
49+
});
50+
51+
describe("isDateRangeValid", () => {
52+
describe("when startDate is after endDate", () => {
53+
it("should return false", () => {
54+
expect(isDateRangeValid(DATE_B, DATE_A)).toBe(false);
55+
});
56+
});
57+
58+
describe("when startDate is before endDate", () => {
59+
it("should return true", () => {
60+
expect(isDateRangeValid(DATE_A, DATE_B)).toBe(true);
61+
});
62+
});
63+
64+
describe("when startDate the same as endDate", () => {
65+
it("should return true", () => {
66+
expect(isDateRangeValid(DATE_A, DATE_A)).toBe(true);
67+
});
68+
});
69+
});
70+
});

src/utils/dateUtils.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import moment from "moment";
2+
3+
export function getOneDayAfter(date: moment.Moment): moment.Moment {
4+
return date.clone().add(1, "day");
5+
}
6+
7+
/**
8+
* return moments for the start date and n-1 sequential
9+
* days after that. Sequence is every day, no gaps.
10+
*
11+
* @param startDate day to start counting from
12+
* @param dayCount how many days to return total
13+
*/
14+
export function getNSequentialDaysFromStart(
15+
startDate: moment.Moment,
16+
dayCount: number
17+
): moment.Moment[] {
18+
const dates: moment.Moment[] = [];
19+
const currentDate = startDate.clone();
20+
21+
for (let i = 0; i < dayCount; i++) {
22+
const date = currentDate.clone();
23+
24+
dates.push(date);
25+
currentDate.add(1, "days");
26+
}
27+
28+
return dates;
29+
}
30+
31+
/**
32+
* returns the total days between start and end date, inclusive
33+
* of both the start date and end date
34+
* @param startDate from the beginning of this day
35+
* @param endDate to the end of this day
36+
*/
37+
export function getDateRangeInclusiveDayCount(
38+
startDate: moment.Moment,
39+
endDate: moment.Moment
40+
): number | undefined {
41+
// inclusive of both start and end dates
42+
return 1 + endDate.diff(startDate, "days");
43+
}
44+
45+
/**
46+
* return false if the end is before the beginning
47+
* @param startDate
48+
* @param endDate
49+
*/
50+
export function isDateRangeValid(
51+
startDate: moment.Moment,
52+
endDate: moment.Moment
53+
): boolean {
54+
return endDate.isSameOrAfter(startDate);
55+
}

src/utils/mockDateUtilsData.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import moment from "moment";
2+
import { DATE_FORMAT } from "./dateConstants";
3+
4+
export const DATE_A = moment("2018-01-01", DATE_FORMAT);
5+
6+
export const DATE_A_NEXT_DAY_STRING = "2018-01-02";
7+
8+
export const DATE_B = moment("2018-01-10", DATE_FORMAT);
9+
10+
export const INCLUSIVE_DATE_RANGE_A_TO_B = 10;
11+
12+
export const DATE_A_TEN_SEQUENTIAL_DAYS_STRINGS = [
13+
"2018-01-01",
14+
"2018-01-02",
15+
"2018-01-03",
16+
"2018-01-04",
17+
"2018-01-05",
18+
"2018-01-06",
19+
"2018-01-07",
20+
"2018-01-08",
21+
"2018-01-09",
22+
"2018-01-10"
23+
];

0 commit comments

Comments
 (0)