Skip to content
tempo logoTempoDate & Time
Explicit Temporal parsing, timezone-safe arithmetic, and localized date/time formatting for TypeScript.
Version
v3.0.0
Size
3.8 KB gzip
BrowserNode ≥22SSRDeno
TemporalparsenownowInstantisValid View all 35 exports

Why Tempo?

Date/time bugs come from treating an instant and a wall-clock value as interchangeable. Tempo requires an explicit parse target and requires timeZone whenever a wall-clock value becomes an instant.

ts
// Before
const reminder = new Date(meeting.getTime() - 15 * 60_000);

// After
import { parse, shift } from '@vielzeug/tempo';

const localMeeting = parse('2026-03-21T10:30:00', { as: 'plainDateTime' });
const reminder = shift(localMeeting, { minutes: -15 }, { timeZone: 'America/New_York' });
FeatureTempodate-fnsNative Date
Bundle size3.8 KB~10 kB0 kB
Zero dependencies @js-temporal/polyfill
Explicit wall-time conversionManual
DST-safe arithmeticManualManual
Localized formatting Intl

Use Tempo when you need Temporal values, explicit timezone rules, and DST-safe operations.

Consider native Date when your data is only elapsed milliseconds and you do not need calendar or timezone behavior.

Installation

sh
pnpm add @vielzeug/tempo
sh
npm install @vielzeug/tempo
sh
yarn add @vielzeug/tempo

Quick Start

Parse a wall-clock input explicitly, attach its timezone, then format it for a user.

ts
import { format, parse, shift } from '@vielzeug/tempo';

const localMeeting = parse('2026-03-21T10:30:00', { as: 'plainDateTime' });
const reminder = shift(localMeeting, { minutes: -15 }, { timeZone: 'America/New_York' });
const text = format(reminder, {
  locale: 'en-US',
  pattern: 'short',
});

Features

  • parse() — Requires an explicit ISO target: instant, zoned date-time, plain date-time, or plain date.
  • toInstant() / inTimeZone() — Convert wall-clock and absolute values with explicit timezone semantics.
  • shift() / difference() — Apply DST-safe arithmetic across instant, zoned, and wall-clock inputs.
  • contains() / clamp() — Compare normalized ranges with optional calendar-unit precision.
  • startOf() / endOf() — Resolve timezone-aware calendar boundaries, including configurable week starts.
  • dateRange() / recurrence() — Generate validated, lazy zoned calendar sequences.
  • format() / formatRelative() / formatDuration() — Render localized values through Intl, including calendar-aware relative months and years.
  • classifyExpiry() — Classify fixed elapsed-time thresholds without month or year approximation.

Documentation

See Also

  • Rune — format stable Temporal timestamps before writing structured log records.
  • Vault — derive explicit expiry moments before storing records with TTL policies.