xCommonLib/utils/
time_utils.rs

1use time::OffsetDateTime;
2
3use crate::base::status::Status;
4
5const SECONDS_OF_DAY: i64 = 60 * 60 * 24;
6
7const MILL_SECONDS_OF_DAY: i64 = SECONDS_OF_DAY * 1000;
8
9const EIGHT_HOUR: i64 = 60 * 60 * 8 * 1000;
10
11/**
12 * 获取下一天刚开始的时间戳
13 */
14#[allow(dead_code)]
15pub fn cur_timestamp() -> i64 {
16    (OffsetDateTime::now_utc().unix_timestamp_nanos() / 1_000_000) as i64
17}
18
19/**
20 * 获取下一天刚开始的时间戳
21 */
22#[allow(dead_code)]
23pub fn next_day_begin_timestamp_from_today() -> i64 {
24    next_day_begin_timestamp_from(cur_timestamp())
25}
26
27/**
28 * 获取下一天刚开始的时间戳
29 */
30#[allow(dead_code)]
31pub fn next_day_begin_timestamp_from(timestamp: i64) -> i64 {
32    let next_day =
33        ((timestamp + EIGHT_HOUR) / MILL_SECONDS_OF_DAY + 1) * MILL_SECONDS_OF_DAY - EIGHT_HOUR;
34    next_day
35}
36
37/**
38 *  获取前一天的时间
39 */
40#[allow(dead_code)]
41pub fn pre_day_begin_timestamp_from_today() -> i64 {
42    pre_day_begin_timestamp_from(cur_timestamp())
43}
44
45/**
46 *  获取前一天的时间
47 */
48#[allow(dead_code)]
49pub fn pre_day_begin_timestamp_from(timestamp: i64) -> i64 {
50    let pre_day =
51        (timestamp / MILL_SECONDS_OF_DAY) * MILL_SECONDS_OF_DAY - MILL_SECONDS_OF_DAY - EIGHT_HOUR;
52    pre_day
53}
54
55/**
56 *  获取指定时间的开始时间
57 */
58#[allow(dead_code)]
59pub fn begin_timestamp_from(timestamp: i64) -> i64 {
60    (timestamp / MILL_SECONDS_OF_DAY) * MILL_SECONDS_OF_DAY * MILL_SECONDS_OF_DAY - EIGHT_HOUR
61}
62
63/**
64 * 获取指定时间戳,在当天最后这一分钟的时间戳
65 */
66#[allow(dead_code)]
67pub fn last_min_timestamp_from(timestamp: i64) -> i64 {
68    let day_begin_timestamp = begin_timestamp_from(timestamp);
69    day_begin_timestamp + MILL_SECONDS_OF_DAY - 60 * 1000
70}
71
72#[allow(dead_code)]
73fn timestamp_to_local(timestamp: i64) -> i64 {
74    let local_offset = OffsetDateTime::now_local();
75
76    if let Ok(local) = local_offset {
77        return timestamp + (local.offset().whole_seconds() as i64 * 1000);
78    }
79    return timestamp;
80}
81
82/**
83 * 通过时间戳获取年月日
84 */
85#[allow(dead_code)]
86pub fn ymd_from_timestamp(timestamp: i64) -> Result<(u32, u32, u32), Status> {
87    let local_timestamp = timestamp_to_local(timestamp);
88    let datetime = OffsetDateTime::from_unix_timestamp(local_timestamp / 1000);
89    if let Ok(date) = datetime {
90        Ok((date.year() as u32, date.month() as u32, date.day() as u32))
91    } else {
92        Err(Status::error("转换为 datetime 错误!".into()))
93    }
94}
95/**
96 * 通过时间戳获取时分秒
97 */
98#[allow(dead_code)]
99pub fn hms_from_timestamp(timestamp: i64) -> Result<(u32, u32, u32), Status> {
100    let local_timestamp = timestamp_to_local(timestamp);
101    let datetime = OffsetDateTime::from_unix_timestamp(local_timestamp / 1000);
102    if let Ok(date) = datetime {
103        Ok((
104            date.hour() as u32,
105            date.minute() as u32,
106            date.second() as u32,
107        ))
108    } else {
109        Err(Status::error("转换为 datetime 错误!".into()))
110    }
111}
112
113fn fill_buffer(
114    format: &str,
115    match_char: char,
116    time_no: i32,
117    buffer: &mut [u8],
118    cur_index: &mut usize,
119) {
120    let mut symbol_num = 0;
121    // 获取字符个数
122    while *cur_index < format.len() {
123        let ch = format.chars().nth(*cur_index).unwrap();
124        if ch == match_char {
125            symbol_num += 1;
126        } else {
127            *cur_index -= 1;
128            break;
129        }
130        *cur_index += 1;
131    }
132    if *cur_index == format.len() {
133        *cur_index -= 1;
134    }
135    let mut begin = 1;
136    for j in 0..symbol_num {
137        buffer[*cur_index - j] = (time_no / begin % 10) as u8 + 48;
138        begin *= 10;
139    }
140}
141#[allow(dead_code)]
142pub fn time_to_str(
143    format: &str,
144    year: i32,
145    month: i32,
146    day: i32,
147    hour: i32,
148    minutes: i32,
149    seconds: i32,
150    millisecond: i32,
151) -> String {
152    let format_chars: Vec<char> = format.chars().collect();
153    let mut buffer: Vec<u8> = vec![0; format_chars.len()];
154    let format_len = format.len();
155    let mut cur_index = 0;
156    while cur_index < format_len {
157        let ch = format_chars[cur_index];
158        match ch {
159            'y' => fill_buffer(format, ch, year, &mut buffer, &mut cur_index),
160            'M' => fill_buffer(format, ch, month, &mut buffer, &mut cur_index),
161            'd' => fill_buffer(format, ch, day, &mut buffer, &mut cur_index),
162            'h' => fill_buffer(format, ch, hour, &mut buffer, &mut cur_index),
163            'm' => fill_buffer(format, ch, minutes, &mut buffer, &mut cur_index),
164            's' => fill_buffer(format, ch, seconds, &mut buffer, &mut cur_index),
165            'S' => fill_buffer(format, ch, millisecond, &mut buffer, &mut cur_index),
166            _ => buffer[cur_index] = ch as u8,
167        }
168        cur_index += 1;
169    }
170    unsafe { String::from_utf8_unchecked(buffer) }
171}
172#[allow(dead_code)]
173pub fn timestamp_to_string(format: &str, timestamp: i64) -> String {
174    let local_timestamp = timestamp_to_local(timestamp);
175    let datetime = OffsetDateTime::from_unix_timestamp(local_timestamp / 1000);
176    if let Ok(date) = datetime {
177        let second_timestamp = local_timestamp / 1000;
178        let millisecond = (local_timestamp - second_timestamp * 1000) as i32;
179        time_to_str(
180            format,
181            date.year(),
182            date.month() as i32,
183            date.day() as i32,
184            date.hour() as i32,
185            date.minute() as i32,
186            date.second() as i32,
187            millisecond,
188        )
189    } else {
190        "--".to_string()
191    }
192}
193
194#[allow(dead_code)]
195pub fn cur_time_str_with_format(format: &str) -> String {
196  timestamp_to_string(format, cur_timestamp())
197}
198
199
200
201/**
202 *  获取当前时间
203 */
204#[allow(dead_code)]
205pub fn cur_time_str() -> String {
206  cur_time_str_with_format("yyyy-MM-dd hh:mm:ss.SSS")
207}
208
209
210fn buffer_to_number(
211    format: &str,
212    str: &str,
213    match_char: char,
214    format_len: usize,
215    time_no: &mut i32,
216    cur_index: &mut usize,
217) {
218    let mut ch: char;
219    let mut c_ch: char;
220    *time_no = 0;
221    let mut has_val = false;
222
223    while *cur_index < format_len {
224        ch = format.chars().nth(*cur_index).unwrap();
225        c_ch = str.chars().nth(*cur_index).unwrap();
226        if ch != match_char || !c_ch.is_ascii_digit() {
227            if has_val {
228                *cur_index -= 1;
229            }
230            break;
231        }
232        has_val = true;
233        *time_no *= 10;
234        *time_no += c_ch as i32 - '0' as i32;
235        *cur_index += 1;
236    }
237}
238
239pub fn str_to_time(format: &str, string: &str) -> Option<(i32, i32, i32, i32, i32, i32, i32)> {
240    let mut year = 0;
241    let mut month = 0;
242    let mut day = 0;
243    let mut hour = 0;
244    let mut minutes = 0;
245    let mut seconds = 0;
246    let mut millisecond = 0;
247
248    let format_len = format.len();
249    let str_len = string.len();
250    if str_len < format_len {
251        return None;
252    }
253
254    let mut cur_index = 0;
255
256    while cur_index < format_len {
257        let ch = format.chars().nth(cur_index).unwrap();
258        match ch {
259            'y' => buffer_to_number(format, string, ch, format_len, &mut year, &mut cur_index),
260            'M' => buffer_to_number(format, string, ch, format_len, &mut month, &mut cur_index),
261            'd' => buffer_to_number(format, string, ch, format_len, &mut day, &mut cur_index),
262            'h' => buffer_to_number(format, string, ch, format_len, &mut hour, &mut cur_index),
263            'm' => buffer_to_number(format, string, ch, format_len, &mut minutes, &mut cur_index),
264            's' => buffer_to_number(format, string, ch, format_len, &mut seconds, &mut cur_index),
265            'S' => buffer_to_number(
266                format,
267                string,
268                ch,
269                format_len,
270                &mut millisecond,
271                &mut cur_index,
272            ),
273            _ => {
274                if ch != string.chars().nth(cur_index).unwrap() {
275                    return None;
276                }
277            }
278        }
279        cur_index += 1;
280    }
281
282    Some((year, month, day, hour, minutes, seconds, millisecond))
283}