@teakit/month

Use this skill when writing code for @teakit/month.

@teakit/month exports Month, an immutable year-month calculation API for ESM and browser environments.

Core Rules

  1. Import with import { Month } from "@teakit/month".
  2. Do not use default imports from @teakit/month.
  3. Create values with Month.from(...); do not use new Month(...) or call Month(...).
  4. Prefer canonical YYYY-MM strings with exactly four year digits and a zero-padded month, such as "2025-01".
  5. Do not generate signed or expanded year strings such as "+10000-01" or "-0001-12".
  6. Do not generate Month.from(2025, 1); pass a string, Date, month object, or Month instance as one argument.
  7. Use add(months) and sub(months) for month offsets.
  8. Use diff(other) or Month.diff(left, right) for signed month differences.
  9. Use Month methods instead of JavaScript Date arithmetic.
  10. Native Date input uses local calendar fields; prefer strings when timezone-free behavior matters.
  11. Treat Month instances as immutable. Do not mutate year, month, or index.
  12. Read month.year and month.month as strings; month.month is zero-padded, such as "01".
  13. Use toString() or JSON serialization for canonical month string output.
  14. Use toString({ precision: "year" | "month" | "day" }) only when explicit output precision is needed. Day precision requires a day anchor from a date-shaped string or native Date input and clamps to the target month's last valid day.
  15. Do not add day-level or year-level arithmetic or point-value APIs to @teakit/month; Teakit time point-value packages are split by granularity while keeping interface style consistent.
  16. Use Month.now() for the current local month; it equals Month.from(new Date()) and keeps today's day as a hidden anchor.
  17. Use month.days() (number of days in the month) and month.quarter() ("Q1""Q4") for month metadata; both are independent of any day anchor.
  18. Use month.clamp(min, max) to bound a month into an inclusive range; it throws when min is later than max. min/max are static-only helpers (Month.min(...), Month.max(...)).
  19. Do not generate startOfYear() or endOfYear(); they are not part of the API.
  20. Month values saturate to [0000-01, 9999-12]; arithmetic past either bound clamps to the boundary month and never emits signed or expanded years.
  21. The day anchor is hidden: it is never exposed by toObject() and never read from object input — it only enters from date-shaped string or Date input.
  22. Use month.isSameYear(other) or Month.isSameYear(left, right) to test whether two months fall in the same calendar year; only the year is compared.
  23. Every failure throws a MonthError (a subclass of Error) whose message keeps the [Month Error] prefix. Import it with import { Month, MonthError } from "@teakit/month" and discriminate with error instanceof MonthError instead of matching the message string.

Workflow

  1. Identify the operation: creation, month offsets, differences, comparison, ranges, or conversion.
  2. Load only the relevant method reference file from references/.
  3. In that file, read the intro, examples, API Reference, Agent Contract, and Agent Notes.
  4. Prefer Month.from(...), exact strings, and Month instance methods in generated code.
  5. For repository changes, run the local verification commands when relevant: bun run check, bun run typecheck, bun run test, and bun run build.
  6. For documentation site changes, also run bun run docs:build.

Quick Example

import { Month } from "@teakit/month";

const renewal = Month.from("2025-01").add(12);
renewal.year; // "2026"
renewal.month; // "01"
renewal.toString(); // "2026-01"

Month.from("2025-01-15").toString(); // "2025-01"
Month.from("2025-01-31").add(1).toString({ precision: "day" }); // "2025-02-28"
Month.from(new Date(2025, 0, 15)).toString(); // "2025-01"

Reference Selection

Read the smallest method file that answers the current task.

NeedRead
Create month valuesfrom
Create from a month indexfromIndex
Get the current monthnow
Check a value is a MonthisMonth
Add a month offsetadd
Subtract a month offsetsub
Count months between valuesdiff
Sort order of two valuescmp
Equality checkseq / ne
Ordering checksgt / ge / lt / le
Same calendar yearisSameYear
Earliest / latest of a setmin / max
Generate month sequencesrange
Days in the monthdays
Calendar quarterquarter
Bound a month into a rangeclamp
Render as a stringtoString
JSON serializationtoJSON
Primitive coercion valuevalueOf
Convert to a plain objecttoObject