DocsGuide

Getting Started with DaySafe

DaySafe is a lightweight, zero-dependency TypeScript library engineered specifically for timezone-independent calendar date calculations.

What is DaySafe?

Most date calculations in modern web applications do not require a timestamp. Values such as dates of birth, hotel check-in days, invoice terms, subscription renewals, and SQL DATE fields represent specific whole calendar days on the civil calendar.

JavaScript's native Date object represents an instantaneous point in time (milliseconds since the Unix epoch in UTC). When formatted or manipulated in local timezones, timestamps frequently shift across midnight boundaries, resulting in insidious off-by-one errors.

The DaySafe Guarantee

DaySafe treats calendar dates as strict YYYY-MM-DD strings using branded types (DateOnly) and executes all arithmetic with exact integer civil calendar formulas. Local machine timezones and Daylight Saving Time cannot alter the results.

Installation

DaySafe is published to npm with zero runtime dependencies. Install it using your preferred package manager:

Terminal
# npm
$ npm install daysafe
# pnpm
$ pnpm add daysafe
# yarn
$ yarn add daysafe
# bun
$ bun add daysafe

Quick Start Example

Import individual functions directly from daysafe. Tree-shaking is fully supported in both ESM and CommonJS.

quickstart.ts
400 font-semibold">import {
parseDate,
isValidDate,
addDays,
addMonths,
daysBetween,
formatDate,
} 400 font-semibold">from 400 font-semibold">class="text-emerald-400">"daysafe";
// 1. Strict parsing and validation
400 font-semibold">const bookingDate = parseDate(400 font-semibold">class="text-emerald-400">"2026-11-02");
console.log(bookingDate); 400 font-semibold">class=400 font-semibold">class="text-emerald-400">"text-slate-500 italic">// 400 font-semibold">class="text-emerald-400">"2026-11-02" (typed 400 font-semibold">as DateOnly)
// Impossible calendar dates return null without silent rollover
400 font-semibold">const invalid = parseDate(400 font-semibold">class="text-emerald-400">"2026-02-30");
console.log(invalid); 400 font-semibold">class=400 font-semibold">class="text-emerald-400">"text-slate-500 italic">// 400 font-semibold">null
// 2. Predictable calendar arithmetic
400 font-semibold">const returnDate = addDays(400 font-semibold">class="text-emerald-400">"2026-11-02", 7);
console.log(returnDate); 400 font-semibold">class=400 font-semibold">class="text-emerald-400">"text-slate-500 italic">// 400 font-semibold">class="text-emerald-400">"2026-11-09"
// 3. Month arithmetic with end-of-month clamping
// Jan 31 + 1 month safely clamps to Feb 28 without spilling into March!
400 font-semibold">const nextMonth = addMonths(400 font-semibold">class="text-emerald-400">"2026-01-31", 1);
console.log(nextMonth); 400 font-semibold">class=400 font-semibold">class="text-emerald-400">"text-slate-500 italic">// 400 font-semibold">class="text-emerald-400">"2026-02-28"
// 4. Exact signed day differences (immune to DST clock changes)
400 font-semibold">const duration = daysBetween(400 font-semibold">class="text-emerald-400">"2026-11-01", 400 font-semibold">class="text-emerald-400">"2026-11-08");
console.log(duration); 400 font-semibold">class=400 font-semibold">class="text-emerald-400">"text-slate-500 italic">// 7
// 5. Timezone-safe locale formatting locked to UTC
400 font-semibold">const display = formatDate(400 font-semibold">class="text-emerald-400">"2026-11-02", {
locale: 400 font-semibold">class="text-emerald-400">"en-US",
style: 400 font-semibold">class="text-emerald-400">"long",
});
console.log(display); 400 font-semibold">class=400 font-semibold">class="text-emerald-400">"text-slate-500 italic">// 400 font-semibold">class="text-emerald-400">"November 2, 2026"

Parsing and Validation Workflow

Never pass untrusted user input directly into calculations. DaySafe provides two primary validation tools:

parseDate(input)

Returns a branded DateOnly string if the input strictly conforms to YYYY-MM-DD and is an authentic calendar day. Returns null on failure.

isValidDate(input)

Functions as a TypeScript type guard (input is DateOnly). Ideal for conditional branching in form validation and API route guards.

Predictable Error Handling

DaySafe follows standard ECMAScript error semantics:

  • TypeError is thrown if arguments have invalid types (e.g. non-string date, non-integer amount).
  • RangeError is thrown if calculations produce a year outside the supported civil range (0001-01-01 to 9999-12-31).

Explore the Interactive Playground

Test any of DaySafe's 23 functions live in your browser with real parameters.

Open Playground