deep-time
A fully featured and high performance Rust date and time library with attosecond precision that provides astronomical and civil timekeeping.
Overview
- Auto-parsers for datetimes and durations that handle thousands of formats, relative dates and multiple languages, requires the
parsefeature - No std, no alloc, and wide-spread const fn
- Extensively validated against outputs from Astropy, Jiff, and other libraries and sources
- Fast ISO parser
- Time scales e.g. UTC with leap seconds support, including historical, TT, TAI, TDB, NAIF ET, LTC, GPS, etc. An optional feature
tdb_fairhead1990can be enabled which provides the ERFA TDB model - Strptime
- Strftime (multi-language day and month names available)
- First class timezone support provided by the Rust library jiff enabled with the
jiff-tzfeature - To and from all kinds of inputs and outputs, functions mostly prefixed with
toandfrom, available on the library's types, see the main time types functions: Dt. Including JD, MJD, Unix, NTP, etc. - Calendar aware and, with the
jiff-tzfeature, timezone aware math - To and from jiff, chrono, and hifitime types
- No-alloc string return type
- Const fn libm math functions
- Safe, saturating arithmetic throughout
- No
unsafein the library -#![forbid(unsafe_code)] - Lunar and Mars modules
- Sidereal time with a const fn implementation of ERFA Equation of the Origins / Equinoxes
- UT1 and EOP
- Light-time (Shapiro delay, etc.), requires the
physicsfeature - Proper time along trajectories, requires the
physicsfeature - Relativity: Drift, Spacetime, Position, and Velocity — see docs/relativity.md for the underlying model. Requires the
physicsfeature. - CCSDS CUC, CDS, and CCS
- Binary size is mainly controlled through feature gating
Examples
use ;
Documentation
Installation
- This crate has no default features.
- The minimum Rust version is
1.90and minimum Rust edition is2024. This is mainly due to someconstfunctionality that only became stable recently. - Enable
parsefor the auto-parsers andjiff-tzfor timezone support and DST-aware calendar math.
For example, add this to your Cargo.toml in the dependencies section:
[]
= { = "0.1", = ["parse", "jiff-tz"] }
Feature Flags
| Feature | Description | Requires |
|---|---|---|
parse |
Enables the auto-parsers (from_str_parse, from_str_duration, etc.) |
alloc |
jiff-tz |
Enables timezone-aware calendar math (add_days_tz, add_hr_tz, etc.) and to_str_in_tz |
std |
jiff-tz-bundle |
Same as jiff-tz but bundles the full timezone database |
std |
jiff |
Enables basic Jiff interop | alloc |
chrono |
Enables Chrono interop | alloc |
hifitime |
Enables Hifitime interop | — |
serde |
Enables Serialize / Deserialize for Dt and other types |
alloc |
js |
WebAssembly support (includes serde and JS bindings) |
std |
tsify |
TypeScript definitions via tsify (for WASM) |
js |
std |
Enables std functionality including Dt::now() and file handling |
— |
alloc |
Enables allocation (required for parsing and some conversions) | — |
es / de / fr |
Language support, parsing different languages requires alloc, formatting does not | — |
euro |
Enables all European languages | |
lang |
Enables all languages | euro |
panic-handler |
Provides an optional simple #[panic_handler] for no_std environments |
no_std |
defmt |
Enables defmt::Format trait implementations the main types. Intended for use with the defmt logging framework on embedded systems. |
— |
wire |
Enables wire format (serialization) support | — |
tdb_fairhead1990 |
Replaces the fast TDB and TCB conversions with the full ERFA TDB model | — |
physics |
Enables relativistic physics support (Drift, Spacetime, Position, Velocity, Observer, light-time, etc.) |
— |
mars |
Enables Mars time support (to_msd, to_mars_ls, etc.) |
— |
sidereal |
Enables sidereal time support | — |
eop |
Enables Earth Orientation Parameters (UT1, etc.) | alloc |
locale |
Enables system locale detection | std |
Optional No-Alloc Panic Handler
deep-time supports no_std + no_alloc environments. When targeting bare-metal or embedded systems, you can enable a minimal panic handler:
[]
= { = "0.1", = ["panic-handler"] }
This provides a simple #[panic_handler] that uses core::hint::spin_loop() (more power-efficient than a plain loop {}).
You only need this if you are building a binary crate in a no_std environment without your own panic handler.
Notes
- The fast ISO 8601 parser (
from_str_iso) works without theparsefeature. - Multi-language parsing requires the
parsefeature, but multi-language formatting works without it. - The
.parse()implementation onDtautomatically chooses between the full parser and the ISO parser depending on enabled features.
Performance
Benchmarks were measured on an AMD Ryzen 7 7800X3D.
Parsing and Formatting
| Operation | Time | vs Jiff 0.2.31 |
|---|---|---|
| ISO datetime parsing | 19.7 ns | 28.3% faster |
strptime |
34.6 ns | 13.2% faster |
TZ strptime -> Dt vs jiff:Zoned |
185 ns | 16.2% slower |
strftime |
98.3 ns | 58.8% slower |
Auto parser (from_str_parse) |
575 ns | — |
Time Scale Conversions
| Conversion | deep-time | hifitime 4.3 | Relative Performance |
|---|---|---|---|
| TAI → UTC | 9.6 ns | 33.8 ns | 3.5× faster |
| UTC → TAI | 12.7 ns | 32.9 ns | 2.6× faster |
| TAI → TDB | 134 ns | 90.7 ns | 1.5× slower |
| TDB → TAI | 598 ns | 26.8 ns | 22.3× slower |
| GPS conversion | 20.7 ns | 6.4 ns | 3.2× slower |
| GPS week + TOW | 28.2 ns | 7.0 ns | 4.0× slower |
The tests were run with:
Bundled Files
This library bundles some data relevant to, for example, time scale conversions. While every effort will be made to keep the library up to date, perhaps some users will want to know how to re-generate or update certain files and then re-compile.
Leap Seconds
The latest leap seconds table is bundled as a .rs file. A runtime file can be parsed and loaded for time scale conversions, e.g.
If for whatever reason you need to update the library's bundled leap seconds file and re-compile, follow these steps:
- Download the desired leap seconds file, for example from https://data.iana.org/time-zones/data/leap-seconds.list
- Place the downloaded file in the library, with the following location and filename:
deep-time/tests/assets/leap-seconds.list.txt - Then with a terminal open in the library run the command:
cargo gen-leap-seconds - This should overwrite the file
src/utc/leap_seconds_list.rsusing the data - Re-compile the library