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