Production Recipes

Real-World Code Examples

Copyable, production-grade TypeScript recipes for common business logic: from identity age verification and subscription billing schedules to hotel stay pricing and database serialization.

Identity & ComplianceBeginner

User Date of Birth & Age Verification

Try in Playground

Validate user-submitted birth dates, verify minimum age requirements (e.g., 18+), and prevent impossible or future birth dates.

date-of-birth.ts
400 font-semibold">import { parseDate, addYears, isBefore, isAfter, todayUtc } 400 font-semibold">from 400 font-semibold">class="text-emerald-400">"daysafe";
400 font-semibold">interface AgeValidationResult {
valid: boolean;
error?: string;
birthDate?: string;
}
400 font-semibold">export 400 font-semibold">function validateBirthDate(rawInput: string, minimumAge = 18): AgeValidationResult {
400 font-semibold">const birthDate = parseDate(rawInput);
400 font-semibold">if (!birthDate) {
400 font-semibold">return { valid: 400 font-semibold">false, error: 400 font-semibold">class="text-emerald-400">"Invalid calendar date. Please enter YYYY-MM-DD." };
}
400 font-semibold">const today = todayUtc();
// 1. Cannot be born in the future
400 font-semibold">if (isAfter(birthDate, today)) {
400 font-semibold">return { valid: 400 font-semibold">false, error: 400 font-semibold">class="text-emerald-400">"Date of birth cannot be in the future." };
}
// 2. Minimum age threshold (birthDate + minAge <= today)
400 font-semibold">const requiredBirthday = addYears(birthDate, minimumAge);
400 font-semibold">if (isAfter(requiredBirthday, today)) {
400 font-semibold">return {
valid: 400 font-semibold">false,
error: 400 font-semibold">class="text-emerald-400">`User must be at least ${minimumAge} years old.`
};
}
400 font-semibold">return { valid: 400 font-semibold">true, birthDate };
}
// Example usage:
console.log(validateBirthDate(400 font-semibold">class="text-emerald-400">"2000-05-15")); 400 font-semibold">class=400 font-semibold">class="text-emerald-400">"text-slate-500 italic">// { valid: 400 font-semibold">true, birthDate: 400 font-semibold">class="text-emerald-400">"2000-05-15" }
console.log(validateBirthDate(400 font-semibold">class="text-emerald-400">"2026-02-30")); 400 font-semibold">class=400 font-semibold">class="text-emerald-400">"text-slate-500 italic">// { valid: 400 font-semibold">false, error: 400 font-semibold">class="text-emerald-400">"Invalid calendar date..." }
console.log(validateBirthDate(400 font-semibold">class="text-emerald-400">"2015-08-10")); 400 font-semibold">class=400 font-semibold">class="text-emerald-400">"text-slate-500 italic">// { valid: 400 font-semibold">false, error: 400 font-semibold">class="text-emerald-400">"User must be at least 18 years old." }
Why DaySafe Matters Here
  • ✓parseDate strictly validates format and calendar reality without silent rollover.
  • ✓addYears handles leap day birthdays (e.g. Feb 29 + 18 years clamps safely to Feb 28).
  • ✓todayUtc ensures verification isn't skewed by client machine clock timezone differences.
Billing & InvoicingIntermediate

Invoice Due Date & Net-30 Payment Terms

Try in Playground

Calculate payment deadlines for invoices (Net 15, Net 30, Net 60) and adjust if due dates fall on weekends.

invoice-due-date.ts
400 font-semibold">import { addDays, isWeekend, getDayOfWeek, formatDate } 400 font-semibold">from 400 font-semibold">class="text-emerald-400">"daysafe";
400 font-semibold">export 400 font-semibold">interface InvoiceTerms {
issueDate: string;
netDays: number;
rollWeekendToMonday?: boolean;
}
400 font-semibold">export 400 font-semibold">function calculateDueDate({
issueDate,
netDays,
rollWeekendToMonday = 400 font-semibold">true,
}: InvoiceTerms) {
400 font-semibold">let dueDate = addDays(issueDate, netDays);
400 font-semibold">if (rollWeekendToMonday && isWeekend(dueDate)) {
400 font-semibold">const dayOfWeek = getDayOfWeek(dueDate);
// 6 = Saturday (+2 days to Monday), 7 = Sunday (+1 day to Monday)
400 font-semibold">const daysToAdd = dayOfWeek === 6 ? 2 : 1;
dueDate = addDays(dueDate, daysToAdd);
}
400 font-semibold">const formattedDisplay = formatDate(dueDate, {
locale: 400 font-semibold">class="text-emerald-400">"en-US",
style: 400 font-semibold">class="text-emerald-400">"long",
});
400 font-semibold">return {
rawDueDate: dueDate,
formattedDisplay,
isRolledOver: isWeekend(addDays(issueDate, netDays)),
};
}
// Example: Net-30 from Friday Oct 30, 2026 -> falls on Sunday Nov 29 -> rolls to Monday Nov 30
console.log(calculateDueDate({ issueDate: 400 font-semibold">class="text-emerald-400">"2026-10-30", netDays: 30 }));
// { rawDueDate: "2026-11-30", formattedDisplay: "November 30, 2026", isRolledOver: true }
Why DaySafe Matters Here
  • ✓addDays uses pure integer arithmetic, avoiding Daylight Saving Time 23/25 hour bugs.
  • ✓isWeekend checks ISO 8601 day 6 (Saturday) and 7 (Sunday).
  • ✓formatDate produces a timezone-safe customer-facing string without day boundary shifts.
Subscriptions & SaaSIntermediate

Subscription Renewal & Month-End Clamping

Try in Playground

Schedule recurring monthly subscriptions where signups on the 29th, 30th, or 31st safely clamp to month boundaries.

subscription-billing.ts
400 font-semibold">import { addMonths, formatDate, todayUtc } 400 font-semibold">from 400 font-semibold">class="text-emerald-400">"daysafe";
400 font-semibold">export 400 font-semibold">function generateBillingSchedule(startDate: string, durationMonths = 6) {
400 font-semibold">const schedule: { cycle: number; billingDate: string; formatted: string }[] = [];
400 font-semibold">for (400 font-semibold">let i = 0; i < durationMonths; i++) {
400 font-semibold">const billingDate = addMonths(startDate, i);
schedule.push({
cycle: i + 1,
billingDate,
formatted: formatDate(billingDate, { locale: 400 font-semibold">class="text-emerald-400">"en-US", style: 400 font-semibold">class="text-emerald-400">"medium" }),
});
}
400 font-semibold">return schedule;
}
// User signs up on January 31:
400 font-semibold">const schedule = generateBillingSchedule(400 font-semibold">class="text-emerald-400">"2026-01-31", 4);
console.log(schedule);
/* Output:
Cycle 1: 400 font-semibold">class="text-emerald-400">"2026-01-31" (Jan 31)
Cycle 2: 400 font-semibold">class="text-emerald-400">"2026-02-28" (Feb 28 - clamped to month end!)
Cycle 3: 400 font-semibold">class="text-emerald-400">"2026-03-31" (Mar 31)
Cycle 4: 400 font-semibold">class="text-emerald-400">"2026-04-30" (Apr 30 - clamped to 30 days)
*/
Why DaySafe Matters Here
  • ✓Standard JS `new Date(2026, 0, 31)` + 1 month rolls over into March 3rd!
  • ✓DaySafe's addMonths clamps to February 28 (or 29 in leap years), preserving monthly cadence.
Hospitality & BookingsBeginner

Hotel Stay & Booking Duration Calculation

Try in Playground

Calculate exact night counts for reservations and validate check-in / check-out ordering.

booking-duration.ts
400 font-semibold">import { daysBetween, isBefore, isSame, addDays } 400 font-semibold">from 400 font-semibold">class="text-emerald-400">"daysafe";
400 font-semibold">export 400 font-semibold">function validateAndPriceBooking(
checkIn: string,
checkOut: string,
ratePerNightUsd: number
) {
400 font-semibold">if (isSame(checkIn, checkOut)) {
400 font-semibold">throw 400 font-semibold">new Error(400 font-semibold">class="text-emerald-400">"Check-out date must be at least one day after check-in.");
}
400 font-semibold">if (isBefore(checkOut, checkIn)) {
400 font-semibold">throw 400 font-semibold">new Error(400 font-semibold">class="text-emerald-400">"Check-out date cannot precede check-in date.");
}
400 font-semibold">const nights = daysBetween(checkIn, checkOut);
400 font-semibold">const totalPrice = nights * ratePerNightUsd;
400 font-semibold">return {
checkIn,
checkOut,
nights,
totalPrice,
};
}
// Spring DST transition weekend (e.g. March 7 to March 9):
// Timestamp subtraction with / 86400000 yields 1.958 days on 23-hour DST day!
// DaySafe daysBetween returns exact integer 2 nights:
console.log(validateAndPriceBooking(400 font-semibold">class="text-emerald-400">"2026-03-07", 400 font-semibold">class="text-emerald-400">"2026-03-09", 150));
// { checkIn: "2026-03-07", checkOut: "2026-03-09", nights: 2, totalPrice: 300 }
Why DaySafe Matters Here
  • ✓Eliminates fractional day distortions caused by 23-hour spring-forward or 25-hour fall-back days.
  • ✓Guarantees hotel guests are billed for the exact number of calendar nights.
UI ComponentsAdvanced

Calendar Month View Generation

Try in Playground

Generate complete calendar grids (start of month, end of month, padding days) for month-view UI components.

calendar-grid.ts
400 font-semibold">import { startOfMonth, endOfMonth, getDayOfWeek, addDays, toDateParts } 400 font-semibold">from 400 font-semibold">class="text-emerald-400">"daysafe";
400 font-semibold">export 400 font-semibold">interface CalendarDay {
date: string;
dayNumber: number;
isCurrentMonth: boolean;
isWeekend: boolean;
}
400 font-semibold">export 400 font-semibold">function buildMonthGrid(referenceDate: string): CalendarDay[] {
400 font-semibold">const monthStart = startOfMonth(referenceDate);
400 font-semibold">const monthEnd = endOfMonth(referenceDate);
400 font-semibold">const { month } = toDateParts(monthStart);
// ISO day: 1 = Monday ... 7 = Sunday
400 font-semibold">const startDayOfWeek = getDayOfWeek(monthStart);
// Calculate padding days to start on Monday
400 font-semibold">const gridStart = addDays(monthStart, -(startDayOfWeek - 1));
400 font-semibold">const days: CalendarDay[] = [];
400 font-semibold">let current = gridStart;
// 6 weeks * 7 days = 42 grid cells
400 font-semibold">for (400 font-semibold">let i = 0; i < 42; i++) {
400 font-semibold">const parts = toDateParts(current);
400 font-semibold">const dayOfWeek = getDayOfWeek(current);
days.push({
date: current,
dayNumber: parts.day,
isCurrentMonth: parts.month === month,
isWeekend: dayOfWeek >= 6,
});
current = addDays(current, 1);
}
400 font-semibold">return days;
}
400 font-semibold">const grid = buildMonthGrid(400 font-semibold">class="text-emerald-400">"2026-11-15");
console.log(400 font-semibold">class="text-emerald-400">`Generated ${grid.length} cells 400 font-semibold">for November 2026`);
console.log(400 font-semibold">class="text-emerald-400">"First grid cell:", grid[0]);
Why DaySafe Matters Here
  • ✓startOfMonth and endOfMonth establish precise boundaries.
  • ✓toDateParts provides clean integers without timezone translation.
  • ✓addDays generates continuous calendar grids seamlessly.
Backend & DatabaseBeginner

PostgreSQL & MySQL DATE Field Validation

Try in Playground

Safely validate and sanitize input for SQL DATE columns without converting through JavaScript Date timestamps.

database-date-fields.ts
400 font-semibold">import { parseDate, DateOnly } 400 font-semibold">from 400 font-semibold">class="text-emerald-400">"daysafe";
400 font-semibold">export 400 font-semibold">class AppointmentModel {
/**
* Sanitizes input before executing a database query:
* INSERT INTO appointments (patient_id, appointment_date) VALUES ($1, $2);
*/
400 font-semibold">static sanitizeDate(input: unknown): DateOnly {
400 font-semibold">const validated = parseDate(input);
400 font-semibold">if (!validated) {
400 font-semibold">throw 400 font-semibold">new Error(400 font-semibold">class="text-emerald-400">`Invalid SQL DATE value: "${String(input)}". Expected YYYY-MM-DD.`);
}
// Returns strictly validated YYYY-MM-DD string, preventing SQL syntax errors
400 font-semibold">return validated;
}
}
// Passing to ORMs like Prisma, Drizzle, or raw pg:
400 font-semibold">const safeDate = AppointmentModel.sanitizeDate(400 font-semibold">class="text-emerald-400">"2026-11-02");
console.log(safeDate); 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"
Why DaySafe Matters Here
  • ✓SQL DATE columns store calendar dates without time or offset.
  • ✓Passing a standard JS Date to ORMs often converts to UTC midnight timestamp, shifting the day in Western timezones.
  • ✓DaySafe DateOnly strings bind directly to SQL DATE columns with zero ambiguity.