From ac65f50c01f60a9fe54c268d9af84797ee431644 Mon Sep 17 00:00:00 2001 From: Kishan Sambhi Date: Sat, 10 Aug 2024 22:58:50 +0100 Subject: [PATCH] feat: new get academic years function --- .../eactivities/src/getAcademicYear.spec.ts | 42 +++++++++- common/eactivities/src/getAcademicYear.ts | 76 ++++++++++++++++++- 2 files changed, 116 insertions(+), 2 deletions(-) diff --git a/common/eactivities/src/getAcademicYear.spec.ts b/common/eactivities/src/getAcademicYear.spec.ts index 4989f91..57aea1b 100644 --- a/common/eactivities/src/getAcademicYear.spec.ts +++ b/common/eactivities/src/getAcademicYear.spec.ts @@ -1,4 +1,4 @@ -import { getAcademicYear, isValidAcademicYear } from "./getAcademicYear"; +import { getAcademicYear, getAcademicYears, isValidAcademicYear } from "./getAcademicYear"; describe("getAcademicYear", () => { it("should return the academic year if set before August", async () => { @@ -53,4 +53,44 @@ describe("getAcademicYear", () => { expect(isValidAcademicYear("22-2")).toBe(false); }); }); + + it("should return the correct academic years", () => { + expect(getAcademicYears(new Date("2020-08-01"))).toStrictEqual(["20-21"]); + + expect(getAcademicYears(new Date("2021-08-01"))).toStrictEqual(["20-21", "21-22"]); + + expect(getAcademicYears(new Date("2022-07-31"))).toStrictEqual(["20-21", "21-22"]); + + expect(getAcademicYears(new Date("2022-08-01"))).toStrictEqual(["20-21", "21-22", "22-23"]); + expect(getAcademicYears(new Date("2024-08-10"))).toStrictEqual([ + "20-21", + "21-22", + "22-23", + "23-24", + "24-25", + ]); + + expect(getAcademicYears(new Date("2020-07-31"))).toStrictEqual([]); + expect(getAcademicYears(new Date("2024-08-04"), new Date("2019-07-01"))).toStrictEqual([ + "18-19", + "19-20", + "20-21", + "21-22", + "22-23", + "23-24", + "24-25", + ]); + expect(getAcademicYears(new Date("1990-07-31"))).toStrictEqual([]); + + expect(getAcademicYears(new Date("2024-08-01"), new Date("2022-07-31"))).toStrictEqual([ + "21-22", + "22-23", + "23-24", + "24-25", + ]); + + expect(getAcademicYears(new Date("2024-06-30"), new Date("2023-09-01"))).toStrictEqual([ + "23-24", + ]); + }); }); diff --git a/common/eactivities/src/getAcademicYear.ts b/common/eactivities/src/getAcademicYear.ts index bfdaf65..45d00a2 100644 --- a/common/eactivities/src/getAcademicYear.ts +++ b/common/eactivities/src/getAcademicYear.ts @@ -34,7 +34,7 @@ const CURRENT_MILLENIUM = 2000; * * @param currentDate Current date */ -export function getAcademicYear(currentDate: Date) { +export function getAcademicYear(currentDate: Date): AcademicYear { // Extract the year const year = currentDate.getFullYear(); const currentYearShort = year - CURRENT_MILLENIUM; @@ -45,3 +45,77 @@ export function getAcademicYear(currentDate: Date) { // Otherwise, we are in the previous academic year return `${currentYearShort - 1}-${currentYearShort}`; } + +/** + * Generates a list of academic years between a start date and an end date. + * + * An academic year runs from 1st August of one year to 31st July of the next year. + * The function returns academic years in the format `shortyear-shortyear` (e.g., '20-21', '23-24') - see {@link AcademicYear}. + * + * **Allowed Date Range:** + * - Earliest allowed start date: 1st August 2020 + * - Latest allowed end date: 31st July 2099 + * + * @param endDate - The end date up to which academic years should be generated. Must be within the allowed range. + * @param startDate - The start date from which to begin generating academic years. Defaults to 1st August 2020 (so academic year '20-21'). + * @returns An array of academic years between the start and end dates, inclusive. + * + * @throws Will throw an error if the provided dates are outside the allowed range. + * @throws Will return an empty array if the start date is after the end date. + * + * @example + * ```typescript + * getAcademicYears(new Date("2024-08-01"), new Date("2022-07-31")); + * // Returns: ['21-22', '22-23', '23-24', '24-25'] + * + * getAcademicYears(new Date("2024-06-30"), new Date("2023-09-01")); + * // Returns: ['23-24'] + * ``` + */ +export function getAcademicYears( + endDate: Date, + startDate: Date = new Date("2020-08-01"), +): AcademicYear[] { + const earliestDate = new Date("2010-08-01"); + const latestDate = new Date("2099-07-31"); + + // Ensure dates are within the allowed range + if (startDate < earliestDate || endDate > latestDate) { + throw new Error( + "Dates must be within the range from 1st August 2020 to 31st July 2099, and the start date must be before the end date.", + ); + } + + if (startDate > endDate) { + return []; + } + + const academicYears: AcademicYear[] = []; + + let startYear = startDate.getFullYear(); + const startMonth = startDate.getMonth(); + + // Adjust startYear if the startDate is before 1st August of the same year + if (startMonth < 7) { + // Month is zero-indexed, so July is 6 + startYear--; + } + + let endYear = endDate.getFullYear(); + const endMonth = endDate.getMonth(); + + // Adjust endYear if the endDate is before 1st August of the same year + if (endMonth < 7) { + // Month is zero-indexed, so July is 6 + endYear--; + } + + // Generate academic years + for (let year = startYear; year <= endYear; year++) { + const nextYear = year + 1; + const academicYear: AcademicYear = `${year % 100}-${nextYear % 100}` as AcademicYear; + academicYears.push(academicYear); + } + + return academicYears; +}