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
use std::time::Duration;

use super::{Error, Timestamp};
use chrono::{DateTime, Local, NaiveDateTime, Utc};

const NANOS_IN_SEC_U32: u32 = 1_000_000_000;

impl TryFrom<Timestamp> for NaiveDateTime {
    type Error = Error;
    #[inline]
    fn try_from(t: Timestamp) -> Result<Self, Self::Error> {
        NaiveDateTime::from_timestamp_opt(i64::try_from(t.0.as_secs())?, t.0.subsec_nanos())
            .ok_or(Error::ConvertChrono)
    }
}
impl TryFrom<Timestamp> for DateTime<Utc> {
    type Error = Error;
    fn try_from(t: Timestamp) -> Result<Self, Self::Error> {
        let nt = NaiveDateTime::try_from(t)?;
        let dt_utc = DateTime::<Utc>::from_naive_utc_and_offset(nt, Utc);
        Ok(dt_utc)
    }
}
impl TryFrom<Timestamp> for DateTime<Local> {
    type Error = Error;
    fn try_from(t: Timestamp) -> Result<Self, Self::Error> {
        let dt_utc = DateTime::<Utc>::try_from(t)?;
        Ok(DateTime::from(dt_utc))
    }
}
impl TryFrom<NaiveDateTime> for Timestamp {
    type Error = Error;
    fn try_from(datetime: NaiveDateTime) -> Result<Self, Self::Error> {
        let duration_sec = Duration::from_secs(u64::try_from(datetime.timestamp())?);
        let duration_nanos = Duration::from_nanos(u64::from(
            datetime.timestamp_subsec_nanos() / NANOS_IN_SEC_U32,
        ));
        Ok(Self(duration_sec + duration_nanos))
    }
}
impl TryFrom<DateTime<Utc>> for Timestamp {
    type Error = Error;
    fn try_from(datetime: DateTime<Utc>) -> Result<Self, Self::Error> {
        let duration_sec = Duration::from_secs(u64::try_from(datetime.timestamp())?);
        let duration_nanos = Duration::from_nanos(u64::from(
            datetime.timestamp_subsec_nanos() / NANOS_IN_SEC_U32,
        ));
        Ok(Self(duration_sec + duration_nanos))
    }
}
impl TryFrom<DateTime<Local>> for Timestamp {
    type Error = Error;
    fn try_from(datetime: DateTime<Local>) -> Result<Self, Self::Error> {
        let duration_sec = Duration::from_secs(u64::try_from(datetime.timestamp())?);
        let duration_nanos = Duration::from_nanos(u64::from(
            datetime.timestamp_subsec_nanos() / NANOS_IN_SEC_U32,
        ));
        Ok(Self(duration_sec + duration_nanos))
    }
}
impl Timestamp {
    #[inline]
    pub fn try_into_naivedatetime(self) -> Result<NaiveDateTime, Error> {
        self.try_into()
    }
    #[inline]
    pub fn try_into_datetime_local(self) -> Result<DateTime<Local>, Error> {
        self.try_into()
    }
    #[inline]
    pub fn try_into_datetime_utc(self) -> Result<DateTime<Utc>, Error> {
        self.try_into()
    }
}