15个版本 (稳定)
4.0.0 | 2024年1月31日 |
---|---|
3.0.2 | 2023年3月19日 |
3.0.1 | 2022年5月1日 |
3.0.0 | 2022年2月22日 |
0.1.0 | 2019年12月29日 |
#1 in #system-clock
每月下载量16,347
用于 4 crates
83KB
1.5K SLoC
rsntp
一个符合RFC 5905的Rust简单网络时间协议(SNTP)客户端库。
rsntp
提供了一个API,用于与SNTPv4时间服务器同步时间,具有以下特性
- 提供同步(阻塞)和异步(可选)API,基于
tokio
- 可选支持时间日期库
chrono
和time
(默认启用chrono
) - 支持IPv6
使用方法
将以下内容添加到您的Cargo.toml
[dependencies]
rsntp = "4.0.0"
使用阻塞API获取当前本地时间
use rsntp::SntpClient;
use chrono::{DateTime, Local};
let client = SntpClient::new();
let result = client.synchronize("pool.ntp.org").unwrap();
let local_time: DateTime<Local> =
DateTime::from(result.datetime().into_chrono_datetime().unwrap());
println!("Current time is: {}", local_time);
您还可以使用异步API执行相同操作
use rsntp::AsyncSntpClient;
use chrono::{DateTime, Local, Utc};
async fn local_time() -> DateTime<Local> {
let client = AsyncSntpClient::new();
let result = client.synchronize("pool.ntp.org").await.unwrap();
DateTime::from(result.datetime().into_chrono_datetime().unwrap())
}
3.0版本中的API更改
3.0版本使核心代码与时间日期库独立,并添加了对time
库的支持。这导致一些API的重大更改,SynchronizationResult
方法将使用包装结构而不是chrono
结构返回。这些包装结构具有TryInto
实现以及将它们转换为chrono
格式的辅助方法。
要将旧代码进行转换,替换
let datetime = result.datetime();
为
let datetime = result.datetime().into_chrono_datetime().unwrap();
或
let datetime: chrono::DateTime<Utc> = result.datetime().try_into().unwrap();
同样的方法也适用于由SynchronizationResult
返回的Duration
。
对时间日期库的支持
rsntp
支持以不同格式返回时间和日期数据。目前支持两种最流行的日期和时间处理库的格式:chrono
和time
。默认情况下,启用chrono
,但您可以通过功能添加对time
的支持
use rsntp::SntpClient;
let client = SntpClient::new();
let result = client.synchronize("pool.ntp.org").unwrap();
let utc_time = result
.datetime()
.into_offset_date_time()
.unwrap();
println!("UTC time is: {}", utc_time);
可以独立启用两个库的支持;您甚至可以同时启用两个库。
禁用异步API
默认情况下启用异步API,但您可以禁用它。禁用的优点是它消除了对tokio
的依赖,这大大减少了依赖项的数量。
[dependencies]
rsntp = { version = "4.0.0", default-features = false, features = ["chrono"] }
系统时钟假设
rsntp
假设系统时钟是单调且稳定的。这对于 SynchronizationResult::datetime()
方法尤为重要,因为 SynchronizationResult
只存储系统时钟的偏移量。如果系统时钟在同步和调用此方法之间发生变化,则偏移量将不再有效,并返回一些未定义的结果。
支持IPv6
rsntp
支持IPv6,但由于兼容性原因,它默认将其UDP套接字绑定到IPv4地址(0.0.0.0)。这可能会阻止与IPv6服务器的同步。
要使用IPv6,您需要设置IPv6绑定地址
use rsntp::{Config, SntpClient};
use std::net::Ipv6Addr;
let config = Config::default().bind_address((Ipv6Addr::UNSPECIFIED, 0).into());
let client = SntpClient::with_config(config);
let result = client.synchronize("2.pool.ntp.org").unwrap();
let unix_timestamp_utc = result.datetime().unix_timestamp();
依赖关系
~1–9.5MB
~76K SLoC