Skip to content

Commit ac65f50

Browse files
committed
feat: new get academic years function
1 parent c366d4a commit ac65f50

2 files changed

Lines changed: 116 additions & 2 deletions

File tree

common/eactivities/src/getAcademicYear.spec.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getAcademicYear, isValidAcademicYear } from "./getAcademicYear";
1+
import { getAcademicYear, getAcademicYears, isValidAcademicYear } from "./getAcademicYear";
22

33
describe("getAcademicYear", () => {
44
it("should return the academic year if set before August", async () => {
@@ -53,4 +53,44 @@ describe("getAcademicYear", () => {
5353
expect(isValidAcademicYear("22-2")).toBe(false);
5454
});
5555
});
56+
57+
it("should return the correct academic years", () => {
58+
expect(getAcademicYears(new Date("2020-08-01"))).toStrictEqual(["20-21"]);
59+
60+
expect(getAcademicYears(new Date("2021-08-01"))).toStrictEqual(["20-21", "21-22"]);
61+
62+
expect(getAcademicYears(new Date("2022-07-31"))).toStrictEqual(["20-21", "21-22"]);
63+
64+
expect(getAcademicYears(new Date("2022-08-01"))).toStrictEqual(["20-21", "21-22", "22-23"]);
65+
expect(getAcademicYears(new Date("2024-08-10"))).toStrictEqual([
66+
"20-21",
67+
"21-22",
68+
"22-23",
69+
"23-24",
70+
"24-25",
71+
]);
72+
73+
expect(getAcademicYears(new Date("2020-07-31"))).toStrictEqual([]);
74+
expect(getAcademicYears(new Date("2024-08-04"), new Date("2019-07-01"))).toStrictEqual([
75+
"18-19",
76+
"19-20",
77+
"20-21",
78+
"21-22",
79+
"22-23",
80+
"23-24",
81+
"24-25",
82+
]);
83+
expect(getAcademicYears(new Date("1990-07-31"))).toStrictEqual([]);
84+
85+
expect(getAcademicYears(new Date("2024-08-01"), new Date("2022-07-31"))).toStrictEqual([
86+
"21-22",
87+
"22-23",
88+
"23-24",
89+
"24-25",
90+
]);
91+
92+
expect(getAcademicYears(new Date("2024-06-30"), new Date("2023-09-01"))).toStrictEqual([
93+
"23-24",
94+
]);
95+
});
5696
});

common/eactivities/src/getAcademicYear.ts

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const CURRENT_MILLENIUM = 2000;
3434
*
3535
* @param currentDate Current date
3636
*/
37-
export function getAcademicYear(currentDate: Date) {
37+
export function getAcademicYear(currentDate: Date): AcademicYear {
3838
// Extract the year
3939
const year = currentDate.getFullYear();
4040
const currentYearShort = year - CURRENT_MILLENIUM;
@@ -45,3 +45,77 @@ export function getAcademicYear(currentDate: Date) {
4545
// Otherwise, we are in the previous academic year
4646
return `${currentYearShort - 1}-${currentYearShort}`;
4747
}
48+
49+
/**
50+
* Generates a list of academic years between a start date and an end date.
51+
*
52+
* An academic year runs from 1st August of one year to 31st July of the next year.
53+
* The function returns academic years in the format `shortyear-shortyear` (e.g., '20-21', '23-24') - see {@link AcademicYear}.
54+
*
55+
* **Allowed Date Range:**
56+
* - Earliest allowed start date: 1st August 2020
57+
* - Latest allowed end date: 31st July 2099
58+
*
59+
* @param endDate - The end date up to which academic years should be generated. Must be within the allowed range.
60+
* @param startDate - The start date from which to begin generating academic years. Defaults to 1st August 2020 (so academic year '20-21').
61+
* @returns An array of academic years between the start and end dates, inclusive.
62+
*
63+
* @throws Will throw an error if the provided dates are outside the allowed range.
64+
* @throws Will return an empty array if the start date is after the end date.
65+
*
66+
* @example
67+
* ```typescript
68+
* getAcademicYears(new Date("2024-08-01"), new Date("2022-07-31"));
69+
* // Returns: ['21-22', '22-23', '23-24', '24-25']
70+
*
71+
* getAcademicYears(new Date("2024-06-30"), new Date("2023-09-01"));
72+
* // Returns: ['23-24']
73+
* ```
74+
*/
75+
export function getAcademicYears(
76+
endDate: Date,
77+
startDate: Date = new Date("2020-08-01"),
78+
): AcademicYear[] {
79+
const earliestDate = new Date("2010-08-01");
80+
const latestDate = new Date("2099-07-31");
81+
82+
// Ensure dates are within the allowed range
83+
if (startDate < earliestDate || endDate > latestDate) {
84+
throw new Error(
85+
"Dates must be within the range from 1st August 2020 to 31st July 2099, and the start date must be before the end date.",
86+
);
87+
}
88+
89+
if (startDate > endDate) {
90+
return [];
91+
}
92+
93+
const academicYears: AcademicYear[] = [];
94+
95+
let startYear = startDate.getFullYear();
96+
const startMonth = startDate.getMonth();
97+
98+
// Adjust startYear if the startDate is before 1st August of the same year
99+
if (startMonth < 7) {
100+
// Month is zero-indexed, so July is 6
101+
startYear--;
102+
}
103+
104+
let endYear = endDate.getFullYear();
105+
const endMonth = endDate.getMonth();
106+
107+
// Adjust endYear if the endDate is before 1st August of the same year
108+
if (endMonth < 7) {
109+
// Month is zero-indexed, so July is 6
110+
endYear--;
111+
}
112+
113+
// Generate academic years
114+
for (let year = startYear; year <= endYear; year++) {
115+
const nextYear = year + 1;
116+
const academicYear: AcademicYear = `${year % 100}-${nextYear % 100}` as AcademicYear;
117+
academicYears.push(academicYear);
118+
}
119+
120+
return academicYears;
121+
}

0 commit comments

Comments
 (0)