All notable changes to gnss-time are documented in this file.
The format follows Keep a Changelog. This project adheres to Semantic Versioning.
-
Introduce named constants for the Hinnant civil date conversion algorithm in
civil.rsto remove remaining magic numbers and improve symmetry withcivil_from_days.- Add DAYS_PER_ERA, DAYS_PER_4_YEAR_CYCLE, DAYS_PER_100_YEAR_CYCLE
- Add UNIX_EPOCH_FROM_CIVIL constant for epoch offset clarity
- Improve readability and maintainability of
days_to_unix - Align structure with
civil_from_daysimplementation style
-
Introduce named constants for the Hinnant civil date conversion algorithm in
epoch.rsto remove remaining magic numbers and improve symmetry withdays_from_unix_impl.- Add DAYS_PER_400_YEAR_ERAL, DAYS_FROM_CIVIL_TO_UNIX_EPOCH, YARS_PER_ERA
- Improve readability and maintainability of
days_from_unix_impl
-
Introduced
CivilDateTime— a proleptic Gregorian calendar date-time representation derived fromTime<Utc>. -
Added conversion API:
Time<Utc>::to_civil() -> CivilDateTimeCivilDateTime::from_utc_nanos(nanos: u64) -> Result<CivilDateTime, GnssTimeError>CivilDateTime::to_utc() -> Result<Time<Utc>, GnssTimeError>CivilDateTime::to_utc_nanos() -> Result<u64, GnssTimeError>
-
Implemented full
CivilDateTimestructure with nanosecond precision:year,month,dayhour,minute,secondnanos(sub-second component, 0–999_999_999)
-
Added
Displayimplementation for ISO 8601 / RFC 3339 formatting:- Format:
YYYY-MM-DDTHH:MM:SS.nnnnnnnnnZ - Example:
2024-01-15T12:34:56.123456789Z
- Format:
-
Ensured lossless round-trip conversions:
Time<Utc> → CivilDateTime → Time<Utc>preserves exact nanoseconds
-
Added comprehensive test coverage for:
- Epoch boundary (
1972-01-01T00:00:00Z) - GPS epoch alignment
- Leap year correctness
- Sub-second precision handling
- Day boundary transitions
- Round-trip correctness across full range
- Epoch boundary (
-
Added
is_whole_second()helper for fast sub-second checks -
Added example:
examples/civil_time.rsdemonstrating formatting and conversion usage
-
Enforced strict
no_stdcompatibility for core conversion logic (formatting remains conditionally available depending on feature flags) -
Displayimplementation is feature-gated depending on formatting strategy (std/alloc) -
Added comprehensive Postcard-based serialization test suite (
tests/serde_test.rs, 33 tests, behindserdefeature):-
Full round-trip coverage for
Time<S>across all scales (Gps,Utc,Tai,Galileo,Beidou,Glonass), including:EPOCH,MAX, and sub-second precision values
-
Wire format validation aligned with Postcard ULEB-128 encoding:
0→ 1 byte ([0x00])u64::MAX→ 10 bytes- Any
Time<S>→ ≤ 10 bytes - 1-week timestamp → 8 bytes
-
Raw byte-level encoding tests:
1 ns→[0x01]127 ns→[0x7F]128 ns→[0x80, 0x01]
-
Verified scale isolation:
- Identical nanoseconds produce identical wire format across scales
- Correct type-safe deserialization per scale
-
Added round-trip tests for:
Duration(ZERO, positive, negative,MIN,MAX)DurationParts(including boundary values)
-
Verified compatibility with heapless environments:
- Confirmed that a 16-byte buffer is sufficient for all supported types
-
Cross-format consistency tests:
- JSON ↔ Postcard round-trip equivalence
- Macro-based validation across all time scales
-
Integration tests:
- GPS ↔ UTC conversions with leap seconds + Postcard round-trip
- Unix time ↔ UTC + Postcard round-trip
-
-
Added
heapless = "0.8"todev-dependenciesfor embedded serialization testing -
Added
[[test]]configuration:serde_testis compiled only when--features serdeis enabled
-
Extended
docs/EMBEDDED.mdwith Compact binary serialization (Postcard) section:-
Formal wire format specification:
Time<S>→ ULEB-128 (u64, 1–10 bytes)Duration→ ZigZag + ULEB-128 (i64)DurationParts→ tuple[u64, u32]
-
Clarified that Postcard encoding is variable-length (not fixed 8 bytes)
-
Added recommended buffer sizing guidelines (≥ 16 bytes)
-
Added
heapless::Vecexample forno_stdenvironments -
Included telemetry packet example with real encoded size estimation
-
Documented
is_human_readable()behavior for JSON vs binary formats
-
-
Added optional
serdesupport behind theserdefeature flag.- New module
serde_impls.rs(compiled only with#[cfg(feature = "serde")]).
- New module
-
Added custom Serde implementations for core time types:
-
Time<S>— dual-format serialization:-
Human-readable:
{ "scale": "GPS", "nanos": 1356566418000000000 }- Includes runtime validation of
scalefield against the compile-time time scale. - Deserialization returns a descriptive error on mismatch.
- Includes runtime validation of
-
Compact: raw
u64nanoseconds (no scale tag, type-level encoding guarantees correctness).
-
-
Duration:- Human-readable:
{ "nanos": -7000000000 } - Compact: raw
i64nanoseconds
- Human-readable:
-
DurationParts:- Human-readable:
{ "seconds": 5, "nanos": 500000000 } - Compact:
[seconds, nanos]tuple encoding - Enforces invariant
nanos < 1_000_000_000via constructor validation
- Human-readable:
-
-
Implemented Serde using manual visitor-based deserialization (no proc-macros).
- Uses
is_human_readable()to switch formats at runtime. - Fully
no_stdcompatible (whenserdeis built withdefault-features = false). - Error reporting implemented without allocations using
fmt::Display.
- Uses
-
Added 42 Serde-related tests:
- Exact JSON format validation
- Round-trip tests for all supported time scales
- Error cases for scale mismatches
- Compact vs human-readable consistency checks
- Postcard binary round-trip tests
- Boundary tests (
EPOCH,MIN,MAX) - Size comparison tests (compact vs JSON)
- Integration tests across multiple time scales
-
Added documentation section: Serde support
- Describes all formats per type
- Includes usage examples
- Explains design constraints (no proc-macro, no alloc)
-
Extended
docs/ARCHITECTURE.md:- Added Serde design rationale
- Added serialization format specification table
- Updated feature flag matrix
- Updated CI guarantees section
-
Updated
Cargo.toml:-
Added optional dependency:
serde = { version = "1", default-features = false, optional = true }
-
Added feature flag:
serde = ["dep:serde"]
-
Added
allocfeature flag (preparation for future extensions) -
Added dev-dependencies:
serde_jsonpostcard(withallocfeature for tests)
-
Updated
docs.rsmetadata to includeserdefeature
-
-
Updated
src/lib.rs:-
Added conditional module:
#[cfg(feature = "serde")] mod serde_impls;
-
Added Serde usage example in crate-level documentation
-
Updated feature flags documentation table
-
-
в
Cargo.tomlдобавлен serde, как опциональная зависимость -
Added Unix/UTC/GPS epoch constants:
UTC_EPOCH_UNIX_OFFSET_SUTC_EPOCH_UNIX_OFFSET_NSGPS_EPOCH_UNIX_SUTC_CIVIL_EPOCH
-
Added Unix time conversion API:
Time<Utc>::from_unix_secondsTime<Utc>::from_unix_nanosTime<Utc>::as_unix_secondsTime<Utc>::as_unix_nanosTime<Gps>::from_unix_seconds(withLeapSecondsProvider)Time<Gps>::as_unix_seconds(withLeapSecondsProvider)
-
Enforced UTC epoch lower bound (1972-01-01) for Unix → UTC conversions
-
Added unit tests covering Unix ↔ UTC ↔ GPS round-trips and edge cases
-
Added
unix_time.rsexample with 8 sections and complete demonstrations:- Epoch constants — demonstration of constants
- Unix epoch before UTC epoch → error case
- UTC epoch from Unix → UTC epoch
- Round-trip seconds for 8 historical dates
- Round-trip nanoseconds with sub-second precision
- GPS ↔ Unix via UTC + leap seconds
- Verification that GPS−UTC = 18 in 2023
- Integration pattern with
std::time::SystemTime
-
Created a new
benchcrate and moved existing benchmark tests into it:arithmetic_bench.rsconvert_bench.rstime_bench.rs
-
Updated
Cargo.toml:-
Extended documentation for
postcarddependency:- Clarified
allocvs heapless usage modes
- Clarified
-
Improved comments around feature-gated serialization support
-
-
Improved architecture documentation consistency between:
ARCHITECTURE.md- crate-level docs
- feature flag definitions in
Cargo.toml
-
Clarified serialization strategy:
- Human-readable format is schema-based (not string-based)
- Compact format is strictly zero-overhead (no tags, no allocation)
-
Added constants to
prelude.rs:GPS_EPOCH_UNIX_SUTC_EPOCH_UNIX_OFFSET_NSUTC_EPOCH_UNIX_OFFSET_S
-
Updated
prelude.rswith re-exports:UTC_EPOCH_UNIX_OFFSET_SUTC_EPOCH_UNIX_OFFSET_NSGPS_EPOCH_UNIX_S(now available viause)
-
Improved code documentation in
duration.rs -
Updated
README.mdwith minimum required Rust version -
Added links to license files
-
Added constants to
prelude.rs
Time<Utc>::as_unix_nanos: previously au64→i64cast could wrap to negative values for timestamps exceedingi64::MAX. The method now usesi64::try_fromand saturates ati64::MAX, matching its documented behaviour.
- Removed the
benchesdirectory
- updated the examples in the README file, improved the code documentation
- updated the examples in the README file, improved the code documentation
- Updated README file
-
Deterministic property tests in
tests/prop_deterministic.rs:- fixed sample coverage for boundary values, all 18 leap-second transitions,
uniform
u64range coverage, and real IGS epochs - deterministic invariants for GPS→TAI→GPS, GPS→Galileo→GPS, GPS→BeiDou→GPS, GPS→UTC→GPS, arithmetic laws, monotonicity, ambiguity windows, and sub-second edge cases
- fixed sample coverage for boundary values, all 18 leap-second transitions,
uniform
-
Randomized property tests in
tests/prop_tests.rsusingproptest:- GPS domain sampling across the supported range
- bounded duration strategies to avoid arithmetic overflow in law checks
- leap-second boundary sampling within ±3 seconds
- dedicated ambiguity coverage to ensure
ConvertResult::Exactoutside leap windows
-
justfiletest recipes:test-deterministictest-propstest-all
-
Compile-time verification for leap second table (
BUILTIN_TABLE):_ASSERT_FIRST_ENTRY— validates initial offset (TAI−UTC = 19)_ASSERT_TABLE_INVARIANTS— enforces strict ordering and +1 increments_ASSERT_LAST_ENTRY— validates last entry (2017-01-01, TAI−UTC = 37)
-
LeapSeconds::last_update() -> Option<Time<Tai>>— returns last leap second event (TAI) -
LeapSeconds::current_tai_minus_utc() -> i32— accessor for current offset -
RuntimeLeapSeconds:- fixed-capacity, heap-free runtime leap second table (
RUNTIME_CAPACITY = 64) from_builtin()— initialize from compile-time snapshotfrom_slice()— construct from external datatry_extend()— validated append API
- fixed-capacity, heap-free runtime leap second table (
-
LeapExtendError(#[non_exhaustive]) with variants:NotStrictlyAscendingNonUnitIncrementBufferFull
-
Prelude exports:
RuntimeLeapSeconds,LeapExtendError,LeapEntry,RUNTIME_CAPACITY- helper functions
gps_to_utc,utc_to_gps
-
Test
test_builtin_table_matches_iers_bulletin_c:- full cross-verification against IERS data
-
Added
#[must_use]annotations across core types and APIs:Time<S>,Duration,GnssTimeError,ConvertResult<T>- all arithmetic helpers (
checked_*,saturating_*) - accessors (
as_nanos,as_seconds,week,tow_seconds, etc.) - conversion traits (
IntoScale,IntoScaleWith)
-
Added diagnostic messages to
#[must_use]where ignoring results is likely a bug -
Added
#[non_exhaustive]to:GnssTimeErrorConvertResult<T>ConversionKindScaleId(allows future extension without breaking changes)
-
Added helper methods in
scale.rs:OffsetToTai::is_fixed()- (complements existing
is_contextual())
-
Added extended trait coverage test:
test_scale_is_copynow validatesCopy + Clone + Eq + PartialEq + Debug
-
Added test
test_offset_to_tai_helperscoveringis_fixed()andis_contextual() -
Added
clippy.tomlas an explicit lint configuration entry point for future lint expansion
-
Split property-based testing into deterministic and
proptest-based suites to keepno_stdcompatibility clean while still providing host-side randomized coverage -
Updated
proptestdependency configuration inCargo.tomlto explicitly requirestd:default-features = falsefeatures = ["std"]
-
Added
test-allto the CI-orientedjustworkflow -
Leap second table (
BUILTIN_TABLE) fully verified against IERS Bulletin C (all 19 entries validated using threshold formula) -
Updated leap second documentation:
- added update policy and maintenance workflow
- documented compile-time invariants
- added runtime extension examples and validation rules
- included IERS monitoring references and current status (TAI−UTC = 37 as of 2026)
-
LeapSecondsAPI symmetry improved:from_sliceadded as alias tofrom_tablefor clarity
-
Enabled crate-wide lint:
#![warn(clippy::must_use_candidate)]
-
Improved API correctness by enforcing explicit result usage via
#[must_use] -
Strengthened forward-compatibility guarantees using
#[non_exhaustive] -
Updated internal documentation and diagnostics for better developer feedback
-
Prepared clippy configuration for future lint additions (
warn-on-all-wildcard-imports = falseas extension point)
- Fixed documentation typo in
GnssTimeError(i64→u64for internal representation)
- Full CI/CD pipeline:
ci.yml— formatting, clippy (all feature sets), tests, docs, MSRV, cargo-denyembedded.yml— cross-compilation for embedded targets (Cortex-M, RISC-V) withno_stdvalidation- reusable workflow integration (
workflow_call)
publish.yml— automated crates.io release pipeline:- waits for CI to succeed on tagged commit
- verifies tag ↔ Cargo.toml version consistency
cargo publish --dry-run(preflight validation)cargo publishwith protected environment- automatic GitHub Release generation
docs/ARCHITECTURE.md— internal design, module layout, TAI pivot, feature flagsdocs/EMBEDDED.md— embedded usage guide with UBX/GLONASS parsing examples, benchmark tabledocs/GNSS_TIME_PRIMER.md— GPS/GLONASS/UTC/TAI explained for developersdocs/INVARIANTS.md— type-level, arithmetic, conversion and memory invariantsdocs/LEAP_SECONDS.md— full leap second table reference with source citationsexamples/README.md— examples index with benchmark results- Property-based tests
tests/prop_tests.rs(9 tests):- Roundtrip GPS→UTC→GPS (256 sample points, all leap second boundaries, real IGS epochs)
- Roundtrip GPS→GAL→GPS, GPS→BDT→GPS, GPS→TAI→GPS
- Sort order
Vec<Time<Gps>>matches internalu64order - GPS→UTC monotonicity between leap second events
- GPS−UTC offset verification at known epochs
- All 18 historical leap second transitions (1981–2017)
- Strict GPS−UTC offset increase at each transition
Time::NANOS_PER_YEARconstant (365 × 24 × 3600 × 10⁹ ns)- Overflow boundary tests in
src/time.rs:checked_add/checked_subnearu64::MAXandEPOCH,saturating_add/saturating_sub_duration,try_add/try_sub_duration, panicking operators panic on overflow,checked_elapsedneari64boundary
API breaking change: replaced f64 fractional seconds with DurationParts
for all constructors:
-
Time<Gps>::from_week_tow(week, tow)now takesDurationParts -
Time<Glonass>::from_day_tod(day, tod)now takesDurationParts -
Added construction-time validation:
secondsandnanosare checked against valid ranges -
Eliminated non-determinism related to
f64 -
New type
DurationParts:- Fields
seconds: u64andnanos: u32 new()constructor with validationnanos < 1_000_000_000- Method
as_nanos() -> u128for conversion to nanoseconds
- Fields
-
Updated all examples (
examples/):basic_usage.rs,gps_week_tow.rs,glonass_day_tod.rsconvert_basic.rs,convert_contextual.rs,chain_conversion.rsdisplay_formats.rs,dynamic_conversion.rs,embedded_safe_arithmetic.rsglonass_receiver.rs,gps_time_operations.rs,log_stream.rsmatrix_inspection.rs,multi_constellation.rs,no_domain_mixing.rsno_std_example.rs,receiver_timestamp.rs,scale_conversion.rssync_alignment.rs
-
Updated integration tests (
tests/):glonass_test.rs— all constructors rewritten to useDurationPartsroundtrip_test.rs— all roundtrip tests updatedtime_integration_test.rs— adapted to the new API
-
Updated benchmarks (
benches/):arithmetic_bench.rs— unchanged (does not use constructors)convert_bench.rs— updatedfrom_week_towcalls to useDurationPartstime_bench.rs— constructors updated
-
Documentation:
- Full documentation added for
DurationParts - Updated examples in doc comments across all modules
- Full documentation added for
-
CI architecture:
- embedded checks extracted into reusable workflow (
embedded.yml) - improved caching strategy (feature-aware cache keys)
- stricter validation (
-D warnings, clippy across all feature combinations)
- embedded checks extracted into reusable workflow (
-
benches/arithmetic_bench.rs: addedchecked_add,checked_sub_duration,saturating_add,Durationbenchmarks; updated target figures -
benches/convert_bench.rs: addedleap_second_lookupmicrobenchmark
0.3.0 — 2026-04-27
-
Benchmarks (#TIME-12): added
benches/arithmetic_bench.rsandbenches/convert_bench.rs.- Demonstrate zero-cost abstractions:
Time<Gps> + Duration(512 ps) on par withu64 + u64(517 ps). - Conversions without leap seconds: ~0.8–0.9 ns.
GPS → UTCconversion with leap seconds: ~9.5 ns (under 10 ns).- Uses
criterionwith HTML reports.
- Demonstrate zero-cost abstractions:
-
time.rs: added
Time::MINconstant (alias ofEPOCH) for symmetry withMAX. -
time.rs: added documentation describing the value range of
Time<S>(~584 years from the epoch; for GPS up to year 2554). -
time.rs: added
test_time_max_behaviorto verify behavior nearu64::MAX. -
.github/workflows/embedded.yml: added
clippy::arithmetic_overflowcheck to the lint job. -
Added Issue template
enhancement.ymlfor proposing improvements to existing functionality.- Categories: performance, API, time scale conversions, leap seconds, embedded/no_std, formatting, refactoring, testing, documentation.
-
Added
CODEOWNERSfile for automatic ownership assignment across repository areas.- Defines responsibility for source (
/src/), tests (/tests/), benchmarks (/benches/), examples (/examples/), CI/CD (/.github/workflows/), documentation (/docs/), and root files. - Used by GitHub for automatic reviewer assignment on Pull Requests.
- Defines responsibility for source (
-
Added Pull Request template (
.github/pull_request_template.md).- Provides a structured checklist for reviewing changes: scope, description, and testing approach.
- Includes required checks:
cargo fmt,taplo format,cargo clippy,cargo test, documentation, and CHANGELOG updates.
-
CI: added GitHub Actions workflow to validate semantic Pull Request titles (
.github/workflows/semantic-pull-request.yml).- Automatically enforces PR title format:
type(scope?): description. - Supported types:
feat,fix,docs,chore,perf,refactor,test,ci,build,style. - Runs only on non-draft PRs (drafts are ignored).
- Leaves an automatic comment if the title is invalid.
- Automatically enforces PR title format:
-
.github/workflows
- added
embedded.ymlfor type size checks, builds forthumbv7em-none-eabihf,thumbv7em-none-eabi,riscv32imac-unknown-none-elf, host tests, and clippy.
- added
-
.cargo
- added
config.tomlfor cross-compilation:thumbv7em-none-eabihfthumbv7em-none-eabithumbv6m-none-eabiriscv32imac-unknown-none-elfriscv32i-unknown-none-elfopt-level = "s"— minimize binary size for flash-constrained devicescodegen-units = 1— improved optimization-C link-arg=-Tlink.xfor Cortex-M (requires linker script fromcortex-m-rt)-D warnings— treat warnings as errors in embedded CI
- added
-
tests
- added
no_std_compact.rstests verifying:- absence of
Drop Copysemanticsconst fnusability in static context- 8-byte alignment for DMA
- no allocations in conversion paths
core::fmtwithoutstd- enforcement of
#![forbid(unsafe_code)]
- absence of
- added
-
time.rs
- added
impl<S: TimeScale> defmt::Format for Time<S>under#[cfg(feature = "defmt")]
- added
-
error.rs
- added
impl defmt::Format for GnssTimeErrorunder#[cfg(feature = "defmt")]
- added
-
Cargo.toml: bumped to0.3.0; addeddefmt = ["dep:defmt"]usingdep:syntax (Cargo 1.60+); added[package.metadata.docs.rs]for docs.rs targets and features. -
justfile: added commands:setup-embedded,check-std,check-no-std,check-no-std-defmt,lint-no-std,msrv,hack,test-host,test-no-std,ci.
-
leap.rs:LeapSeconds::builtin()now returns&'static LeapSeconds(previouslyconst fn, which is incompatible withno_stdstatic data access). -
time.rs: removedconstfromas_seconds_f64(floating-point operations are notconston stable Rust 1.75).
0.2.0 — 2026-04-26
-
Full conversion matrix (
matrix):ScaleIdtype for runtime identification of time scales (GPS, GLONASS, Galileo, BeiDou, TAI, UTC).ConversionKindtype — classification of conversion types (Fixed, Identity, EpochShift, Contextual, SameScale).ConversionMatrixstructure — validation of compatibility and statistics over the conversion graph.- TAI offset constants:
TAI_OFFSET_GPS_NS,TAI_OFFSET_GALILEO_NS,TAI_OFFSET_BEIDOU_NS,TAI_OFFSET_TAI_NS,GLONASS_UTC_EPOCH_SHIFT_NS. beidou_via_gps_to_glonass_via_utcfunction — example of chained conversion across multiple scales.- Tests covering symmetry and classification of all 30 off-diagonal conversion paths.
-
Extended conversion capabilities in
leapandconvert:- Functions:
galileo_to_utc,galileo_to_glonass,beidou_to_utc,beidou_to_glonass, and reverse conversionsutc_to_galileo,utc_to_beidou. - Implementations of
IntoScaleandIntoScaleWithfor all scale pairs, including Galileo ↔ GLONASS, BeiDou ↔ GLONASS, Galileo ↔ UTC, BeiDou ↔ UTC. - Full support for a 6×6 conversion matrix (30 directional paths).
- Functions:
-
Fixed a typo in
matrix.rsdoctest (needs_leap_secondsmethod and corrected number of contextual paths: 16 instead of 22). -
New examples:
matrix_inspection.rs— prints the conversion matrix.dynamic_conversion.rs— runtime (dynamic) conversions.chain_conversion.rs— end-to-end BeiDou → TAI conversion chain.
-
GLONASS-specific methods (
Time<Glonass>):sub_second_nanos()— nanosecond fraction of the current second.day_of_week()— ISO weekday (1 = Monday … 7 = Sunday), based on the 1996-01-01 epoch (Monday).is_weekend()— returnstruefor Saturday or Sunday.
-
GLONASS integration tests (
tests/glonass_test.rs):- Verification of constant GLO ↔ UTC offset (no leap seconds).
- Roundtrip tests: GLO → UTC → GLO and GLO → GPS → GLO.
- Validation of
day_of_week()against known dates. - Behavior at the leap second boundary (2017-01-01).
-
Unified conversion API (
convert):IntoScale<Target>trait for fixed-offset conversions (GPS↔TAI, GPS↔Galileo, GPS↔BeiDou, GLO↔UTC).IntoScaleWith<Target>trait for contextual conversions (GPS↔UTC, GPS↔GLO) with explicitLeapSecondsProvider.ConvertResult<T>type for handling the ambiguous 1-second window during leap second insertion.into_scale_with_checkedmethod for detecting timestamps within a leap second.
-
preludemodule — convenient import of commonly used types:use gnss_time::prelude::*;
-
New examples (
examples/):convert_basic.rs— fixed-offset conversions (no leap seconds).convert_contextual.rs— GPS <-> UTC conversions with leap seconds and ambiguity detection.
-
Integration tests (
tests/):roundtrip_test.rs— roundtrip accuracy across all scales, covering 18 leap second transitions and known RINEX epochs.time_integration_test.rs— end-to-end usage scenarios.
utc_to_gps: replaced a single-pass approximation with a two-pass algorithm. RoundtripGPS → UTC → GPSis now exact (< 1 ns) across all 18 GPS-era leap second boundaries.
- Added documentation for the
convertmodule, including a table of supported conversions and usage examples. - Added
preludefor more convenient imports.
0.1.0 — 2026-04-21
-
Duration— signed nanosecond interval (i64):- Конструкторы:
from_nanos,from_micros,from_millis,from_seconds,from_minutes,from_hours,from_days. - Проверяемые варианты:
checked_from_micros,checked_from_millis,checked_from_seconds. - Методы:
as_nanos,as_micros,as_millis,as_seconds,as_seconds_f64. - Арифметика:
checked_add,checked_sub,saturating_add,saturating_sub,try_add,try_sub. - Свойства:
is_positive,is_negative,is_zero,abs. - Реализованы трейты:
Add,AddAssign,Sub,SubAssign,Neg,Display.
- Конструкторы:
-
Тип
Time<S>— параметризованная временная метка с наносекундной точностью (u64).- Общие методы:
from_nanos,from_seconds,checked_from_seconds,as_nanos,as_seconds,as_seconds_f64. - Арифметика с
Duration:checked_add,checked_sub_duration,saturating_add,saturating_sub_duration,try_add,try_sub_duration. - Разность
Time - TimeвозвращаетDuration. - Реализованы трейты:
Add<Duration>,Sub<Duration>,AddAssign,SubAssign,Sub<Time>,PartialOrd,Ord,Debug,Display.
- Общие методы:
-
Шкалы времени (
scale) — маркерные типы для GPS, GLONASS, Galileo, BeiDou, TAI, UTC.- Каждая шкала определяет: имя, смещение относительно TAI, календарную эпоху, стиль отображения.
OffsetToTai::Fixedдля шкал с постоянным смещением (GPS, Galileo, BeiDou, TAI).OffsetToTai::Contextualдля UTC и GLONASS (требуют leap seconds).
-
Эпохи и календарная арифметика (
epoch).- Тип
CivilDateдля пролептической григорианской даты. - Константы эпох:
GPS_EPOCH,GLONASS_EPOCH,GALILEO_EPOCH,BEIDOU_EPOCH,TAI_EPOCH,UNIX_EPOCH. - Константы смещений между эпохами (в днях, секундах, наносекундах).
const fnдля вычисления разницы между датами на этапе компиляции.
- Тип
-
Специфичные конструкторы для GPS и GLONASS.
Time<Gps>::from_week_tow(week, tow_s)и методыweek(),tow_seconds(),sub_second_nanos().Time<Glonass>::from_day_tod(day, tod_s)и методыday(),tod_seconds().
-
Leap seconds (
leap) — поддержка конверсий через таблицу високосных секунд.- Тип
LeapEntryс полямиtai_nanosиtai_minus_utc. - Тип
LeapSecondsсо статической встроенной таблицей (19 записей, от 1980 до 2017). - Трейт
LeapSecondsProviderдля кастомных источников (blanket impl для&P). - Функции конверсии:
gps_to_utc,utc_to_gps(требуютLeapSecondsProvider).glonass_to_utc,utc_to_glonass(константный сдвиг, без leap seconds).gps_to_glonass,glonass_to_gps(через UTC).
- Тесты для граничных переходов leap second (1998→1999, 2016→2017).
- Тип
-
Тип ошибок
GnssTimeErrorс вариантами:Overflow— арифметическое переполнение.InvalidInput— неверный аргумент (например, TOW вне диапазона).LeapSecondsRequired— требуется контекст leap seconds.
-
Форматирование
Displayв зависимости от шкалы:WeekTow(GPS, Galileo, BeiDou):"GPS 2345:432000.000".DayTod(GLONASS):"GLO 10512:43200.000".Simple(TAI, UTC):"TAI +1000000000s 0ns".
-
Examples:
basic_usage.rs— создание меток, арифметика, saturating операции.gps_week_tow.rs— работа с GPS неделями и TOW.glonass_day_tod.rs— работа с GLONASS днями и TOD.scale_conversion.rs— конвертация между шкалами через TAI.display_formats.rs— демонстрация разных форматов вывода.
-
Тесты — покрытие всех ключевых функций, включая проверки на переполнение, граничные случаи leap seconds, round-trip конверсии.
- Added
README.mdwith overview, scale table, and usage example. - Added detailed documentation comments in modules
duration,epoch,scale,time,leap. - Added
#.
- All types are 8 bytes (
Duration—i64,Time<S>—u64). Time<S>andDurationarerepr(transparent).- Conversions via TAI use integer arithmetic with no allocations.
- Leap second table lookup uses binary search over a
&'staticslice.