tenderdash_proto/
time.rs

1//! Time conversion traits and functions
2
3// Most likely we build nostd
4#[cfg(not(any(feature = "server", feature = "client")))]
5use crate::format;
6use crate::{Error, google::protobuf::Timestamp};
7pub trait ToMillis {
8    /// Convert protobuf timestamp into milliseconds since epoch
9    ///
10    /// Note there is a resolution difference, as timestamp uses nanoseconds
11    ///
12    /// # Arguments
13    ///
14    /// * millis - time since epoch, in milliseconds
15    ///
16    /// # Panics
17    ///  
18    /// Panics when timestamp doesn't fit `u64` type
19    fn to_millis(&self) -> Result<u64, Error>;
20
21    #[deprecated(note = "use `to_millis` instead", since = "1.3.1")]
22    fn to_milis(&self) -> u64 {
23        self.to_millis()
24            .expect("cannot convert time to milliseconds")
25    }
26}
27
28impl ToMillis for Timestamp {
29    /// Convert protobuf timestamp into milliseconds since epoch
30    fn to_millis(&self) -> Result<u64, Error> {
31        chrono::DateTime::from_timestamp(self.seconds, self.nanos as u32)
32            .map(|t| t.to_utc().timestamp_millis())
33            .and_then(|t| t.try_into().ok())
34            .ok_or(Error::time_conversion(format!(
35                "time value {:?} out of range",
36                self
37            )))
38    }
39}
40
41pub trait FromMillis: Sized {
42    /// Create protobuf timestamp from milliseconds since epoch
43    ///
44    /// Note there is a resolution difference, as timestamp uses nanoseconds
45    ///
46    /// # Arguments
47    ///
48    /// * millis - time since epoch, in milliseconds; must fit `i64` type
49    fn from_millis(millis: u64) -> Result<Self, Error>;
50    #[deprecated(note = "use `from_millis` instead", since = "1.3.1")]
51    fn from_milis(millis: u64) -> Self
52    where
53        Self: Sized,
54    {
55        Self::from_millis(millis).expect("conversion from milliseconds should not fail")
56    }
57}
58
59impl FromMillis for Timestamp {
60    /// Create protobuf timestamp from milliseconds since epoch
61    ///
62    /// Note there is a resolution difference, as timestamp uses nanoseconds
63    ///
64    /// # Panics
65    ///  
66    /// Panics when `millis` don't fit `i64` type
67    fn from_millis(millis: u64) -> Result<Self, Error> {
68        let ts_millis = millis
69            .try_into()
70            .map_err(|e| Error::time_conversion(format!("milliseconds out of range: {:?}", e)))?;
71
72        let dt = chrono::DateTime::from_timestamp_millis(ts_millis)
73            .ok_or(Error::time_conversion(format!(
74                "cannot create date/time from milliseconds {}",
75                ts_millis,
76            )))?
77            .to_utc();
78
79        Ok(Self {
80            nanos: dt.timestamp_subsec_nanos() as i32,
81            seconds: dt.timestamp(),
82        })
83    }
84}