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,
};
}