gnss-time 0.5.2

Type-safe GNSS time scales: GPS, GLONASS, Galileo, BeiDou, TAI, UTC — no_std by default
Documentation

gnss-time

Crates.io no_std docs.rs MSRV Embedded

Strongly typed GNSS time model with zero-cost conversions and explicit leap second handling.

gnss-time is a minimal, high-performance library for representing and converting time across GNSS and atomic time scales:

  • GLONASS
  • GPS
  • Galileo
  • BeiDou
  • TAI
  • UTC

This crate focuses on correctness, type safety, and deterministic conversions, not on navigation or positioning algorithms.

Core Idea (mental model)

GNSS time is not a single system.

Each scale differs in:

  • epoch
  • unit definition
  • leap second behavior

This crate enforces:

different time scales are different types

So invalid mixing is impossible at compile time.

API in 2 minutes

use gnss_time::prelude::*;

let gps = Time::<Gps>::from_week_tow(2200, DurationParts {
    seconds: 0,
    nanos: 0,
}).unwrap();

// Fixed conversion (zero-cost)
let gal: Time<Galileo> = gps.into_scale().unwrap();

GNSS Time Primer

GNSS systems define different time scales:

  • GLONASS → UTC(SU)-aligned (leap-second dependent)
  • GPS / Galileo → TAI − 19s (fixed offset)
  • BeiDou (BDT) → TAI − 33s (fixed offset)
  • TAI → continuous atomic time
  • UTC → civil time with leap seconds

The same physical moment may have multiple valid representations.

Features

Type-safe time domains

Each scale is a distinct type:

  • Glonass
  • Gps
  • Galileo
  • Beidou
  • Tai
  • Utc

Cross-scale arithmetic is not allowed implicitly.

Zero-cost abstractions

Arithmetic compiles down to native operations:

  • Time + Durationu64 + u64
  • no heap allocations
  • no runtime overhead in fast path

Explicit conversion model

Conversions are categorized:

  • Fixed → constant offset (zero-cost)
  • EpochShift → deterministic shift
  • Contextual → leap second aware

Leap-second aware UTC

UTC conversions support:

  • leap second table lookup
  • ambiguity detection
  • explicit result model:
ConvertResult::Exact
ConvertResult::AmbiguousLeapSecond

Conversion graph inspection

The library exposes the full conversion matrix:

  • 6×6 scale graph
  • fixed vs contextual edges
  • runtime inspection tools

Performance

Arithmetic

Operation Cost
Time + Duration (panic path) ~0.5 ns
checked_add ~4.3 ns
saturating_add ~0.5 ns

Conversions

Operation Cost
GPS → Galileo / TAI / BeiDou ~0.8–1.0 ns
GPS → UTC (leap-second aware) ~9–10 ns
UTC → GPS ~22 ns

Important design choice

UTC is contextual

UTC conversions:

  • depend on leap second table
  • are not always invertible
  • may be ambiguous during leap insertion

This is intentional and modeled explicitly.

Example: leap-second aware conversion

use gnss_time::prelude::*;

let gps = Time::<Gps>::from_week_tow(
        2200,
        DurationParts {
            seconds: 0,
            nanos: 0,
        },
    )
    .unwrap();

let ls = LeapSeconds::builtin();
let result: ConvertResult<Time<Utc>> = gps.into_scale_with_checked(ls).unwrap();

match result {
    ConvertResult::Exact(utc) => {
        println!("UTC: {}", utc);
    }
    ConvertResult::AmbiguousLeapSecond(utc) => {
        println!("Leap second ambiguity: {}", utc);
    }
}

No domain mixing guarantee

Invalid operations are rejected at compile time:

let gps: Time<Gps> = ...;
let utc: Time<Utc> = ...;

// ❌ compile error
let x = gps + utc;

Design goals

  • Prevent GNSS time domain mixing at compile time
  • Make leap seconds explicit and unavoidable
  • Provide deterministic conversions where possible
  • Achieve zero-cost abstractions over raw timestamps
  • Be fully no_std compatible
  • Serve as a foundational GNSS time layer

Supported scales

Scale Format
GLONASS Day / TOD
GPS Week / TOW
Galileo Week / TOW
BeiDou Week / TOW
TAI Seconds + nanos
UTC Leap-second aware

Status

  • Core types
  • Fixed conversions
  • Leap second handling
  • Conversion matrix
  • Embedded-safe arithmetic

License

Dual-licensed under:

  • MIT
  • Apache-2.0