Functional Weave
Code in TypeScript

health.gestational-age@1.0.1

impl/typescript.ts

1,422 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 { addDays, daysBetween, parseIsoDate } from "./dates_add_days.ts";  ← from dates.add-days ^1.0.0 · built alongside by fune
import { type GestationalAge } from "./health_gestational_age_types.ts";

/** Naegele's rule: 280 days (40+0 weeks) from the LMP for a 28-day cycle. */
const TERM_DAYS = 280;
/** 44+0 weeks: beyond this the dates are almost certainly wrong. */
const MAX_DAYS = 308;

/**
 * Gestational age and estimated due date from the last menstrual period. A
 * cycle longer or shorter than 28 days moves ovulation, so both are shifted by
 * the difference, as the NHS due date calculator does.
 */
export function gestationalAge(lmpDate: string, onDate: string, cycleLengthDays: number): GestationalAge {
  if (!Number.isInteger(cycleLengthDays) || cycleLengthDays < 20 || cycleLengthDays > 44) {
    throw new RangeError(`cycleLengthDays must be a whole number from 20 to 44, received ${cycleLengthDays}`);
  }
  parseIsoDate(lmpDate);
  parseIsoDate(onDate);
  const shift = cycleLengthDays - 28;
  const totalDays = daysBetween(lmpDate, onDate) - shift;
  if (totalDays < 0) {
    throw new RangeError(`onDate ${onDate} is before the adjusted start of pregnancy`);
  }
  if (totalDays > MAX_DAYS) {
    throw new RangeError(`gestational age of ${totalDays} days is more than 44+0 weeks: check the dates`);
  }
  return {
    weeks: Math.floor(totalDays / 7),
    days: totalDays % 7,
    totalDays,
    dueDate: addDays(lmpDate, TERM_DAYS + shift),
  };
}