Skip to content

Instantly share code, notes, and snippets.

@Xevion
Created December 1, 2022 00:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Xevion/651061307321201c0d8ea90e8f60f7ad to your computer and use it in GitHub Desktop.
Save Xevion/651061307321201c0d8ea90e8f60f7ad to your computer and use it in GitHub Desktop.
import { z } from "zod";
import { getMonth } from "date-fns";
export const SeasonEnum = z.enum(["FALL", "SPRING"]);
export type Season = z.TypeOf<typeof SeasonEnum>;
export const SemesterSchema = z.object({
season: SeasonEnum,
year: z.number().min(2000).max(2050),
});
export type Semester = z.infer<typeof SemesterSchema>;
const semesterRanges: Record<Season, [number, number]> = {
[SeasonEnum.enum.FALL]: [8, 12],
[SeasonEnum.enum.SPRING]: [0, 4],
};
/**
* Given a date, retrieve the season it resides within.
* @param time The date to operate on. Assumed UTC.
* @return {Season|null} The season, if the date is in one. If no seasons match, null is returned.
*/
export const getSeason = (time: Date): Season | null => {
const semesterEntry = Object.entries(semesterRanges).find(([, [startMonth, endMonth]]) => {
const month = getMonth(time);
console.log({ month, startMonth, endMonth });
return month >= startMonth && month <= endMonth;
});
return semesterEntry != null ? (semesterEntry[0] as Season) : null;
};
/**
* Given the date of a specific event, identify the semester it occurs within.
* @param time {Date} The date to operate on. Assumed UTC.
* @return {Semester|null} The semester (season & year) the date occurs within. If no seasons match, null is returned.
*/
export const getSemester = (time: Date): Semester | null => {
const season = getSeason(time);
return season != null ? SemesterSchema.parse({ season, year: time.getUTCFullYear() }) : null;
};
/**
* Calculate the start and end dates for a given Semester.
* This is useful for generating min/max values while filtering events in the database.
* @param season {Season} The season to use the range of. Spring, for example, might be January to May.
* @param year {number|null} The year of the date range. If null, it will default to the current year (UTC).
*/
export const getSemesterRange = (
season: Season,
year: number | null = null
): { start: Date; end: Date } => {
if (year == null) year = new Date().getUTCFullYear();
const [startMonth, endMonth] = semesterRanges[season];
return {
start: new Date(year, startMonth),
end: new Date(year, endMonth),
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment