Times, instants and the business's own clock
Why every time is an instant with an offset, how a slot carries the business's timezone, and what a clock change does to the free times.
Updated 8 October 2026 About 2 minutes View as Markdown
Every time the API sends or accepts is an instant: a moment that means the same thing everywhere, written with its offset. The API sends them in UTC and accepts any offset. Opening hours are the one exception, kept as times on the business's own wall clock, and turned into instants once, on the server.
Instants, with an offset
{
"start": "2026-10-06T07:00:00+00:00",
"end": "2026-10-06T07:45:00+00:00"
}
Compare and store them as instants, the way any date library parses them. A time sent without an offset is refused rather than guessed at: the browser's clock, the server's and the business's are three different answers, and a time with no offset silently picks one of them.
The business's timezone
availability() returns the slots with the business's timezone beside them,
and that is the clock to show them on.
import { localTime } from '@backendfree/bookings';
const { slots, timezone } = await bookings.availability({ service });
localTime(slots[0].start, timezone); // nine in the morning, the reader's way
localTime(slots[0].start, timezone, undefined, 'de-CH'); // '09:00'
Somebody booking a haircut in Zurich from a laptop set to New York wants to see nine in the morning, not three. The zone is the business's, and the way the time is written is the reader's.
Across a clock change
On the spring morning the clocks go forward, an hour of wall time never happens, and no slot is offered inside it. In autumn an hour happens twice, and the slots in it are offered as the instants they are, still inside opening hours. Neither needs anything from your side, as long as you send and store instants.