Functional Weave
Code in Rust

hr.length-of-service@1.0.0

impl/typescript.ts

1,216 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 } from "./dates_add_days.ts";  ← from dates.add-days ^1.0.0 · built alongside by fune
import { addMonths } from "./dates_add_months.ts";  ← from dates.add-months ^1.0.0 · built alongside by fune
import { type ServiceLength } from "./hr_length_of_service_types.ts";

/**
 * Completed years, months and days of service, both end dates included.
 *
 * The end is moved to the following day so that a service period ending on
 * the eve of an anniversary counts as a whole year; forgetting that is the
 * off-by-one that denies someone a statutory right by a day.
 */
export function lengthOfService(startDate: string, endDate: string): ServiceLength {
  const totalDays = daysBetween(startDate, endDate) + 1;
  if (totalDays < 1) {
    throw new RangeError(`endDate ${endDate} is before startDate ${startDate}`);
  }
  const endExclusive = addDays(endDate, 1);
  let months =
    (Number(endExclusive.slice(0, 4)) - Number(startDate.slice(0, 4))) * 12 +
    (Number(endExclusive.slice(5, 7)) - Number(startDate.slice(5, 7)));
  while (months > 0 && addMonths(startDate, months) > endExclusive) months -= 1;
  const anniversary = addMonths(startDate, months);
  return {
    years: Math.floor(months / 12),
    months: months % 12,
    days: daysBetween(anniversary, endExclusive),
    totalDays,
  };
}