1use chrono::{DateTime, Duration, FixedOffset, SecondsFormat, Utc};
2use serde::{Serialize, Serializer};
3
4use crate::prelude::*;
5
6#[derive(Debug)]
7pub struct YTime(DateTime<Utc>);
8
9impl YTime {
10
11 pub fn origin(&self) -> DateTime<Utc> {
12 self.0
13 }
14
15 pub fn now() -> Self {
16 Self(Utc::now())
17 }
18
19 pub fn from_str(rfc3339_time_str: &str) -> YRes<Self> {
20 let dt = DateTime::parse_from_rfc3339(rfc3339_time_str).map_err(|e|
21 err!("build YTime from rfc3339 format string failed").trace(
22 ctx!("build YTime from rfc3339 format string: DateTime::parse_from_rfc3339 failed", rfc3339_time_str, e)
23 )
24 )?;
25 let utc = dt.with_timezone(&Utc);
26 Ok(Self(utc))
27 }
28
29 pub fn to_str(&self) -> String {
30 self.0.to_rfc3339_opts(SecondsFormat::Millis, true)
31 }
32
33 pub fn east8(&self) -> YRes<String> {
34 let offset = FixedOffset::east_opt(8 * 3600).ok_or(
35 err!("get time string of YTime in east8 timezone failed").trace(
36 ctx!("get time string of YTime in east8 timezone: FixedOffset::east_opt failed")
37 )
38 )?;
39 let east8_time = self.0.with_timezone(&offset);
40 Ok(east8_time.format("%Y-%m-%d %H:%M:%S").to_string())
41 }
42
43 pub fn duration(&self, seconds: i64) -> YTime {
44 YTime(self.0 + Duration::seconds(seconds))
45 }
46
47 pub fn timestamp(&self) -> i64 {
48 self.0.timestamp_millis()
49 }
50
51}
52
53impl Serialize for YTime {
54 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
55 where
56 S: Serializer,
57 {
58 serializer.serialize_str(&self.to_str())
59 }
60}