imte(intelligent)
一个用来处理日期时刻库。
docs.rs地址: docs.rs/chrono/0.4.19/chrono/index.html
一、运用办法Cargo.toml[dependencies]chrono = "0.4"main.rsuse chrono::{DateTime, Datelike, Local, TimeZone, Timelike, Utc};// 或许use chrono::prelude::*;二、根底结构2.1 DateTime<Tz: TimeZone>日期时刻结构体#[derive(Clone)]pub struct DateTime<Tz: TimeZone> { datetime: NaiveDateTime, offset: Tz::Offset,}2.2 Date<Tz: TimeZone>日期结构体#[derive(Clone)]pub struct Date<Tz: TimeZone> { date: NaiveDate, offset: Tz::Offset,}2.3 Duration差值结构体,用来核算两个日期之差。/// ISO 8601 time duration with nanosecond precision./// This also allows for the negative duration; see inpidual methods for details.#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]pub struct Duration { secs: i64, nanos: i32, // Always 0 <= nanos < NANOS_PER_SEC}2.4 TimeZone时区traitpub trait TimeZone: Sized + Clone { /// An associated offset type. /// This type is used to store the actual offset in date and time types. /// The original `TimeZone` value can be recovered via `TimeZone::from_offset`. type Offset: Offset; fn ymd(&self, year: i32, month: u32, day: u32) -> Date<Self> { self.ymd_opt(year, month, day).unwrap() }... //其他办法体}2.5 Offset时区差值trait/// The offset from the local time to UTC.pub trait Offset: Sized + Clone + fmt::Debug { /// Returns the fixed offset from UTC to the local time stored. fn fix(&self) -> FixedOffset;}三、根底用法3.1 获取当时时刻// 获取utc时刻let utc_datetime = Utc::now();println!("utc_datetime: {}", utc_datetime); // utc_datetime: 2021-11-01 10:05:22.349150 UTC// 获取local时刻let local_datetime = Local::now();println!("local_datetime: {}", local_datetime); // local_datetime: 2021-11-01 18:05:22.349230 +08:003.2 时刻日期特点// 获取日期的特点println!("local_datetime 年: {}", local_datetime.year());// local_datetime 年: 2021println!( "local_datetime 月: 12月制:{}, 11个月制:{}", local_datetime.month(), local_datetime.month0());// local_datetime 月: 12月制:11, 11个月制:10println!("local_datetime 日: {}", local_datetime.day());// local_datetime day: 1println!( "local_datetime 小时: 24小时制:{}, 12小时制: {:?}", local_datetime.hour(), local_datetime.hour12());// local_datetime 小时: 24小时制:19, 12小时制: (true, 7)println!("local_datetime 分钟: {}", local_datetime.minute());// local_datetime local_datetime 分钟: 36println!("local_datetime 秒: {}", local_datetime.second());// local_datetime 秒: 31println!("local_datetime 周几: {}", local_datetime.weekday());// local_datetime 周几: Monprintln!( "local_datetime 周几(数字): {}", local_datetime.weekday().number_from_monday());// local_datetime 周几(数字): 1println!("local_dateimte 一年的第几天: {}", local_datetime.ordinal());// local_dateimte 一年的第几天: 3053.3 获取时刻戳Utc和Local转化后的时刻戳是共同的println!("utc timestamp: {}", utc_datetime.timestamp()); // utc timestamp: 1635761246println!("local timestamp: {}", local_datetime.timestamp()); // local timestamp: 16357612463.4 日期时刻转字符串// 把日期时刻直接转化成字符串let local_str = local_datetime.to_string();println!("lcoal_str: {}", local_str); //lcoal_str: 2021-11-01 19:24:38.939970 +08:00// 格局化字符串let local_str1 = local_datetime.format("%Y-%m-%dT%H:%M:%S").to_string();println!("local_str1: {}", local_str1); //local_str1: 2021-11-01T19:24:38// 只展现日期let local_str2 = local_datetime.format("%Y-%m-%d").to_string();println!("local_str2: {}", local_str2); //local_str2: 2021-11-01// 只展现时刻let local_str3 = local_datetime.format("%H:%M:%S").to_string();println!("local_str3: {}", local_str3); //local_str3: 19:24:383.5. 获取日期// 获取日期格局let local_date = local_datetime.date();println!("local_date: {}", local_date); //local_date: 2021-11-01+08:00assert_eq!(Utc::today(), Utc::now().date());assert_eq!(Local::today(), Local::now().date());3.6 创立日期// 手动创立日期时刻let local_handle_datetime1 = Local.ymd(2021, 10, 15).and_hms(10, 12, 30);println!("local_handle_datetime1: {}", local_handle_datetime1); //local_handle_datetime1: 2021-10-15 10:12:30 +08:00// 手动创立带有毫秒级的时刻let local_handle_datetime2 = Local.ymd(2021, 10, 27).and_hms_milli(18, 18, 18, 889);println!("local_handle_datetime2: {}", local_handle_datetime2); // local_handle_datetime2: 2021-10-20 18:18:18.889 +08:003.7 日期时刻差// 两个日期时刻的差值let sub_datetime = local_handle_datetime2 - local_handle_datetime1;println!( "相差:{}天, {}小时, {}分钟, {}秒, {}周. 格局化:{}", sub_datetime.num_days(), sub_datetime.num_hours(), sub_datetime.num_minutes(), sub_datetime.num_seconds(), sub_datetime.num_weeks(), sub_datetime.to_string());// 相差:12天, 296小时, 17765分钟, 1065948秒, 1周. 格局化:P12DT29148.889S3.8 获取几天或几周后的日期// 获取前3天的日期let three_days_before = local_datetime - chrono::Duration::days(3);println!("three_days_before: {}", three_days_before); //three_days_before: 2021-10-29 19:55:41.982785 +08:00// 获取下周的今日let next_week_day = local_datetime + chrono::Duration::weeks(1);println!("next_week_day: {}", next_week_day); // next_week_day: 2021-11-08 19:55:41.982785 +08:003.9 时刻字符串转日期时刻类型let dt = Utc.ymd(2014, 11, 28).and_hms(12, 0, 9);let fixed_dt = dt.with_timezone(&FixedOffset::east(8 * 3600)); // 设置时区// 用parse来转化assert_eq!( "2014-11-28T12:00:09Z".parse::<DateTime<Utc>>(), Ok(dt.clone()));assert_eq!( "2014-11-28T20:00:09+08:00".parse::<DateTime<Utc>>(), Ok(dt.clone()));assert_eq!( "2014-11-28T20:00:09+08:00".parse::<DateTime<FixedOffset>>(), Ok(fixed_dt.clone()));// 用DateTime结构来转化assert_eq!( DateTime::parse_from_str("2014-11-28 21:00:09 +09:00", "%Y-%m-%d %H:%M:%S %z"), Ok(fixed_dt.clone()));assert_eq!( DateTime::parse_from_rfc2822("Fri, 28 Nov 2014 21:00:09 +0900"), Ok(fixed_dt.clone()));assert_eq!( DateTime::parse_from_rfc3339("2014-11-28T21:00:09+09:00"), Ok(fixed_dt.clone()));// 经过Utc的datetime_from_str转化assert_eq!( Utc.datetime_from_str("2014-11-28 12:00:09", "%Y-%m-%d %H:%M:%S"), Ok(dt.clone()));assert_eq!( Utc.datetime_from_str("Fri Nov 28 12:00:09 2014", "%a %b %e %T %Y"), Ok(dt.clone()));3.10 时刻戳转日期时刻类型let dt = Utc.timestamp(1_500_000_000, 0);assert_eq!(dt.to_rfc2822(), "Fri, 14 Jul 2017 02:40:00 +0000");3.11 Utc转Locallet utc_now = Utc::now();let local_now = utc_now .with_timezone(&chrono::FixedOffset::east(8 * 3600)) .format("%Y-%m-%d %H:%M:%S") .to_string();println!("local_now {}", local_now);四、序列化许多时分需求读写数据库,从数据库内读出的时刻是Utc的,可是页面展现需求是Local,所以能够合作serde库来进行序列及反序列化。详细用法如下:
先声明序列及反序列办法pub mod date_format { use chrono::{DateTime, FixedOffset, Local, TimeZone, Utc}; use serde::{self, Deserialize, Deserializer, Serializer}; const FORMAT: &'static str = "%Y-%m-%d %H:%M:%S"; pub fn serialize<S>(date: &DateTime<Utc>, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, { let s = date .with_timezone(&FixedOffset::east(8 * 3600)) .format(FORMAT) .to_string(); serializer.serialize_str(&s) } pub fn deserialize<'de, D>(deserializer: D) -> Result<DateTime<Utc>, D::Error> where D: Deserializer<'de>, { let s = String::deserialize(deserializer)?; let r = Local .datetime_from_str(&s, FORMAT) .map_err(serde::de::Error::custom)?; Ok(DateTime::from(r)) }}声明结构体时,设置字段的序列化办法use serde_derive::{Deserialize, Serialize};#[derive(Debug, sqlx::FromRow, Serialize, Deserialize)]pub struct person { pub id: i32, pub name: String, #[serde(with = "date_format")] pub create_time: DateTime<Utc>,}