menios icon indicating copy to clipboard operation
menios copied to clipboard

Timezone support using IANA tz database

Open pbalduino opened this issue 3 months ago • 0 comments

Problem

meniOS currently lacks timezone awareness. All time operations assume UTC with no ability to:

  • Convert between timezones
  • Handle daylight saving time (DST) transitions
  • Display local time based on geographic location
  • Support POSIX TZ environment variable

This limitation affects:

  • Timestamp display in shell/utilities (always shows UTC)
  • Build system timestamps (no local time conversion)
  • Application time handling (can't respect user's timezone)
  • Future network services (no timezone negotiation)

Goal

Implement full timezone support using the authoritative IANA timezone database (tzdata), enabling meniOS to:

  • Parse and interpret timezone rules
  • Convert UTC ↔ local time
  • Handle DST transitions automatically
  • Support standard timezone identifiers (America/New_York, Europe/London, etc.)

IANA tz Database

Source: https://www.iana.org/time-zones

The IANA timezone database (tzdata) provides:

  • Historical and current timezone rules for all regions
  • DST transition dates and offsets
  • Leap second information
  • POSIX timezone string format

Latest release: tzdata2024b (updated regularly)

Format: Compiled binary files (tzfile(5)) or source text files

Proposed Architecture

High-Level Flow

User sets TZ="America/New_York"
    ↓
libc reads /usr/share/zoneinfo/America/New_York
    ↓
Parse tzfile format (TZif binary)
    ↓
Apply timezone rules to UTC time
    ↓
Return local time with DST awareness

Components Required

1. Network Stack (Prerequisite)

Issues: #67-#73 (TCP/IP stack)

To download tzdata from IANA:

  • TCP/IP networking
  • DNS resolution
  • HTTP/HTTPS support

2. TLS/SSL Support (Prerequisite)

New dependency: TLS library (mbedTLS, BearSSL, or libressl)

IANA serves tzdata over HTTPS:

  • https://data.iana.org/time-zones/tzdata-latest.tar.gz
  • Requires TLS 1.2+ support
  • Certificate validation

3. Archive Extraction (Prerequisite)

New dependency: tar and gzip support

tzdata is distributed as .tar.gz:

  • gzip decompression
  • tar archive extraction
  • File creation in /usr/share/zoneinfo/

4. Timezone Library (Core Implementation)

New component: libtz or integrate into libc

Responsibilities:

  • Parse TZif binary format (tzfile(5))
  • Interpret POSIX timezone strings
  • Apply transition rules
  • Cache timezone data

5. Kernel Integration

Kernel changes: Minimal

Kernel should:

  • Keep system time in UTC (already done)
  • Provide syscalls for time retrieval (already done: gettimeofday, clock_gettime)
  • NOT handle timezones (keep this in userspace)

Implementation Phases

Phase 1: Download and Extract tzdata (#299)

Prerequisites: Network (#67-#73), TLS library, tar/gzip support

Tasks:

  • [ ] Implement or port gzip decompression
  • [ ] Implement or port tar extraction
  • [ ] Download tzdata from IANA over HTTPS
  • [ ] Extract to /usr/share/zoneinfo/
  • [ ] Verify file integrity (SHA-512 checksums provided by IANA)

Estimate: 2-3 weeks (assuming network stack exists)

Phase 2: TZif Parser (#300)

Prerequisites: Phase 1 complete

Tasks:

  • [ ] Implement TZif binary format parser (version 2/3)
  • [ ] Read timezone files from /usr/share/zoneinfo/
  • [ ] Extract transition times and offsets
  • [ ] Handle leap seconds (optional)
  • [ ] Cache parsed timezone data

Format: TZif files have this structure:

struct tzhead {
    char tzh_magic[4];      // "TZif"
    char tzh_version;       // '2' or '3'
    char tzh_reserved[15];
    char tzh_ttisutcnt[4];  // UTC/local indicators
    char tzh_ttisstdcnt[4]; // Standard/wall indicators
    char tzh_leapcnt[4];    // Leap second count
    char tzh_timecnt[4];    // Transition time count
    char tzh_typecnt[4];    // Local time type count
    char tzh_charcnt[4];    // Timezone abbrev char count
};
// Followed by transition times, type indices, ttinfo structs, abbrev strings

Estimate: 1-2 weeks

Phase 3: Timezone Conversion API (#301)

Prerequisites: Phase 2 complete

Tasks:

  • [ ] Implement tzset() - initialize timezone from TZ env var
  • [ ] Implement localtime() - convert time_t to struct tm (local)
  • [ ] Implement gmtime() - convert time_t to struct tm (UTC) [already done via #290]
  • [ ] Implement mktime() - convert struct tm to time_t [already done via #290]
  • [ ] Implement timegm() - UTC version of mktime
  • [ ] Handle DST transitions automatically
  • [ ] Support POSIX TZ strings (e.g., "EST5EDT,M3.2.0,M11.1.0")

API Example:

// Set timezone
setenv("TZ", "America/New_York", 1);
tzset();

// Convert UTC to local time
time_t utc_time = time(NULL);
struct tm *local = localtime(&utc_time);
printf("%s", asctime(local));  // Shows local time with DST

Estimate: 2-3 weeks

Phase 4: Integration and Testing (#302)

Prerequisites: Phase 3 complete

Tasks:

  • [ ] Update ls to show local file timestamps
  • [ ] Update shell prompt to show local time
  • [ ] Add date utility with timezone support
  • [ ] Test DST transitions (spring forward, fall back)
  • [ ] Test timezone changes (travel across zones)
  • [ ] Regression tests for edge cases

Test Cases:

  • Before/after DST transition
  • Leap years
  • Historical timezone changes
  • Future timezone predictions
  • Invalid timezone names
  • Missing tzdata files

Estimate: 1-2 weeks

Phase 5: Timezone Configuration Utility (#303)

Prerequisites: Phase 4 complete

Tasks:

  • [ ] Implement tzselect or similar utility
  • [ ] Allow user to set system timezone
  • [ ] Persist timezone in /etc/localtime or /etc/timezone
  • [ ] Support TZ environment variable override

Estimate: 1 week

Dependencies

This issue has significant prerequisites:

Critical Blockers

  1. Network Stack (#67-#73) - Required to download tzdata
  2. TLS/SSL Library (new issue needed) - HTTPS support for IANA
  3. Archive Support (new issue needed) - tar and gzip extraction

Nice to Have

  1. DNS Resolution (#70) - Resolve data.iana.org
  2. HTTP Client (#72) - Download over HTTP/HTTPS

Soft Dependencies

  1. File Write Support (#189) ✅ COMPLETE - Write tzdata to disk
  2. VFS Streaming I/O (#294) ✅ COMPLETE - Handle large tzdata files

Alternative Approach: Bundled tzdata

To avoid network/TLS dependencies initially:

  • Bundle tzdata in disk image during build
  • Extract tzdata2024b.tar.gz on host
  • Copy compiled zoneinfo files to /usr/share/zoneinfo/ in disk image
  • Skip download phase (Phases 1) initially
  • Add download capability later when network stack ready

Pros:

  • Can implement timezone support now
  • No network dependencies
  • Smaller initial scope

Cons:

  • Timezone data becomes stale (need manual updates)
  • Larger disk image
  • No automatic updates

Timeline Estimate

With Bundled tzdata (Recommended First)

  • Phase 2: TZif parser - 1-2 weeks
  • Phase 3: Conversion API - 2-3 weeks
  • Phase 4: Integration - 1-2 weeks
  • Phase 5: Configuration - 1 week
  • Total: 5-8 weeks

With Network Download (Future)

  • Phase 1: Download/extract - 2-3 weeks
  • Phase 2-5: Same as above - 5-8 weeks
  • Total: 7-11 weeks (requires network stack first)

References

  • IANA tz database: https://www.iana.org/time-zones
  • tzfile(5) format: https://man7.org/linux/man-pages/man5/tzfile.5.html
  • tzset(3) API: https://man7.org/linux/man-pages/man3/tzset.3.html
  • POSIX TZ strings: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html

Related Issues

  • #67-#73 - TCP/IP networking stack
  • #290 - Time conversion utilities (gmtime/mktime) ✅ COMPLETE
  • #189 - FAT32 write support ✅ COMPLETE
  • #294 - VFS streaming I/O ✅ COMPLETE

Recommendation

Start with bundled tzdata approach:

  1. Bundle tzdata in disk image (no network needed)
  2. Implement TZif parser (Phase 2)
  3. Implement conversion API (Phase 3)
  4. Integrate into utilities (Phase 4)
  5. Later: Add network download when TCP/IP stack ready

This allows timezone support to be implemented independently of the network stack, providing immediate value to users.

pbalduino avatar Oct 17 '25 13:10 pbalduino