dev_tool/
date_util.rs

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