r_tool/date/
date_util.rs

1use std::time::{SystemTime, UNIX_EPOCH};
2
3use chrono::{Datelike, Duration, Local, NaiveDate, NaiveDateTime, Utc, Weekday};
4
5#[allow(dead_code)]
6pub enum DateTimeFormat {
7    YmdHMS,
8    // "yyyy-mm-dd hh:mm:ss" => "%Y-%m-%d %H:%M:%S"
9    YmdHM,
10    // "yyyy-mm-dd hh:mm"    => "%Y-%m-%d %H:%M"
11    YmdH,
12    // "yyyy-mm-dd hh"       => "%Y-%m-%d %H"
13    Ymd,
14    // "yyyy-mm-dd"          => "%Y-%m-%d"
15    Ym,
16    // "yyyy-mm"             => "%Y-%m"
17    Md,
18    // "mm-dd"               => "%m-%d"
19    DMYHMS,
20    // "dd-mm-yy hh:mm:ss"   => "%d-%m-%y %H:%M:%S"
21    YmdHmsSlash,
22    // "yyyy/mm/dd hh:mm:ss" => "%Y/%m/%d %H:%M:%S"
23    YmdHmSlash,
24    // "yyyy/mm/dd hh:mm"    => "%Y/%m/%d %H:%M"
25    YmdHSlash,
26    // "yyyy/mm/dd hh"       => "%Y/%m/%d %H"
27    YmdSlash,
28    // "yyyy/mm/dd"          => "%Y/%m/%d"
29    YmSlash,
30    // "yyyy/mm"             => "%Y/%m"
31    MdSlash,
32    // "mm/dd"               => "%m/%d"
33    DmyhmsSlash,
34    // "dd/mm/yy hh:mm:ss"   => "%d/%m/%y %H:%M:%S"
35    Y,
36    // "yyyy"                => "%Y"
37    M,
38    // "mm"                  => "%m"
39    HMS,
40    // "hh:mm:ss"            => "%H:%M:%S"
41    MS,              // "mm:ss"               => "%m:%S"
42}
43
44impl DateTimeFormat {
45    fn to_str(&self) -> &'static str {
46        match self {
47            Self::YmdHMS => "%Y-%m-%d %H:%M:%S",
48            Self::YmdHM => "%Y-%m-%d %H:%M",
49            Self::YmdH => "%Y-%m-%d %H",
50            Self::Ymd => "%Y-%m-%d",
51            Self::Ym => "%Y-%m",
52            Self::Md => "%m-%d",
53            Self::DMYHMS => "%d-%m-%y %H:%M:%S",
54            Self::YmdHmsSlash => "%Y/%m/%d %H:%M:%S",
55            Self::YmdHmSlash => "%Y/%m/%d %H:%M",
56            Self::YmdHSlash => "%Y/%m/%d %H",
57            Self::YmdSlash => "%Y/%m/%d",
58            Self::YmSlash => "%Y/%m",
59            Self::MdSlash => "%m/%d",
60            Self::DmyhmsSlash => "%d/%m/%y %H:%M:%S",
61            Self::Y => "%Y",
62            Self::M => "%m",
63            Self::HMS => "%H:%M:%S",
64            Self::MS => "%m:%S",
65        }
66    }
67}
68
69#[allow(dead_code)]
70pub enum TimeUnit {
71    Years,
72    Months,
73    Days,
74    Hours,
75    Minutes,
76    Seconds,
77    Weeks,
78}
79
80
81pub struct DateUtil {}
82
83#[allow(dead_code)]
84impl DateUtil {
85
86
87    /// 获取结束年的时间
88    ///
89    /// # 参数
90    ///
91    /// * `input_datetime`: 输入日期时间
92    ///
93    /// 返回值: 结束年的时间
94    pub fn get_end_of_year(input_datetime: NaiveDateTime) -> NaiveDateTime {
95        // 获取年份
96        let year = input_datetime.date().year();
97
98        // 创建一个 NaiveDateTime,将月、日、小时、分钟、秒部分设置为12月31日 23:59:59
99        let end_of_year = NaiveDateTime::new(NaiveDate::from_ymd_opt(year, 12, 31).unwrap(), chrono::NaiveTime::from_hms_opt(23, 59, 59).unwrap());
100
101        end_of_year
102    }
103
104    /// 获取结束月的时间
105    ///
106    /// # 参数
107    ///
108    /// * `input_datetime`: 输入日期时间
109    ///
110    /// 返回值: 结束月的时间
111    pub fn get_end_of_month(input_datetime: NaiveDateTime) -> NaiveDateTime {
112        // 获取年份和月份
113        let year = input_datetime.date().year();
114        let month = input_datetime.date().month();
115
116        // 获取该月的天数
117        let days_in_month = NaiveDate::from_ymd_opt(year, month + 1, 1).unwrap_or_else(|| NaiveDate::from_ymd_opt(year + 1, 1, 1).unwrap()).pred_opt().unwrap().day();
118
119        // 创建一个 NaiveDateTime,将日、小时、分钟、秒部分设置为该月最后一天 23:59:59
120        let end_of_month = NaiveDateTime::new(NaiveDate::from_ymd_opt(year, month, days_in_month).unwrap(), chrono::NaiveTime::from_hms_opt(23, 59, 59).unwrap());
121
122        end_of_month
123    }
124
125    /// 获取结束周的时间
126    ///
127    /// # 参数
128    ///
129    /// * `input_datetime`: 输入日期时间
130    ///
131    /// 返回值: 结束周的时间
132    pub fn get_end_of_week(input_datetime: NaiveDateTime) -> NaiveDateTime {
133        // 获取输入日期时间的星期几
134        let weekday = input_datetime.date().weekday();
135
136        // 计算距离该星期结束的天数
137        let days_to_end = match weekday {
138            Weekday::Mon => 6,
139            Weekday::Tue => 5,
140            Weekday::Wed => 4,
141            Weekday::Thu => 3,
142            Weekday::Fri => 2,
143            Weekday::Sat => 1,
144            Weekday::Sun => 0,
145        };
146
147        // 创建一个 NaiveDateTime,将小时、分钟、秒部分设置为星期结束的时刻
148        let end_of_week = input_datetime + Duration::days(days_to_end as i64);
149        let end_of_week = NaiveDateTime::new(end_of_week.date(), chrono::NaiveTime::from_hms_opt(23, 59, 59).unwrap());
150
151        end_of_week
152    }
153
154
155
156    /// 获取开始年的时间
157    ///
158    /// # 参数
159    ///
160    /// * `input_datetime`: 输入日期时间
161    ///
162    /// 返回值: 开始年的时间
163    pub fn get_start_of_year(input_datetime: NaiveDateTime) -> NaiveDateTime {
164        // 获取年份
165        let year = input_datetime.date().year();
166
167        // 创建一个 NaiveDateTime,将月、日、小时、分钟、秒部分设置为1月1日 0:0:0
168        let start_of_year = NaiveDateTime::new(NaiveDate::from_ymd_opt(year, 1, 1).unwrap(), chrono::NaiveTime::from_hms_opt(0, 0, 0).unwrap());
169
170        start_of_year
171    }
172
173    /// 获取开始月的时间
174    ///
175    /// # 参数
176    ///
177    /// * `input_datetime`: 输入日期时间
178    ///
179    /// 返回值: 开始月的时间
180    pub fn get_start_of_month(input_datetime: NaiveDateTime) -> NaiveDateTime {
181        // 获取年份和月份
182        let year = input_datetime.date().year();
183        let month = input_datetime.date().month();
184        // 创建一个 NaiveDateTime,将日、小时、分钟、秒部分设置为该月1日 0:0:0
185        let start_of_month = NaiveDateTime::new(NaiveDate::from_ymd_opt(year, month, 1).unwrap(), chrono::NaiveTime::from_hms_opt(0, 0, 0).unwrap());
186
187        start_of_month
188    }
189
190    /// 获取开始周的时间
191    ///
192    /// # 参数
193    ///
194    /// * `input_datetime`: 输入日期时间
195    ///
196    /// 返回值: 开始周的时间
197    pub fn get_start_of_week(input_datetime: NaiveDateTime) -> NaiveDateTime {
198        // 获取输入日期时间的星期几
199        let weekday = input_datetime.date().weekday();
200
201        // 计算距离该星期开始的天数
202        let days_to_start = match weekday {
203            Weekday::Mon => 0,
204            Weekday::Tue => 1,
205            Weekday::Wed => 2,
206            Weekday::Thu => 3,
207            Weekday::Fri => 4,
208            Weekday::Sat => 5,
209            Weekday::Sun => 6,
210        };
211
212        // 创建一个 NaiveDateTime,将小时、分钟、秒部分设置为星期开始的时刻
213        let start_of_week = input_datetime - Duration::days(days_to_start as i64);
214        let start_of_week = NaiveDateTime::new(start_of_week.date(), chrono::NaiveTime::from_hms_opt(0, 0, 0).unwrap());
215
216        start_of_week
217    }
218
219    /// 获取一天中的起始时间
220    ///
221    /// # 参数
222    ///
223    /// * `input_date`: 输入日期(不包含时间部分)
224    ///
225    /// 返回值: 一天中的起始时间
226    pub fn get_start_of_day_for_day(input_date: NaiveDate) -> NaiveDateTime {
227        // 创建一个 NaiveDateTime,将小时、分钟、秒部分设置为零
228        let start_of_day = NaiveDateTime::new(input_date, chrono::NaiveTime::from_hms_opt(0, 0, 0).unwrap());
229
230        start_of_day
231    }
232
233
234    /// 获取一天的结束时间
235    ///
236    /// # 参数
237    ///
238    /// * `input_date`: 输入日期(不包含时间部分)
239    ///
240    /// 返回值: 一天的结束时间
241    pub fn get_end_of_day_for_day(input_date: NaiveDate) -> NaiveDateTime {
242        // 创建一个 NaiveDateTime,将小时、分钟、秒部分设置为23:59:59
243        let end_of_day = NaiveDateTime::new(input_date, chrono::NaiveTime::from_hms_opt(23, 59, 59).unwrap());
244
245        end_of_day
246    }
247
248    /// 获取一天的起始时间
249    ///
250    /// # 参数
251    ///
252    /// * `input_datetime`: 输入日期时间
253    ///
254    /// 返回值: 一天的起始时间
255    pub fn get_start_of_day(input_datetime: NaiveDateTime) -> NaiveDateTime {
256        // 获取日期部分
257        let date_part = input_datetime.date();
258
259        // 创建一个 NaiveDateTime,将小时、分钟、秒部分设置为0:0:0
260        let start_of_day = NaiveDateTime::new(date_part, chrono::NaiveTime::from_hms_opt(0, 0, 0).unwrap());
261
262        start_of_day
263    }
264
265    /// 获取一天的结束时间
266    ///
267    /// # 参数
268    ///
269    /// * `input_datetime`: 输入日期时间
270    ///
271    /// 返回值: 一天的结束时间
272    pub fn get_end_of_day(input_datetime: NaiveDateTime) -> NaiveDateTime {
273        // 获取日期部分
274        let date_part = input_datetime.date();
275
276        // 创建一个 NaiveDateTime,将小时、分钟、秒部分设置为23:59:59
277        let end_of_day = NaiveDateTime::new(date_part, chrono::NaiveTime::from_hms_opt(23, 59, 59).unwrap());
278
279        end_of_day
280    }
281
282
283
284
285
286    /// 对 NaiveDateTime 进行时间加减法
287    ///
288    /// # 参数
289    ///
290    /// * `input_time`: 输入时间
291    /// * `step`: 步长,可以是正数或负数
292    /// * `unit`: 时间单位,使用 TimeUnit 枚举表示
293    ///
294    /// 返回值: 计算后的时间
295    pub fn manipulate_time(input_time: NaiveDateTime, step: i64, unit: TimeUnit) -> NaiveDateTime {
296        // 定义时间间隔
297        let duration = match unit {
298            TimeUnit::Years => Duration::days(step * 365),
299            TimeUnit::Months => Duration::days(step * 30),
300            TimeUnit::Days => Duration::days(step),
301            TimeUnit::Hours => Duration::hours(step),
302            TimeUnit::Minutes => Duration::minutes(step),
303            TimeUnit::Seconds => Duration::seconds(step),
304            TimeUnit::Weeks => Duration::weeks(step),
305        };
306
307        // 进行时间加减法操作
308        input_time + duration
309    }
310    /// 解析时间字符串
311    ///
312    /// # 参数
313    ///
314    /// * `input`: 待解析的时间字符串
315    /// * `format_str`: 时间格式
316    ///
317    /// 返回值: 解析后的时间,以 NaiveDateTime 格式表示
318    ///
319    pub fn parse_time(input: String, format_str: DateTimeFormat) -> Option<NaiveDateTime> {
320        let parsed_time = NaiveDateTime::parse_from_str(input.as_str(), format_str.to_str());
321
322        return match parsed_time {
323            Ok(parsed_time) => { Option::from(parsed_time) }
324
325            Err(err) => {
326                println!("时间转换异常 , {}", err);
327                Option::None
328            }
329        }
330    }
331
332
333    /// 获取当前时间
334    ///
335    /// # 参数
336    ///
337    /// * `format_str`: 目标格式
338    ///
339    /// 返回值: String 当前时间的字符串表示
340    ///
341    pub fn get_now_time_string(format_str: DateTimeFormat) -> String {
342        let current_time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs();
343        let formatted_time = chrono::DateTime::<chrono::Local>::from(UNIX_EPOCH + std::time::Duration::from_secs(current_time))
344            .format(format_str.to_str())
345            .to_string();
346        return formatted_time;
347    }
348
349
350    pub fn now() -> NaiveDateTime {
351        Local::now().naive_local()
352    }
353
354    /// 获取当前 UTC 时间
355    ///
356    /// # 参数
357    ///
358    /// * `format_str`: 目标格式
359    ///
360    /// 返回值: String 当前 UTC 时间的字符串表示
361    ///
362    pub fn get_now_time_utc_string(format_str: DateTimeFormat) -> String {
363        let current_time = Utc::now();
364        current_time.format(format_str.to_str()).to_string()
365    }
366}
367
368
369#[cfg(test)]
370mod tests {
371    use crate::date::date_util::DateTimeFormat;
372    use crate::date::date_util::DateUtil;
373    use crate::date::date_util::TimeUnit;
374
375    #[test]
376    fn test_date_util() {
377        // 示例用法
378        println!("当前日期:{}", DateUtil::get_now_time_string(DateTimeFormat::YmdHMS));
379        let s = DateUtil::get_now_time_utc_string(DateTimeFormat::YmdHMS);
380        println!("当前日期:{}", s);
381
382        let time = DateUtil::parse_time(s, DateTimeFormat::YmdHMS);
383        println!("当前日期:{}", time.unwrap());
384
385
386        let time1 = DateUtil::manipulate_time(DateUtil::now(), -1, TimeUnit::Days);
387        println!("计算后日期:{}", time1);
388
389        // 获取当前日期时间
390        let current_datetime = chrono::Utc::now().naive_utc();
391
392        // 获取开始年的时间
393        let start_of_year = DateUtil::get_start_of_year(current_datetime);
394
395        // 获取开始月的时间
396        let start_of_month = DateUtil::get_start_of_month(current_datetime);
397
398        // 获取开始周的时间
399        let start_of_week = DateUtil::get_start_of_week(current_datetime);
400        // 获取结束年的时间
401        let end_of_year = DateUtil::get_end_of_year(current_datetime);
402
403        // 获取结束月的时间
404        let end_of_month = DateUtil::get_end_of_month(current_datetime);
405
406        // 获取结束周的时间
407        let end_of_week = DateUtil::get_end_of_week(current_datetime);
408
409        // 打印结果
410        println!("当前日期时间:{}", current_datetime);
411        println!("开始年的时间:{}", start_of_year);
412        println!("开始月的时间:{}", start_of_month);
413        println!("开始周的时间:{}", start_of_week);
414        println!("结束年的时间:{}", end_of_year);
415        println!("结束月的时间:{}", end_of_month);
416        println!("结束周的时间:{}", end_of_week);
417    }
418}