1use std::sync::OnceLock;
2
3pub use chrono::{DateTime, Duration, FixedOffset, Local, Utc};
4
5use super::Result;
6
7pub type OffsetDateTime = DateTime<FixedOffset>;
8pub type UtcDateTime = DateTime<Utc>;
9
10static LOCAL_OFFSET: OnceLock<FixedOffset> = OnceLock::new();
11
12pub fn local_offset() -> &'static FixedOffset {
13 LOCAL_OFFSET.get_or_init(_local_offset)
14}
15
16fn _local_offset() -> FixedOffset {
17 FixedOffset::east_opt(3600 * 8).unwrap()
18}
19
20pub fn now_utc() -> OffsetDateTime {
21 Utc::now().fixed_offset()
22}
23
24#[inline]
25pub fn now() -> OffsetDateTime {
26 Local::now().fixed_offset()
27}
28
29pub fn now_epoch_millis() -> i64 {
30 let now = now_utc();
31 now.timestamp_millis()
32}
33
34#[inline]
35pub fn now_epoch_seconds() -> i64 {
36 now_utc().timestamp()
37}
38
39pub fn format_time(time: OffsetDateTime) -> Result<String> {
40 Ok(time.to_rfc3339())
41}
42
43pub fn now_utc_plus_sec_str(sec: u64) -> Result<String> {
44 let new_time = now_utc() + Duration::seconds(sec as i64);
45 format_time(new_time)
46}
47
48pub fn parse_utc(moment: &str) -> Result<OffsetDateTime> {
49 let time = moment.parse::<OffsetDateTime>().unwrap();
50 Ok(time)
51}
52
53#[cfg(feature = "prost-types")]
54pub fn to_prost_timestamp(d: &OffsetDateTime) -> prost_types::Timestamp {
55 prost_types::Timestamp { seconds: d.timestamp(), nanos: d.timestamp_subsec_nanos() as i32 }
56}
57
58#[cfg(feature = "prost-types")]
59pub fn from_prost_timestamp(t: &prost_types::Timestamp) -> Option<OffsetDateTime> {
60 DateTime::from_timestamp(t.seconds, t.nanos as u32).map(|d| d.fixed_offset())
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66
67 #[test]
68 fn test_now_utc() {
69 let now = now_utc();
70 assert_eq!(*now.offset(), FixedOffset::east_opt(0).unwrap());
71 }
72
73 #[test]
74 fn test_convert_std() {
75 let now_utc = now_utc();
76 println!("now is: {}", now_utc);
77
78 let now_local = now();
79 println!("now is {}", now_local);
80 }
81}