dev_tool/
date_util.rs

1
2use chrono::{DateTime, Duration, Local, NaiveDateTime, ParseError, TimeZone, Utc, NaiveDate};
3use std::cmp::Ordering;
4use std::time::{SystemTime, UNIX_EPOCH};
5
6/// 日期工具,包含常用快捷生成,如获取当日时间字符串、格式化、时间字符串解析等
7pub struct DateUtil;
8
9impl DateUtil {
10    /// 获取当前日期字符串,输出格式:%Y-%m-%d
11    ///
12    pub fn current_date_string() -> String {
13        let now = Local::now();
14        now.format("%Y-%m-%d").to_string()
15    }
16
17    /// 获取当前日期的字符串表示
18    ///
19    /// 该函数获取本地当前时间,并将其格式化为"年-月-日"的字符串格式。
20    ///
21    /// # 返回值
22    /// 返回格式为"YYYY-MM-DD"的日期字符串
23    pub fn today_string() -> String {
24        let now = Local::now();
25        now.format("%Y-%m-%d").to_string()
26    }
27
28    pub fn parse_day_string(day_string: &str) -> Result<NaiveDate, ParseError> { 
29        NaiveDate::parse_from_str(day_string, "%Y-%m-%d")
30    }
31
32    /// 进行日期偏移,offset为偏移量,正数表示向后偏移,负数表示向前偏移
33    /// 
34    /// # 返回值
35    /// 返回格式为"YYYY-MM-DD"的日期字符串
36    pub fn day_offset(offset: i64) -> String {
37        let now: DateTime<Local> = Local::now();
38        let duration = Duration::days(offset);
39        let now = now + duration;
40        now.format("%Y-%m-%d").to_string()
41    }
42
43    /// 获取昨天日期的字符串表示
44    ///
45    /// 该函数计算昨天的日期,并将其格式化为"YYYY-MM-DD"格式的字符串。
46    ///
47    /// # Returns
48    ///
49    /// 返回昨天日期的字符串表示,格式为"YYYY-MM-DD"
50    ///
51    /// # Example
52    ///
53    /// ```
54    /// let yesterday = yesterday_string();
55    /// println!("{}", yesterday); // 输出类似 "2023-12-06"
56    /// ```
57    pub fn yesterday_string() -> String {
58        // 获取当前本地时间
59        let now = Local::now();
60        // 计算昨天的时间
61        let yesterday = now - Duration::days(1);
62        // 将昨天的日期格式化为字符串并返回
63        yesterday.format("%Y-%m-%d").to_string()
64    }
65
66    /// 获取明天日期的字符串表示
67    ///
68    /// 该函数计算明天的日期,并将其格式化为"YYYY-MM-DD"格式的字符串。
69    ///
70    /// # 返回值
71    /// 返回表示明天日期的字符串,格式为"YYYY-MM-DD"
72    pub fn tomorrow_string() -> String {
73        // 获取当前本地时间
74        let now = Local::now();
75        // 计算明天的时间
76        let tomorrow = now + Duration::days(1);
77        // 将明天的日期格式化为字符串并返回
78        tomorrow.format("%Y-%m-%d").to_string()
79    }
80
81    /// 比较两个时间字符串的大小
82    ///
83    /// 该函数将两个时间字符串按照指定的格式解析为DateTime对象,然后进行比较。
84    ///
85    /// # 参数
86    /// * `time1` - 第一个时间字符串
87    /// * `time2` - 第二个时间字符串
88    /// * `fmt` - 时间格式字符串,用于解析time1和time2
89    ///
90    /// # 返回值
91    /// * `Ok(Ordering)` - 比较结果,Ordering::Less表示time1小于time2,
92    ///                    Ordering::Equal表示time1等于time2,
93    ///                    Ordering::Greater表示time1大于time2
94    /// * `Err(ParseError)` - 时间解析失败时返回错误信息
95    ///
96    /// # 错误处理
97    /// 如果任一时间字符串无法按照指定格式解析,函数将返回ParseError错误
98    pub fn cmp_string(time1: &str, time2: &str, fmt: &str) -> Result<Ordering, ParseError> {
99        // 将两个时间字符串转换为DateTime对象,然后进行比较大小
100        let naive1 = NaiveDateTime::parse_from_str(time1, fmt)?;
101        let naive2 = NaiveDateTime::parse_from_str(time2, fmt)?;
102        let datetime1: DateTime<Utc> = Utc.from_utc_datetime(&naive1);
103        let datetime2: DateTime<Utc> = Utc.from_utc_datetime(&naive2);
104        let c = datetime1.cmp(&datetime2);
105        Ok(c)
106    }
107
108    /// 获取当前时间字符串,输出格式:%Y-%m-%d %H:%M:%S
109    ///
110    pub fn current_time_string() -> String {
111        let now = Local::now();
112        now.format("%Y-%m-%d %H:%M:%S").to_string()
113    }
114
115    /// # 参数
116    /// - time: 格式如:"2025-08-30 12:00:00"
117    pub fn parse_datetime(time: &str) -> Result<NaiveDateTime, chrono::ParseError> {
118        let res = NaiveDateTime::parse_from_str(time, "%Y-%m-%d %H:%M:%S")?;
119        Ok(res)
120    }
121
122    pub fn parse_string(time: &str, fmt: &str) -> Result<NaiveDateTime, chrono::ParseError> {
123        let res = NaiveDateTime::parse_from_str(time, fmt)?;
124        Ok(res)
125    }
126
127    /// 当前时间戳(秒),返回10位长度
128    pub fn current_timestamp() -> u64 {
129        let time = Local::now();
130        DateUtil::timestamp(time)
131    }
132
133    /// 返回10位时间戳(秒)
134    pub fn timestamp(time: DateTime<Local>) -> u64 {
135        let system_time: SystemTime = time.into();
136        let duration = system_time.duration_since(UNIX_EPOCH).unwrap();
137        let timestamp = duration.as_secs();
138        timestamp
139    }
140
141    /// 时间戳加减法(秒)
142    pub fn timestamp_add(time: DateTime<Local>, seconds: i64) -> u64 {
143        let diff = Duration::seconds(seconds);
144        let time = time + diff;
145        DateUtil::timestamp(time)
146    }
147}
148
149#[cfg(test)]
150mod tests {
151
152    use super::*;
153
154    #[test]
155    fn test_current_time_string() {
156        let timestring = DateUtil::current_time_string();
157        println!("timestring = {}", timestring);
158    }
159
160    #[test]
161    fn test_current_timestamp() {
162        let ts = DateUtil::current_timestamp();
163        println!("ts = {}", ts);
164    }
165
166    #[test]
167    fn test_parse_datetime() {
168        let x = DateUtil::parse_datetime("2025-08-30 12:00:00");
169        println!("{:?}", x);
170    }
171
172    #[test]
173    fn test_cmp_string() {
174        let c = DateUtil::cmp_string(
175            "2025-08-30 13:00:00",
176            "2025-08-30 12:00:01",
177            "%Y-%m-%d %H:%M:%S",
178        );
179        println!("{:?}", c);
180    }
181}