8 个版本
0.3.3 | 2024 年 6 月 13 日 |
---|---|
0.3.2 | 2024 年 6 月 4 日 |
0.3.1 | 2024 年 5 月 11 日 |
0.3.0 | 2024 年 4 月 7 日 |
0.1.0 | 2024 年 3 月 26 日 |
#52 在 日期和时间 类别中
每月 257 次下载
110KB
1K SLoC
tai-time
基于 TAI 时间标准的纳秒级精度单调时钟时间戳。
概述
虽然 Rust 的标准库已经提供了 std::time::Instant
单调时间戳,但其绝对值是透明的。在许多科学和工程应用中,如模拟、GNSS 和同步系统,需要基于绝对时间参考的单调时间戳。
这个包为这类应用提供了相当中立的、侧重于简单性、遵循 Rust 的 std::time
习惯用法以及与 std::time::Duration
类型的互操作性的时间戳。
TaiTime
时间戳指定一个 TAI 时间点。它表示为从 1970-01-01 00:00:00 TAI 或任意任意纪元开始的 64 位有符号秒数和正数纳秒。这种时间戳格式具有许多令人期望的属性
- 它在涉及标准
Duration
类型的算术运算中计算效率很高,该类型使用非常相似的内部分配表示法 - 当选择 1970 纪元时(参见
MonotonicTime
)- 将 Unix 时间戳精确转换为这种时间戳是微不足道的,只需从该时间戳减去 TAI 和 UTC 时间之间的闰秒数即可
- 它构成了 80 位 PTP IEEE-1588 时间戳的严格 96 位超集,PTP IEEE-1588 是一种广泛使用的高精度时间分配标准
- 它与 TAI64N 时间格式实质上相似(尽管不是严格相同)
- 使用自定义纪元,可以表示其他单调时钟,如全球定位系统时钟、伽利略系统时间时钟和北斗时间时钟(参见
GpsTime
、GstTime
、BdtTime
、Tai1958Time
和Tai1972Time
)。
MonotonicTime
是 TaiTime
的别名,其纪元设置为 1970-01-01 00:00:00 TAI,在没有规定特定纪元的情况下,是推荐的戳记选择。
在存在 std
的系统中,TaiClock
可以根据单调系统时钟生成 TAI 时间戳。在支持它的平台上(目前只有 Linux),可以使用 TaiTime::now
获取本地 TAI 系统时钟时间。
用法
将其添加到您的 Cargo.toml
[dependencies]
tai-time = "0.3.3"
示例
基本用法
use tai_time::{GpsTime, MonotonicClock, MonotonicTime};
// A timestamp dated 2009-02-13 23:31:30.987654321 TAI.
// (same value as Unix timestamp for 2009-02-13 23:31:30.987654321 UTC).
let t0 = MonotonicTime::new(1_234_567_890, 987_654_321).unwrap();
// Current TAI time based on the system clock, assuming 37 leap seconds.
let clock = MonotonicClock::init_from_utc(37);
let t1 = clock.now();
println!("Current TAI time: {}", t1);
// Elapsed time between `t0` and `t1`.
let dt = t1.duration_since(t0);
println!("t1 -t0: {}s, {}ns", dt.as_secs(), dt.subsec_nanos());
// Elapsed time since `t1`.
let dt = clock.now().duration_since(t1);
println!("Elapsed: {}s, {}ns", dt.as_secs(), dt.subsec_nanos());
// Print out `t1` as a GPS timestamp.
let gps_t1: GpsTime = t1.to_tai_time().unwrap();
println!("GPS timestamp: {}s, {}ns", gps_t1.as_secs(), gps_t1.subsec_nanos());
从日期时间字段和日期时间字符串构建
use tai_time::{MonotonicTime, Tai1958Time};
let t0 = MonotonicTime::try_from_date_time(2222, 11, 11, 12, 34, 56, 789000000).unwrap();
// The `FromStr` implementation accepts date-time stamps with the format:
// [±][Y]...[Y]YYYY-MM-DD hh:mm:ss[.d[d]...[d]]
// or:
// [±][Y]...[Y]YYYY-MM-DD'T'hh:mm:ss[.d[d]...[d]]
assert_eq!("2222-11-11 12:34:56.789".parse(), Ok(t0));
格式化显示为日期时间
use tai_time::MonotonicTime;
let t0 = MonotonicTime::try_from_date_time(1234, 12, 13, 14, 15, 16, 123456000).unwrap();
assert_eq!(
format!("{}", t0),
"1234-12-13 14:15:16.123456"
);
assert_eq!(
format!("{:.0}", t0),
"1234-12-13 14:15:16"
);
assert_eq!(
format!("{:.3}", t0),
"1234-12-13 14:15:16.123"
);
assert_eq!(
format!("{:.9}", t0),
"1234-12-13 14:15:16.123456000"
);
直接从系统时钟读取 TAI 时间(仅限 Linux,需要功能 tai_clock
)
use tai_time::MonotonicTime;
let now = MonotonicTime::now();
println!("Current TAI time: {}", now);
设计选择和限制
在从/到 UTC 基准时间戳的转换过程中,永远不会自动计算闰秒。这是故意的:由于闰秒无法预测得很远,任何试图“隐藏”它们的存在于用户代码中的尝试都会给人以错误的安全感,并且最终会使识别新闰秒引入后的故障变得更加困难。
功能标志
支持 no-std
默认情况下,此包启用 std
功能,以访问操作系统时钟并允许转换为/从 time::SystemTime
。可以通过指定 default-features = false
使其兼容 no-std
。
支持时间相关包
使用 chrono
功能,可以提供从/到 UTC 日期时间戳的转换方法。
TAI 系统时钟
仅在 Linux 上,可以通过激活 tai_clock
功能从系统时钟读取 TAI 时间。务必阅读有关 TaiTime::now
的可能注意事项。
序列化
TaiTime
和相关错误类型可以通过激活 serde
功能使用 serde
进行(反)序列化。
defmt
支持
激活 defmt
功能将在 TaiTime
和相关错误类型上派生 defmt::Format
特性。
许可证
此软件根据您的选择,许可为 Apache 许可证第 2 版 或 MIT 许可证。
贡献
除非您明确声明,否则根据 Apache-2.0 许可证定义的,您有意提交的任何贡献,都应如上所述双重许可,而不附加任何额外的条款或条件。
依赖关系
~0–0.9MB
~17K SLoC