Date and time
Instants, dates, clock times, and spans.
A time column is an instant, a calendar value, or a span.
Time
The value is a Temporal object. The schema timestamps codec is "temporal". Fractional seconds apply to timestamptz, timestamp, time, and timetz.
Bun and Node 26 provide a Temporal global. Node 22 and 24 need a polyfill assigned to globalThis.Temporal before these columns run. okmodel does not ship one. A missing global is OKM1210.
import { Temporal } from "temporal-polyfill";
globalThis.Temporal = Temporal;Instant
t.timestamptz() is timestamptz. The TypeScript value is Temporal.Instant. Postgres stores it in UTC. Storage is 8 bytes. A created time or an event uses it.
import { table, t } from "okmodel/pg";
export const notes = table("notes", {
id: t.identity(),
publishedAt: t.timestamptz(),
});Timestamp
t.timestamp() is timestamp. The TypeScript value is Temporal.PlainDateTime. It stores a civil date and time. Storage is 8 bytes.
import { table, t } from "okmodel/pg";
export const notes = table("notes", {
id: t.identity(),
editedAt: t.timestamp(),
});Date
t.date() is date. The TypeScript value is Temporal.PlainDate. It stores a calendar day. Storage is 4 bytes.
import { table, t } from "okmodel/pg";
export const notes = table("notes", {
id: t.identity(),
day: t.date(),
});Time of day
t.time() is time. The TypeScript value is Temporal.PlainTime. It stores a clock time. The zone is its own column. Storage is 8 bytes.
import { table, t } from "okmodel/pg";
export const notes = table("notes", {
id: t.identity(),
opens: t.time(),
});Offset
t.timetz() is timetz. The TypeScript value is { time, offset }. time is a Temporal.PlainTime. offset is +HH:MM or -HH:MM. A daylight-saving change needs the zone in its own column. Storage is 12 bytes.
import { table, t } from "okmodel/pg";
export const notes = table("notes", {
id: t.identity(),
shift: t.timetz(),
});OKM1210
An offset other than ±HH:MM is refused when the value is encoded. A timetz with a seconds offset such as +05:30:15 is OKM1210 on read.
Interval
t.interval() is interval. The TypeScript value is Temporal.Duration. It stores a span. Storage is 16 bytes. fields is one of year, month, day, hour, minute, second, year to month, day to hour, day to minute, day to second, hour to minute, hour to second, minute to second.
import { table, t } from "okmodel/pg";
export const notes = table("notes", {
id: t.identity(),
length: t.interval("day to second"),
});OKM1060
Any other fields value is refused.
OKM1210
An interval that mixes signs, such as 1 day -01:00:00, cannot be one Temporal.Duration. The decoders take the default IntervalStyle (postgres) and ISO-8601; sql_standard and postgres_verbose output is not read.
Fractional seconds
precision is fractional seconds, an integer from 0 to 6. Omit it for full precision. It applies to t.timestamptz(), t.timestamp(), t.time(), and t.timetz(). Digits past the sixth are rounded by Postgres on write: 2020-01-02T03:04:05.123456789Z reads back as .123457. An explicit precision truncates client-side instead. Either way a read-back differs from the written value past microseconds, with no warning.
import { table, t } from "okmodel/pg";
export const notes = table("notes", {
id: t.identity(),
editedAt: t.timestamp(0),
});OKM1060
A precision outside 0 to 6 is refused.
Next: Columns.