timezone-data 0.1.0

no_std, no-alloc parser for embedded IANA TZif timezone data: transitions, zone types, POSIX TZ rules, leap seconds, and zone metadata.
Documentation
# timezone-data

A `#![no_std]`, allocation-free Rust crate that parses IANA TZif timezone files
and exposes the raw timezone data most libraries keep private: transitions, zone
types, POSIX `TZ` rules, leap seconds, and per-zone metadata.

Timezone data is compiled from the [official IANA source](https://data.iana.org/time-zones/releases/)
and embedded in the crate as an uncompressed zip archive, so there is no
dependency on the host system's timezone files — and **no external crate
dependencies at all**.

This is a Rust port of the Go package [`gotz`](https://github.com/KarpelesLab/gotz).

## Highlights

- **`no_std` + no `alloc`.** Everything borrows into the embedded `&'static`
  bytes and decodes lazily through iterators. Nothing is heap-allocated.
- **Zero dependencies.**
- **Complete IANA database** embedded (600 entries, including the `zone1970.tab`
  and `iso3166.tab` metadata tables).

## Usage

```rust
use timezone_data::load;

let z = load("America/New_York")?;

// Inspect zone types (EST, EDT, ...).
for zt in z.types() {
    println!("{}  offset={}  dst={}", zt.abbrev, zt.offset, zt.is_dst);
}

// Iterate historical transitions.
for t in z.transitions() {
    let zt = z.type_at(t.type_idx);
    println!("{} -> {}", t.when, zt.abbrev);
}

// Look up the active zone at a specific Unix timestamp.
let zt = z.lookup(1_700_000_000);
println!("zone: {} (UTC offset {})", zt.abbrev, zt.offset);

// Get the POSIX TZ rule for future transitions.
if let Some(rule) = z.extend() {
    let (start, end) = rule.transitions_for_year(2025).unwrap();
    println!("DST starts: {start}, ends: {end}");
}

// Country and coordinates metadata.
if let Some(m) = z.meta() {
    if let Some(c) = m.countries().next() {
        println!("country: {} ({})", c.name, c.code);
    }
    println!("location: {}, {}", m.lat, m.lon);
}
# Ok::<(), timezone_data::Error>(())
```

Times are expressed as `i64` Unix seconds — the crate is timezone-library
agnostic. If you need a `chrono`/`time` value, convert at the boundary;
[`Zone::raw_data`] also returns the original TZif bytes for feeding into another
parser.

## API overview

| Item | Description |
|------|-------------|
| `load(name) -> Result<Zone, Error>` | Load a zone by IANA name (`""`/`"UTC"` → UTC). |
| `load_insensitive(name)` | Load with case-insensitive fallback. |
| `parse(name, data)` | Parse arbitrary TZif bytes. |
| `names()` | Iterate every embedded entry name. |
| `Zone::types()` / `type_at(i)` | Local time types (abbrev, offset, DST flag). |
| `Zone::transitions()` | Stored transition records. |
| `Zone::leap_seconds()` | Leap-second records. |
| `Zone::lookup(unix)` | Zone type in effect at an instant. |
| `Zone::transitions_for_range(start, end)` | Stored + POSIX-generated transitions in `[start, end)`. |
| `Zone::extend()` / `extend_raw()` | Parsed / raw POSIX `TZ` footer. |
| `Zone::meta()` | Country + coordinate metadata. |
| `parse_posix_tz(s)` | Parse a POSIX `TZ` string directly. |

## Updating the embedded data

`zoneinfo.zip` is committed to the repository. To refresh it from a new IANA
release, compile the tzdata with `zic` and repackage it with **no compression**
(STORE) — the embedded reader does not implement inflate. The original `gotz`
repository's `update.sh` / `mkzip.go` produce a compatible archive; copy the
resulting `zoneinfo.zip` into this crate's root and rebuild.

## License

MIT. Timezone data is in the public domain (IANA).