# gizlang:time

calendar dates in UTC from milliseconds since 1970-01-01, as JavaScript's Date keeps them (proleptic Gregorian; System.time() is now).

```gizlang
import * as Time from "gizlang:time";
```

## Types

### `DateTime`

```gizlang
type DateTime = { year: i64; month: i64; day: i64; hour: i64; minute: i64; second: i64; millisecond: i64; }
```

A civil date and time, in UTC or in the zone that made it.

- `year`: `i64`
- `month`: `i64`
- `day`: `i64`
- `hour`: `i64`
- `minute`: `i64`
- `second`: `i64`
- `millisecond`: `i64`

### `CivilDate`

```gizlang
type CivilDate = { year: i64; month: i64; day: i64; }
```

A civil date without a time: what a day number (days since 1970-01-01) is.

- `year`: `i64`
- `month`: `i64`
- `day`: `i64`

### `TimeError`

```gizlang
type TimeError = { message: string; code: i64; }
```

A time failure: what is wrong and a code.

- `message`: `string`
- `code`: `i64`

### `Zone`

```gizlang
type Zone
```

Offsets are seconds east of UTC. A Zone is owned data, independent of its Dir.

Opaque: create and use it through this module's functions.

## Functions

### `daysFromCivil`

```gizlang
function daysFromCivil(year: i64, month: i64, day: i64): i64
```

Days since 1970-01-01 of a civil date, and back (H. Hinnant's algorithms):
the one calendar every date in Gizlang goes through, GizDB's SQL dates too.

Effects: fail.

### `dateOfDay`

```gizlang
function dateOfDay(days: i64): CivilDate
```

The civil date of a day number (days since 1970-01-01).

Effects: fail.

### `utc`

```gizlang
function utc(ms: i64): DateTime
```

The UTC date and time of MS, milliseconds since 1970-01-01 UTC.

Effects: fail.

### `utcMs`

```gizlang
function utcMs(d: DateTime): i64
```

The milliseconds since 1970-01-01 UTC of the UTC date and time D.

Effects: fail.

### `weekday`

```gizlang
function weekday(ms: i64): i64
```

0 is Sunday, as JavaScript's getUTCDay.

Effects: fail.

### `weekdayOfDay`

```gizlang
function weekdayOfDay(day: i64): i64
```

The weekday of DAY (days since 1970-01-01, a Thursday): 0 is Sunday.

Effects: fail.

### `dayNames`

```gizlang
function dayNames(long: bool): Vec<string>
```

The English names of the days, Sunday first (weekday's order): "Sun" or, when LONG, "Sunday".

Effects: fail.

### `monthNames`

```gizlang
function monthNames(long: bool): Vec<string>
```

The English names of the months, January first: "Jan" or, when LONG, "January".

Effects: fail.

### `iso`

```gizlang
function iso(ms: i64): string
```

`2026-10-09T03:24:17.304Z`, as JavaScript's toISOString: years outside 0 to
9999 take a sign and six digits (`+010901-04-24...`).

Effects: fail.

### `parseZone`

```gizlang
function parseZone(data: bytes): Zone throws TimeError
```

The zone of a TZif file's bytes (RFC 8536, versions 1-3, no leap seconds): data a program carries, as
GizDB carries the tz database. O(bytes), allocating the transition, type and offset vectors once.

Effects: fail.

### `posixZone`

```gizlang
function posixZone(text: string, rules: string): Zone throws TimeError
```

The zone a POSIX TZ string names ("CST6CDT,M3.2.0,M11.1.0", "<-01:30>+01:30"; offsets west of UTC). A daylight
name without rules takes `rules` ("M3.2.0,M11.1.0", as PostgreSQL's posixrules gives them).

Effects: fail.

### `zone`

```gizlang
function zone(dir: Dir, name: string): Zone throws TimeError
```

Read once through the supplied directory capability; O(file bytes), allocating
transition/type/offset vectors once. No global IO or cache; queries borrow them.

Effects: fail, io.

### `monthDays`

```gizlang
function monthDays(year: i64, month: i64): i64
```

The number of days in MONTH (1 to 12) of YEAR.

Effects: fail.

### `addDays`

```gizlang
function addDays(d: DateTime, days: i64): DateTime requires valid(d) && days> = -MAX_DAY_ADJUSTMENT && days <= MAX_DAY_ADJUSTMENT
```

Calendar operations preserve the clock; apply Zone.instant to resolve DST.

Effects: fail.

### `addMonths`

```gizlang
function addMonths(d: DateTime, months: i64): DateTime requires valid(d) && months> = -MAX_MONTH_ADJUSTMENT && months <= MAX_MONTH_ADJUSTMENT
```

D moved by MONTHS months; a day past the end of the month becomes its last day.

Effects: fail.

### `addYears`

```gizlang
function addYears(d: DateTime, years: i64): DateTime requires valid(d) && years> = -MAX_YEAR_ADJUSTMENT && years <= MAX_YEAR_ADJUSTMENT
```

D moved by YEARS years; February 29 becomes February 28 in a year that is not a leap year.

Effects: fail.

### `daysBetween`

```gizlang
function daysBetween(from: DateTime, to: DateTime): i64 requires valid(from) && valid(to)
```

Signed civil-date distance (to - from), independent of time-of-day and DST.

Effects: fail.

### `parseIso`

```gizlang
function parseIso(text: string): i64 throws TimeError
```

Extended ISO calendar date-time, mandatory Z or ±HH:MM[:SS], 1-3 fraction digits.

Effects: fail.

## Methods

### `Zone.offset`

```gizlang
function Zone.offset(self: Zone, ms: i64): i64 requires ms> = -MAX_ZONE_INSTANT_MS && ms <= MAX_ZONE_INSTANT_MS
```

O(log transitions), no allocation. TZif's type zero applies before the table.

Effects: fail.

### `Zone.abbreviation`

```gizlang
function Zone.abbreviation(self: Zone, ms: i64): string requires ms> = -MAX_ZONE_INSTANT_MS && ms <= MAX_ZONE_INSTANT_MS
```

The zone's abbreviation in effect at `ms` ("KST", "PDT"), or "" when the zone has none.

Effects: fail.

### `Zone.local`

```gizlang
function Zone.local(self: Zone, ms: i64): DateTime
```

The local date and time in this zone of MS, milliseconds since 1970-01-01 UTC.

Effects: fail.

### `Zone.instant`

```gizlang
function Zone.instant(self: Zone, d: DateTime): i64 throws TimeError
```

O(types * log transitions); only a gap scans the table. No allocation.

Effects: fail.

### `Zone.iso`

```gizlang
function Zone.iso(self: Zone, ms: i64): string
```

MS as ISO 8601 text in this zone, with its offset.

Effects: fail.

## Constants

### `MILLISECONDS_PER_SECOND`

```gizlang
const MILLISECONDS_PER_SECOND = 1000
```

The number of milliseconds in one second: 1000.

### `MILLISECONDS_PER_MINUTE`

```gizlang
const MILLISECONDS_PER_MINUTE = 60000
```

The number of milliseconds in one minute: 60000.

### `MILLISECONDS_PER_HOUR`

```gizlang
const MILLISECONDS_PER_HOUR = 3600000
```

The number of milliseconds in one hour: 3600000.

### `MILLISECONDS_PER_DAY`

```gizlang
const MILLISECONDS_PER_DAY = 86400000
```

The number of milliseconds in one day: 86400000.

### `SECONDS_PER_MINUTE`

```gizlang
const SECONDS_PER_MINUTE = 60
```

The number of seconds in one minute: 60.

### `MINUTES_PER_HOUR`

```gizlang
const MINUTES_PER_HOUR = 60
```

The number of minutes in one hour: 60.

### `SECONDS_PER_HOUR`

```gizlang
const SECONDS_PER_HOUR = 3600
```

The number of seconds in one hour: 3600.

### `SECONDS_PER_DAY`

```gizlang
const SECONDS_PER_DAY = 86400
```

The number of seconds in one day: 86400.

### `MAX_ZONE_INSTANT_MS`

```gizlang
const MAX_ZONE_INSTANT_MS = 9000000000000000000
```

The most milliseconds of an instant that a zone conversion accepts.

### `MAX_DAY_ADJUSTMENT`

```gizlang
const MAX_DAY_ADJUSTMENT = 365000000
```

The most days that a date adjustment adds or subtracts.

### `MAX_MONTH_ADJUSTMENT`

```gizlang
const MAX_MONTH_ADJUSTMENT = 12000000
```

The most months that a date adjustment adds or subtracts.

### `MAX_YEAR_ADJUSTMENT`

```gizlang
const MAX_YEAR_ADJUSTMENT = 1000000
```

The most years that a date adjustment adds or subtracts.

