Skip to content

Repository files navigation

sml-tzdb

CI

UTC-offset lookup for a small, hand-coded set of timezones in Standard ML. Converts a civil timestamp to a UTC offset (in minutes) using exact, weekday-based DST rules — no system calls, no file I/O, and not the full IANA database.

Supported zones: UTC, America/New_York, America/Chicago, America/Denver, America/Los_Angeles, Europe/London, Europe/Paris, Europe/Berlin, Asia/Kolkata, Asia/Tokyo, Asia/Shanghai. Any other name falls back to UTC (offset 0).

API sketch

(* UTC offset in minutes for a given civil instant *)
val off : int = Tzdb.offsetMinutes "America/New_York"
              { year=2024, month=7, day=4, hour=12, minute=0 }
(* -240  (EDT = UTC-4, expressed as -240 minutes) *)

(* Human-readable offset string *)
val s : string = Tzdb.utcOffset "Asia/Kolkata"
               { year=2024, month=1, day=1, hour=0, minute=0 }
(* "+0530" *)

(* Is daylight saving time in effect? *)
val d : bool = Tzdb.isDst "America/New_York"
             { year=2024, month=3, day=10, hour=12, minute=0 }   (* true *)

(* Zone abbreviation for the instant *)
val a : string = Tzdb.abbreviation "America/New_York"
               { year=2024, month=1, day=15, hour=12, minute=0 } (* "EST" *)

(* Discovery *)
val zs : string list = Tzdb.listZones ()
val k  : bool = Tzdb.knownZone "Asia/Tokyo"   (* true *)

Types

type zone    = string   (* IANA zone name, e.g. "America/Chicago" *)
type instant = { year : int, month : int, day : int,
                 hour : int, minute : int }

Known limitations

  • Not the IANA database. Only the zones listed above are known, and their rules are hand-coded, not loaded from tzdata. Historical rule changes (e.g. pre-2007 US DST dates) are not represented — the current rules are applied to every year.
  • Exact transitions, current rules. US DST = 2nd Sunday of March 02:00 to 1st Sunday of November 02:00; EU DST = last Sunday of March to last Sunday of October, computed with a real weekday calculation (Sakamoto). Instants within the one-hour transition window are not specially disambiguated.
  • Fixed-offset zones (Asia/Kolkata +05:30, Asia/Tokyo +09:00, Asia/Shanghai +08:00, UTC) have no DST and are always exact.
  • Civil instants are interpreted as wall-clock time in the given zone.
  • Zone names are case-sensitive; unknown zones return offset 0 / abbreviation "UTC" and isDst = false rather than raising. month is 1-indexed.

Installing with smlpkg

smlpkg add github.com/sjqtentacles/sml-tzdb
smlpkg sync

Reference from your .mlb:

lib/github.com/sjqtentacles/sml-tzdb/tzdb.mlb

Building and testing

make test        # MLton
make test-poly   # Poly/ML
make all-tests   # both
make clean

Example

make example builds and runs examples/demo.sml, which looks up UTC offsets, DST status, and abbreviations for seven zones at two fixed civil instants — no system clock is read (output is byte-identical under MLton and Poly/ML):

=== sml-tzdb demo ===

known zones     = 11
knownZone "Asia/Tokyo"   = true
knownZone "Mars/Olympus" = false

-- 2024-07-04 12:00 (northern-hemisphere summer) --
  UTC                 offset=+0000  (0 min)  dst=false  abbr=UTC
  America/New_York    offset=-0400  (~240 min)  dst=true  abbr=EDT
  America/Los_Angeles offset=-0700  (~420 min)  dst=true  abbr=PDT
  Europe/London       offset=+0100  (60 min)  dst=true  abbr=BST
  Europe/Berlin       offset=+0200  (120 min)  dst=true  abbr=CEST
  Asia/Kolkata        offset=+0530  (330 min)  dst=false  abbr=IST
  Asia/Tokyo          offset=+0900  (540 min)  dst=false  abbr=JST

-- 2024-01-15 12:00 (northern-hemisphere winter) --
  UTC                 offset=+0000  (0 min)  dst=false  abbr=UTC
  America/New_York    offset=-0500  (~300 min)  dst=false  abbr=EST
  America/Los_Angeles offset=-0800  (~480 min)  dst=false  abbr=PST
  Europe/London       offset=+0000  (0 min)  dst=false  abbr=GMT
  Europe/Berlin       offset=+0100  (60 min)  dst=false  abbr=CET
  Asia/Kolkata        offset=+0530  (330 min)  dst=false  abbr=IST
  Asia/Tokyo          offset=+0900  (540 min)  dst=false  abbr=JST

Project layout

sml.pkg
Makefile
lib/github.com/sjqtentacles/sml-tzdb/
  tzdb.sig     TZDB signature
  tzdb.sml     compiled timezone rules + offset lookup
  tzdb.mlb
test/
  test.sml     known-city offset tests (winter and summer)

License

MIT. See LICENSE.

About

Hand-coded timezone UTC-offset lookup in Standard ML with exact weekday-based DST transitions, isDst, zone abbreviations, and zone discovery.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages