Skip to content
clockworktz
v1.0.0 · zero dependencies · tzdb 2026f

clockworktzTimezones that get the weird zones right.

A zero-dependency timezone library for JavaScript and TypeScript. Half-hour and 45-minute offsets, 30-minute DST, skipped days, negative DST and historical local mean time, with DST gaps and overlaps resolved exactly the way Temporal does. In about 21 kB.

$npm install clockworktz
quick-start.ts
import { fromUTC, convert, format } from 'clockworktz'

fromUTC('2024-07-15T14:00:00Z', 'Australia/Lord_Howe')
// {
//   utc: '2024-07-15T14:00:00.000Z',
//   zone: 'Australia/Lord_Howe',
//   local: '2024-07-16 00:30:00.000',
//   offsetMinutes: 630,
//   isDST: false,
//   abbreviation: '+1030',
//   source: 'system-intl'
// }

// Strings without an offset are wall time in the source zone
convert('2024-07-15T16:30:00', 'Asia/Kathmandu', 'America/St_Johns').local
// '2024-07-15 08:15:00.000'

format('2024-07-15T14:00:00Z', 'Pacific/Chatham', 'yyyy-MM-dd HH:mm xxx')
// '2024-07-16 02:45 +12:45'

Right now

Eight zones that break naive timezone code

Not every zone is a whole number of hours from UTC, and not every DST shift is one hour. These clocks are live in your browser.

  • Australia/Lord_Howe
     30-minute DST
  • Pacific/Chatham
     +12:45 / +13:45
  • Asia/Kathmandu
     +05:45 all year
  • Australia/Eucla
     Unofficial +08:45
  • Pacific/Marquesas
     −09:30
  • Pacific/Kiritimati
     UTC+14, a day ahead
  • America/St_Johns
     Half-hour, with DST
  • Antarctica/Troll
     Two-hour DST

DST gaps and overlaps

Some local times never happen. Some happen twice.

When clocks spring forward, a wall time is skipped; when they fall back, it repeats. Pick a scenario and a strategy to see how interpretLocal resolves it.

Clocks jump from 02:00 EST to 03:00 EDT, so 02:30 never happens.

01:59 EST
02:00 – 02:59 skipped
03:00 EDT
interpretLocal('2024-03-10T02:30:00', 'America/New_York', {
  disambiguation: 'compatible',
})
// utc:   '2024-03-10T07:30:00.000Z'
// local: '2024-03-10 03:30:00.000' (EDT)
Read the disambiguation guide

Why clockworktz

Small, strict and exact

Examples

One small API for every timezone job

Convert instants and wall times, format with date-fns-style tokens, find transitions, and drive live clocks. Every output shown is the library's real result.

Full API reference
meeting.ts
import { convert, fromUTC } from 'clockworktz'

// 10:00 in London: what is that for everyone else?
const attendees = ['America/Los_Angeles', 'Asia/Kolkata', 'Australia/Sydney']

for (const zone of attendees) {
  const { local } = convert('2024-09-12T10:00:00', 'Europe/London', zone, {
    format: 'EEE HH:mm',
  })
  console.log(zone, local)
}
// America/Los_Angeles Thu 02:00
// Asia/Kolkata        Thu 14:30
// Australia/Sydney    Thu 19:00

// Instants work too: Date, epoch milliseconds, or ISO strings with an offset
fromUTC(new Date('2024-07-15T14:00:00Z'), 'Asia/Kolkata').local
// '2024-07-15 19:30:00.000'

// Fixed offsets are zones as well
fromUTC('2024-07-15T14:00:00Z', '+05:30').local
// '2024-07-15 19:30:00.000'

Engines

Use the platform's data, or pin your own

Both engines run the same conversions and are tested against the same fixtures. Switch with one call.

system-intl

Default

Uses the timezone data built into Node.js or the browser (ICU). Nothing to ship; updates arrive with the OS and runtime.

  • 0 kB of data
  • Always as fresh as the runtime
  • isDST derived from January and July offsets

embedded-tzdb

Opt-in · 30 kB gz

Uses a compiled IANA tzdb release from the clockworktz/tzdb subpath. You only pay for it if you import it.

  • Identical results on every platform
  • Exact DST flags, abbreviations and local mean time
  • Ed25519-signed updates, shared across tabs

Tested

If it's strange, it's in the test suite

Both engines are tested against the same exact fixtures. The embedded data is checked against ICU for every zone from 1970 onwards, and the suite runs under several host timezones and in Chromium, Firefox and WebKit.

  • Lord Howe +10:30 / +11
  • Chatham +12:45 / +13:45
  • Eucla +08:45
  • Kathmandu +05:45
  • Marquesas −09:30
  • Kiritimati +14
  • Samoa's skipped day, 2011
  • Casablanca's Ramadan DST
  • Dublin's negative DST
  • Troll's two-hour DST
  • Caracas 2016
  • Pyongyang 2015 & 2018
  • Etc/GMT+5 sign inversion
  • Europe/Kiev → Europe/Kyiv
  • Local mean time before 1900
  • Rules beyond 2100

Stop debugging 02:30 on a Sunday.