Skip to main content

spacetime

Write or fix application code using the spacetime JavaScript library for date parsing, timezone conversion, calendar arithmetic, comparisons, and formatting.

Source facts

Repository
spencermountain/spacetime
Last source activity
October 16, 2026 at 20:39
Detected SKILL.md language
English
Stars
4,107
Forks
191

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
spacetime
description
Write or fix application code using the spacetime JavaScript library for date parsing, timezone conversion, calendar arithmetic, comparisons, and formatting.
# Date-time operations with spacetime Use the public API of the application's installed version. Distinguish an **instant** from a **wall-clock time in a region**, and choose the timezone accordingly. Examples use the regular `spacetime` entry unless stated otherwise. ## Inputs and state - The constructor takes `(input, timezone?, options?)`; `fromUnixSeconds` takes `(seconds, timezone?, options?)`. Current-date helpers such as `now` and `today` take `(timezone?, options?)`. Omitted zones default to the host timezone. - Months are **0–11**, including array inputs; dates are **1–31**. `date()` is day of month; `day()` is weekday, with Sunday = 0. - Numeric inputs and `s.epoch` use **milliseconds**. Use `fromUnixSeconds()` for seconds. `s.epoch` and `s.tz` are properties, not methods. - Capture returned objects: `s = s.add(1, 'day')`. Most setters are immutable; calling without an argument reads the value. Setting an hour preserves minutes. - `epochSeconds(value)` and `weekStart(value)` mutate the receiver. `i18n()`, `extend()`/`plugin()`, and timezone data affect shared state; cloning does not isolate them. Avoid changing shared configuration per request. - Prefer complete inputs when defaults are unwanted. `{ dmy: true }` selects day/month parsing. `null`, `undefined`, and `''` mean **now**; validate missing input before construction if that is inappropriate for the application. - `isValid()` checks the resulting date, not strict input validity: parsing and setters can clamp values. Validate original fields when rejection is required. Unknown explicit timezone names can throw even with `silent: true`. ## Timezones and DST ```js import spacetime from 'spacetime' const meeting = spacetime('2026-01-15T09:30:00', 'America/New_York') meeting.goto('Europe/London').time() // '2:30pm': same instant meeting.timezone('Europe/London').time() // '9:30am': same wall clock, new instant meeting.offset() // -300: minutes east of UTC meeting.timezone().current.offset // -5: hours east of UTC ``` Use regional IANA names, not ambiguous abbreviations such as `EST`. A numeric offset identifies a fixed offset, not regional DST rules; parse it then `goto()` the region. Conversion can change the date. Do not manually apply another offset. Preserve fractional offsets; `Etc/GMT+5` reverses the usual sign and means UTC−05. Missing or repeated local times need care: choose an occurrence using a known epoch or explicit-offset timestamp. Do not assume missing times are rejected or invent an earlier/later/reject parsing option. Bundled annual rules are not a complete historical database and can give wrong transitions in other years. Host timezone updates do not update them; account for this when accuracy matters. ## Arithmetic and boundaries - `add(1, 'day')` preserves local clock time where it exists; `add(24, 'hours')` measures elapsed time. Calendar days and weeks can span different hours over DST. - Month arithmetic clamps: January 31 plus one month can be February 29; subtracting a month then gives January 29, not the original date. - Fractional days use elapsed time; half a day is 12 hours. Fractional months use 28 days, so half a month is 14 days. Rounding occurs on every call: `0.1` day rounds to two hours, so ten additions total 20 hours. Combine amounts when repeated rounding is unwanted. - `{ weekStart: 0 }` sets Sunday boundaries; Monday is the default. This does not redefine `week()` numbering. `day('monday', true)` allows equality; for a strictly later Monday use `s.add(1, 'day').day('monday', true)`. ## Comparisons and ranges Use valid Spacetime objects for comparisons. `isEqual()` compares instants; `isSame(other, unit)` compares calendar fields in the receiver's zone. Its third argument `false` compares each date's own local fields. `diff(other, unit)` is a whole-unit total, positive when `other` is later; no-unit totals are not components to sum. `since(other)` describes the argument relative to the receiver; `from(other)` reverses that direction, and `fromNow()` describes the receiver. `isBetween()` excludes endpoints unless its third argument is `true`. `every(unit, end, stepCount = 1)` excludes the end and can include an aligned start; an unaligned start advances to the next boundary. Short spans may return `[]`. Use positive integer steps and bound large ranges: results are collected eagerly. ## Formatting and transfer `format()` uses named tokens or braces: `s.format('{iso-year}-{iso-month}-{date-pad}')`. `iso-month` is one-based; `month-pad` is zero-based. `{time}` already includes AM/PM. `unixFmt('yyyy-MM-dd HH:mm')` uses a separate Unicode-style token system with limited coverage. Do not infer supported methods or tokens from other libraries. Store an epoch or UTC ISO timestamp for an instant, retaining the regional zone when needed for later calendar arithmetic. `toNativeDate()` preserves the instant but loses the zone; native Date's local getters use the host timezone. ## Temporal Regular `spacetime` accepts native `ZonedDateTime`, `Instant`, `PlainDate`, and `PlainDateTime` objects and returns a `ZonedDateTime` through `.toTemporal()`. These operations require `globalThis.Temporal`; no polyfill is bundled. Prefer native objects over annotated strings to preserve the chosen repeated-hour instant. Regular Spacetime retains milliseconds and uses its own timezone rules. `spacetime/temporal` is an experimental entry using Temporal's calendar and runtime timezone rules. It requires Temporal at construction and supports a smaller API; do not assume regular-entry methods such as `since`, `every`, or `i18n` exist. `.toTemporal()` and `.format('iso-full')` retain native precision. Verify relevant behavior against the installed version when choosing this entry or relying on DST transitions, month ends, or ambiguous inputs.
View on GitHub