【跟小嘉学 Rust 编程】二十八、Rust中的日期与时间(DateTime)

2023-09-18 01:21:36

系列文章目录

【跟小嘉学 Rust 编程】一、Rust 编程基础
【跟小嘉学 Rust 编程】二、Rust 包管理工具使用
【跟小嘉学 Rust 编程】三、Rust 的基本程序概念
【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念
【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据
【跟小嘉学 Rust 编程】六、枚举和模式匹配
【跟小嘉学 Rust 编程】七、使用包(Packages)、单元包(Crates)和模块(Module)来管理项目
【跟小嘉学 Rust 编程】八、常见的集合
【跟小嘉学 Rust 编程】九、错误处理(Error Handling)
【跟小嘉学 Rust 编程】十一、编写自动化测试
【跟小嘉学 Rust 编程】十二、构建一个命令行程序
【跟小嘉学 Rust 编程】十三、函数式语言特性:迭代器和闭包
【跟小嘉学 Rust 编程】十四、关于 Cargo 和 Crates.io
【跟小嘉学 Rust 编程】十五、智能指针(Smart Point)
【跟小嘉学 Rust 编程】十六、无畏并发(Fearless Concurrency)
【跟小嘉学 Rust 编程】十七、面向对象语言特性
【跟小嘉学 Rust 编程】十八、模式匹配(Patterns and Matching)
【跟小嘉学 Rust 编程】十九、高级特性
【跟小嘉学 Rust 编程】二十、进阶扩展
【跟小嘉学 Rust 编程】二十一、网络编程
【跟小嘉学 Rust 编程】二十三、Cargo 使用指南
【跟小嘉学 Rust 编程】二十四、内联汇编(inline assembly)
【跟小嘉学 Rust 编程】二十五、Rust命令行参数解析库(clap)
【跟小嘉学 Rust 编程】二十六、Rust的序列化解决方案(Serde)
【跟小嘉学 Rust 编程】二十七、Rust 异步编程(Asynchronous Programming)
【跟小嘉学 Rust 编程】二十八、Rust中的日期与时间

前言

本章节讲解 Rust 的异步编程方案,我们将讲解 Future、Waker、Executor、Pin、async 和 await、Stream等

主要教材参考 《The Rust Programming Language》
主要教材参考 《Rust For Rustaceans》
主要教材参考 《The Rustonomicon》
主要教材参考 《Rust 高级编程》
主要教材参考 《Cargo 指南》
主要教材参考 《Rust 异步编程》


一、Rust 标准库中的日期与时间

Rust 标准库中提供了默认的时间类型:std:time:SystemTime 和 std:time:Duration

1.1、时间类型(std:time:SystemTime)

1.1.1、创建 std:time:SystemTime

在 Rust 中 std:time:SystemTime 是默认的时间类型,它表示从 Unix 纪元(1970年1月1日)起的时间点。std:time:SystemTime 可以用来表示过去或者未来的时间,以及时间间隔。

use std::time::SystemTime;

fn main(){
    let now = SystemTime::now();
    println!("当前时间:{:?}", now);
}

输出结果

当前时间:SystemTime { tv_sec: 1694959432, tv_nsec: 564005000 }

1.1.2、比较 SystemTime 实例

可以使用比较运算符(例如:<、>、<=、>=) 来比较 SystemTime 的大小。

use std::time::{SystemTime, Duration};

fn main(){
    let now = SystemTime::now();
    let future = now + Duration::from_secs(60);
    println!("当前时间:{:?}", now> future);
}

1.1.3、elapsed 方法

返回系统时间与当前时间的差值。这个函数如果返回OK,那么就是返回从此时间到当前时间所经过的时间量。如果要可靠测量经过的时间,使用 Instant 代替。

use std::time::SystemTime;
use std::time::Duration;
use std::thread;

fn main(){
    let now = SystemTime::now();
    thread::sleep(Duration::from_secs(1));

    match now.elapsed() {
        Ok(elapsed) =>{
            println!("{}",elapsed.as_secs());
        }
        Err(e) => {
            println!("Error: {e:?}");
        }
    }
}

1.2、时间间隔类型(std:time:Duration)

在 Rust 中 Duration 表示时间间隔。

use std::time::Duration;
let five_seconds = Duration::new(5, 0);

new 方法的参数,第一个参数是秒数,第二个参数是纳秒数。

1.3、即时类型(std::time::Instant)

use std::time::Instant;

fn main(){
    let now = Instant::now();
    println!("Instant: {:?}", now);
}

返回查看函数运行时间

use std::time::Instant;

fn run_time() {
    let now = Instant::now();
    // 执行函数
    run();
    println!("执行时间: {}", now.elapsed().as_millis());
}

fn run() {} 

二、time 库

2.1、time 库介绍

time 是一个 Rust的日期时间库,他有如下的特点

  • 方便且安全,time 有一个简单的API;
  • 空间优化效率高,支持 ±999,999 年的范围内的日期,精度为纳秒;
  • 序列化准备,支持ISO8601, RFC2822 and RFC3339 特性
  • const 准备的 API
  • 支持 no-std 属性

2.2、添加依赖

cargo add time

2.3、使用方法

2.3.1、获取当前时间的UTC偏移量

获取当前时间的UTC偏移量;

use time::OffsetDateTime;

fn main(){
    let now = OffsetDateTime::now_utc();
    print!("{now}");
}

输出结果

2023-09-17 15:10:26.798899 +00:00:00%

2.3.2、创建日期和时间

2.3.2.1、使用方法来创建日期和时间对象
use time::{Date, UtcOffset};

fn main(){
    let date = Date::from_iso_week_date(2023, 1, time::Weekday::Friday).unwrap();
    let datetime = date.with_hms(5, 20, 0).unwrap();
    let datetime_off = datetime.assume_offset(UtcOffset::from_hms(1, 2, 3).unwrap());

    println!("{date}, {datetime}, {datetime_off}");
}

输出结果

2023-01-06, 2023-01-06 5:20:00.0, 2023-01-06 5:20:00.0 +01:02:03
2.3.2.2、使用宏来创建
use time::macros::{date,datetime};

fn main(){
    let date = date!(2023-05-20);
    let datetime = datetime!(2023-05-20 13:14:52);
    let datetime_off =  datetime!(2023-05-20 13:14:52 +1:02:03);
    println!("{date}, {datetime}, {datetime_off}");
    // 2023-05-20, 2023-05-20 13:14:52.0, 2023-05-20 13:14:52.0 +01:02:03
}

2.3.3、计算时间间隔

use time::Duration;
use time::macros::datetime;

fn main(){
    let a = datetime!(2022-01-01 10:00:55);
    let b = datetime!(2022-01-01 13:00:00);
    
    let duration: Duration = b - a;
    
    println!("{}", duration);     // 2h59m5s
}

2.3.4、字符串与日期时间转换

要使用该功能需要开启 parsing 特征

time = { version = "0.3.28", features = ["macros","parsing"] }
2.3.4.1、字符串转换为日期时间对象
use time::format_description::well_known::Iso8601;
use time::PrimitiveDateTime;

fn main(){
    let date = PrimitiveDateTime::parse("2022-01-02T11:12:13", &Iso8601::DEFAULT).unwrap();
    
    println!("{}", date);     // 2022-01-02 11:12:13.0
}
2.3.4.2、自定义格式字符串转换为时间对象
use time::macros::format_description;
use time::Time;


fn main(){
    let my_format = format_description!("h=[hour],m=[minute],s=[second]");
    let time = Time::parse("h=11,m=12,s=13", &my_format).unwrap();
    println!("{}", time);     // 11:12:13.0
}

2.3.2、支持序列化

需要开启 serde-well-known 特性。

use time::macros::format_description;
use time::{OffsetDateTime, Time};
use serde::{Deserialize};

#[derive(Deserialize)]
struct Notification {
    message: String,
    #[serde(with = "time::serde::iso8601")]
    timestamp: OffsetDateTime,
}

fn main() {
    let input = r#"{
      "message": "foo",
      "timestamp": "2022-01-02T11:12:13Z"
    }"#;

    let notification: Notification = serde_json::from_str(input).unwrap();
    println!("{:?}", notification.timestamp);
}

三、chrono 库

3.1、chrono库介绍

chrono 支持各种运行时环境和操作系统,支持的特征如下两大类

  • 默认特征:
    • alloc:企业用依赖于分配的特性,主要是字符串格式化
    • std:启用依赖于标准库的功能,这是alloc 的超集,增加了与标准库类型和特征的互操作;
    • clock:启用读取系统时间,此类api取决于 unix 操作系统的标准库 和 Windows API
    • wasmbind: 与 wasm32 目标的JS Date API 接口
  • 可选特征
    • serde、rkyv 序列化
    • arbitrary:使用任意 crate 类型构造类型的任意实例
    • unstable-locales:支持本地化,这个将带有_localization 后缀的各种方法,实现和API可能会更改,甚至删除。
    • oldtime:这个特性不再与功能,但是曾经提供了 time 0.1 的兼容性;

添加依赖

cargo add chrono

3.2、chrono 常用操作

3.2.1、DateTime

3.2.1.1、获取当前时间
use chrono::{Local, DateTime};

fn main(){
	// 获取当前时间
    let datetime: DateTime<Local> = Local::now();
    println!("datetime = {:#?}", datetime);
	
	// 获取日期
	println!("datetime.date_naive()= {:#?} ",datetime.date_naive());

	// 获取时间戳
	println!("datetime.timestamp()= {:#?} ",datetime.timestamp());
}
3.2.1.2、i64时间戳转换日期时间
use chrono::{Utc, TimeZone};

fn main(){
	// 时间戳转换
	let timestamp:i64 = 1694966356;
	let new_utc_dt = Utc.timestamp_opt(timestamp + 30, 0).unwrap();
	println!("new_utc_dt = {:#?}", new_utc_dt);
}
3.2.1.3、日期时间格式化

1、时间转换为字符串

use chrono::{Local, DateTime};

fn main(){
	let local:DateTime<Local>  = Local::now();
	let format = local.format("%Y-%m-%d %H:%M:%S");
	println!("{:#?}", format!("{}", format));
}

2、字符串转换为日期时间

use chrono::{DateTime, FixedOffset, ParseResult, NaiveDateTime};

fn main(){
	let t = NaiveDateTime::parse_from_str("2022-02-10 00:00:00", "%Y-%m-%d %H:%M:%S").unwrap();
	println!("{:?}", t);
    println!("{:?}", t.date());
	println!("{:?}",t.to_string());
	
	let t1: ParseResult<DateTime<FixedOffset>> =
	DateTime::parse_from_str("2020-03-28 21:00:09 +09:00", "%Y-%m-%d %H:%M:%S %z");
	println!("{:?}", t1.unwrap().date_naive());
}

3.2.2、时区相关

use chrono::FixedOffset;

fn main(){
	let timezone_offset =FixedOffset::east_opt(8*3600).unwrap();
	println!("timezone_offset = {:#?}", timezone_offset);
}

3.2.3、Duration

Duration代表来一个时间段,例如2分钟,4小时等;

use chrono::Duration;

fn main(){
	let duration = Duration::days(1);
	println!("{:#?}",duration.num_seconds());
}

四、coarsetime库

4.1、coarsetime介绍

提供有高性能的 Duration、Instant 实现

添加依赖

cargo add coarsetime

4.2、Duration

use coarsetime::{Instant, Duration};

fn main(){
	let d = Duration::from_days(1);
	println!("{:#?}", d);
}

4.3、Instant

use coarsetime::Instant;

fn main(){
	let now = Instant::now();
	let ts1 = Instant::recent();

	println!("now :  {:#?}", now);
	println!("ts1 :  {:#?}", ts1);

	Instant::update();
	let ts2= Instant::recent();
	println!("now :  {:#?}", now);
	println!("ts1 :  {:#?}", ts1);
	println!("ts2 :  {:#?}", ts2);
	
}

总结

本章节讲解标准库、time库、chrono库、coarsetime库的介绍。

更多推荐

算法基础:图

图论图论〔GraphTheory〕是数学的一个分支。它以图为研究对象。图论中的图是由若干给定的点及连接两点的线所构成的图形,这种图形通常用来描述某些事物之间的某种特定关系,用点代表事物,用连接两点的线表示相应两个事物间具有这种关系。如下就是一种逻辑上的图结构:图是一种最复杂的数据结构,前面讲的数据结构都可以看成是图的特

oracle 12c相对oralce 11g的新特性(3)|oracle 12c的自动化管理特性:自动备份、自动恢复、自动维护的功能使用

一、前言:前面几期讲解了oracle12c多租户的使用、In-Memory列存储来提高查询性能以及数据库的克隆、全局数据字典和共享数据库资源的使用今天我们讲讲oracle12c的另外的一个自动化管理功能新特性:自动备份、自动恢复、自动维护的功能二、自动备份、自动恢复、自动维护概要通过使用这些自动化功能,Oracle12

使用 FHE 实现加密大语言模型

近来,大语言模型(LLM)已被证明是提高编程、内容生成、文本分析、网络搜索及远程学习等诸多领域生产力的可靠工具。大语言模型对用户隐私的影响尽管LLM很有吸引力,但如何保护好输入给这些模型的用户查询中的隐私这一问题仍然存在。一方面,我们想充分利用LLM的力量,但另一方面,存在向LLM服务提供商泄露敏感信息的风险。在某些领

PCIE研究-1

PCI-Express(peripheralcomponentinterconnectexpress)是一种高速串行计算机扩展总线标准,PCIe属于高速串行点对点双通道高带宽传输,所连接的设备分配独享通道带宽,不共享总线带宽,主要支持主动电源管理,错误报告,端对端的可靠性传输,热插拔以及服务质量(QOS)等功能。PCI

【大数据实训】基于Hadoop的2019年11月至2020年2月宁波天气数据分析(五)

博主介绍:✌全网粉丝6W+,csdn特邀作者、博客专家、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于大数据技术领域和毕业项目实战✌🍅文末获取项目联系🍅基于Hadoop的2019年11月至2020年2月宁波天气数据分析2019—2020学年第二学期《分布式系统原理与技术》期

如何使用Java爬取指定链接的网页内容

在当今信息时代,互联网上的数据量庞大且不断增长。为了获取特定网页的内容,爬虫技术成为了一种非常有用的工具。本文将介绍如何使用Java编程语言来实现爬取指定链接的网页内容。首先,我们需要准备好Java开发环境。确保你已经安装了JavaDevelopmentKit(JDK)并配置好了环境变量。接下来,我们将使用Java提供

面向Java开发者的ChatGPT提示词工程(7)

在如今信息爆炸的时代,我们面临着海量的文字信息,很难抽出足够的时间去阅读所有感兴趣的内容。然而,大语言模型为我们提供了一种有效的解决方案:通过自动文本摘要,帮助我们快速获取文章的核心内容。这种技术已经被广泛应用于各种软件应用程序中。以ChatGPT为例,它提供了一个简洁的网页界面,让用户能够轻松地对文章进行摘要。这种方

关于C#.Net网页跳转的7种方法

一、目前在ASP.NET中页面传值共有这么几种方式:1.Response.Redirect("http://www.hao123.com",false);目标页面和原页面可以在2个服务器上,可输入网址或相对路径。后面的bool值为是否停止执行当前页。跳转向新的页面,原窗口被代替。浏览器中的URL为新路径。Respons

运算符——“MySQL数据库”

各位CSDN的uu们好呀,今天,小雅兰的内容是MySQL数据库里面的操作符,下面,让我们进入操作符的世界吧!!!算术运算符比较运算符逻辑运算符位运算符运算符的优先级拓展:使用正则表达式查询算术运算符算术运算符主要用于数学运算,其可以连接运算符前后的两个数值或表达式,对数值或表达式进行加(+)、减(-)、乘(*)、除(/

您的开发团队是否面临效率陷阱?

“努力还是摸鱼?”这是一个职场老笑话了,当被问到这句话,人们往往回以礼貌一笑或单纯点头、做个鬼脸。这个笑话无伤大雅,但它总让人想起一个根深蒂固的观念:在工作时,我们必须时刻保持高效。在谷歌搜索“工作效率”,会弹出数百万结果,无论是关于自我提升的书籍,还是TED演讲,又或是提高工作效率的应用程序,比如“如何在工作中提高工

(10)(10.9) 术语表(三)

文章目录1Oilpan2OSD3PCB4PCM5PDB6PIC7PID8POI9PPM10PWM11PX4FMU/PX4IO12RTL13SiRFIII14Sketch15SVN16TelemetrySystem17Thermopile18UAV19VLOS20WAAS21Xbee22ZigBee1OilpanOilp

热文推荐