Functional Weave
Code in Python

education.school-year-group@1.0.1

impl/typescript.ts

1,633 bytes · the TypeScript implementation · view raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

import { parseIsoDate } from "./dates_add_days.ts";  ← from dates.add-days ^1.0.0 · built alongside by fune
import { COHORT_RULES, YEAR_GROUPS } from "./education_school_year_group_data.ts";  ← this capability’s own data, compiled from data/cohort-rules.json into the same file by fune build
import { type SchoolYearGroup, type UkNation } from "./education_school_year_group_types.ts";

/**
 * The year group a child is in on a date, placed by their birth date.
 *
 * The cohort comes from the birth date itself (born on or after the cohort
 * start joins a year later), never from an age on a cut-off date, which
 * misplaces 29 February births where the cohort starts on 1 March.
 */
export function schoolYearGroup(birthDate: string, onDate: string, nation: UkNation): SchoolYearGroup {
  const birth = parseIsoDate(birthDate);
  const on = parseIsoDate(onDate);
  if (onDate < birthDate) {
    throw new RangeError(`onDate ${onDate} is before birthDate ${birthDate}`);
  }
  const rule = COHORT_RULES.find((r) => r.nation === nation);
  if (rule === undefined) {
    throw new RangeError(`unknown nation "${nation}": use england, wales, scotland or northern-ireland`);
  }
  const birthMonthDay = birthDate.slice(5);
  const onMonthDay = onDate.slice(5);
  const entryYear = birth.year + rule.entryAge + (birthMonthDay >= rule.cohortStart ? 1 : 0);
  const startYear = onMonthDay >= rule.schoolYearStart ? on.year : on.year - 1;
  const index = startYear - entryYear;
  const name = YEAR_GROUPS.find((g) => g.nation === nation && g.index === index);
  return {
    schoolYearStart: `${String(startYear).padStart(4, "0")}-${rule.schoolYearStart}`,
    entryYear,
    index,
    yearGroup: name === undefined ? null : name.label,
    stage: name === undefined ? null : name.stage,
  };
}