Functional Weave
Code in TypeScript

payroll.notice-period

Statutory minimum notice in weeks from continuous service: one week per year from two years, capped at twelve.

1.0.0 (not the latest) · published 2026-10-03 by charlie · Anterra

Pinned by 10 tests, run in TypeScript, Python and Rust.

Not professional advice. This capability calculates payroll figures from published rules. It is a software component for developers, not tax or legal advice. Rules change and every rate here has an effective date. Check that the dates cover your case. Verify results against the official sources listed in its README, and have a payroll specialist review how you use it, before anyone relies on the output. Provided “as is” under its licence, without warranty.

What it does

The statutory minimum notice for ending a contract of employment in Great Britain, from the Employment Rights Act 1996 s.86:

| Continuous service on the day notice is given | Employer must give | Employee must give | |---|---|---| | under one month | no statutory minimum (0) | no statutory minimum (0) | | one month to under two years | 1 week | 1 week | | two years to under twelve years | 1 week per completed year | 1 week | | twelve years or more | 12 weeks | 1 week |

For example

  • statutoryNotice(2026-09-01, 2026-09-23) → service years 0, employer weeks 0, employee weeks 0 under a month's service: no statutory notice either way
  • statutoryNotice(2026-08-25, 2026-09-23) → service years 0, employer weeks 0, employee weeks 0 one day short of a month
  • statutoryNotice(2026-08-24, 2026-09-23) → service years 0, employer weeks 1, employee weeks 1 exactly one month: one week each way

The function

The same function in TypeScript, Python and Rust, pinned by the same tests. Pick your language; the choice follows you around the registry.

export function statutoryNotice(startDate: string, noticeDate: string): StatutoryNotice
startDatedatefirst day of continuous employment
noticeDatedatethe day notice is given; service is counted up to and including it
returnsStatutoryNotice

The type it declares, generated into your project

/** The minimum each side must give under ERA 1996 s.86. */
export interface StatutoryNotice {
  /** completed years of continuous service on noticeDate */
  readonly serviceYears: number;
  /** minimum notice the employer must give: 0 under one month's service */
  readonly employerWeeks: number;
  /** minimum notice the employee must give: 1 week from one month's service, never more */
  readonly employeeWeeks: number;
}

Your code names it in one line, in the file that uses it

import { statutoryNotice } from "#fune/payroll.notice-period@^1";
impl/typescript.ts · 15 lines · open · raw

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

import { lengthOfService } from "./hr_length_of_service.ts";  ← from hr.length-of-service ^1.0.0 · built alongside by fune
import { type StatutoryNotice } from "./payroll_notice_period_types.ts";

/**
 * ERA 1996 s.86 minimum notice. Below one month's service the section does
 * not apply at all, which is different from one week: an employer who
 * dismisses on day 20 owes no statutory notice.
 */
export function statutoryNotice(startDate: string, noticeDate: string): StatutoryNotice {
  const service = lengthOfService(startDate, noticeDate);
  const atLeastOneMonth = service.years > 0 || service.months > 0;
  let employerWeeks = 0;
  if (atLeastOneMonth) employerWeeks = service.years < 2 ? 1 : Math.min(service.years, 12);
  return { serviceYears: service.years, employerWeeks, employeeWeeks: atLeastOneMonth ? 1 : 0 };
}

Install

fune build

With that line in your source, in a TypeScript project (language typescript in fune.project), fune build resolves it and its 1 dependency, pins them in fune.lock, downloads only the TypeScript package of each, and builds the code above into your project’s .fune/build, one readable file per capability with a header linking back here. Or pin a range in fune.project and build in one step:

fune add payroll.notice-period
Download for TypeScript payroll.notice-period-1.0.0-typescript.fune · 5,983 bytes sha256 9949a82990724e5ff725bc152ea7bdf2ba56d8f909838fc7a533e28feb10d255

The manifest, vectors and README with only the TypeScript implementation. Install it without the registry with fune add ./payroll.notice-period-1.0.0-typescript.fune, or fetch it from a terminal with fune pull payroll.notice-period@1.0.0:typescript.

The whole function, every language, is one file too: payroll.notice-period-1.0.0.fune, 8,084 bytes, sha256 2ffa1493b724e7a2ad4e78005fe7800be20ff73a78fe669ee042abed9ce74163. It installs into a project of any language.

Customise it in your app

The seams this capability offers. Put a marker directly above a function of your own and fune build wires it into the built code; the package on the registry is not changed, the built file’s header lists it under CUSTOMISED, and fune hooks lists every hook in the project. How hooks work.

before — your function gets the arguments and returns them, changed or not, or throws to refuse the call.

// fune: before payroll.notice-period

after — your function gets the result and the arguments, and returns the final result.

// fune: after payroll.notice-period

replace — inside this capability’s code only, calls to a dependency go to your function, with the same signature. Other capabilities that use it are unaffected; write in * to replace it everywhere.

// fune: replace hr.length-of-service in payroll.notice-period

step — your function runs at a numbered point inside the function’s body, receives the in-scope values it names as parameters, and may return replacements. List the points with fune show payroll.notice-period --steps.

// fune: step payroll.notice-period after <n|label>

Tests

A version published now needs at least 8 tests for every function, and one that expects the error for each function that throws; the registry refuses it otherwise. fune verify --all runs each case in TypeScript, Python and Rust, and a project runs them again with fune verify. This page lists the cases; it does not run them. The exact JSON is vectors.json.

CaseArgumentsExpected
under a month's service: no statutory notice either way 2026-09-01, 2026-09-23 → service years 0, employer weeks 0, employee weeks 0
one day short of a month 2026-08-25, 2026-09-23 → service years 0, employer weeks 0, employee weeks 0
exactly one month: one week each way 2026-08-24, 2026-09-23 → service years 0, employer weeks 1, employee weeks 1
a day short of two years is still one week 2024-01-01, 2025-12-30 → service years 1, employer weeks 1, employee weeks 1
two years on the anniversary: two weeks 2024-01-01, 2025-12-31 → service years 2, employer weeks 2, employee weeks 1
six completed years: six weeks 2020-03-15, 2026-09-23 → service years 6, employer weeks 6, employee weeks 1
a day short of twelve years is eleven weeks 2014-04-01, 2026-03-30 → service years 11, employer weeks 11, employee weeks 1
twelve years: twelve weeks 2014-04-01, 2026-03-31 → service years 12, employer weeks 12, employee weeks 1
thirty years is capped at twelve weeks 1996-01-01, 2026-01-01 → service years 30, employer weeks 12, employee weeks 1
notice before the start date is an error 2026-09-23, 2026-09-01 → error: is before startDate

More from the author

Service is measured with hr.length-of-service up to and including the day notice is given, so the extra week arrives on the anniversary itself.

A contract can give longer notice, never shorter; this returns only the statutory floor. It does not cover summary dismissal for gross misconduct, payment in lieu, or s.86(4) (fixed-term contracts of a month or less treated as indefinite after three months' service). Northern Ireland has its own equivalent legislation and is not covered.

Source: Employment Rights Act 1996 s.86, "Rights of employer and employee to minimum notice", https://www.legislation.gov.uk/ukpga/1996/18/section/86.

Files

PathBytes
README.md1,138
impl/python.py810
impl/rust.rs1,204
impl/typescript.ts770
vectors.json1,637