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 75 76 77 78 79
use serde::de::{self, Deserialize, Deserializer, Unexpected, Visitor}; use serde::ser::{Serialize, Serializer}; use std::fmt; use chrono; use chrono::offset::{FixedOffset, Local, Offset}; use std::ops::Deref; #[derive(Debug, Eq, PartialEq, Hash)] pub struct DateTime(chrono::DateTime<FixedOffset>); impl Deref for DateTime { type Target = chrono::DateTime<FixedOffset>; fn deref(&self) -> &Self::Target { &self.0 } } use std::time; impl Default for DateTime { fn default() -> Self { let systime = time::SystemTime::now(); let datetime_local = chrono::DateTime::<Local>::from(systime); let tz = chrono::offset::Utc.fix(); let datetime_with_tz = datetime_local.with_timezone(&tz); DateTime(datetime_with_tz) } } impl DateTime { pub fn now() -> Self { Self::default() } } impl Serialize for DateTime { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, { serializer.serialize_str(self.0.to_rfc3339().as_str()) } } struct DateTimeVisitor; impl<'de> Visitor<'de> for DateTimeVisitor { type Value = DateTime; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a valid date time formatted str") } fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: de::Error, { chrono::DateTime::parse_from_rfc3339(value) .map(|x| DateTime(x)) .map_err(|_e| de::Error::invalid_value(Unexpected::Str(value), &self)) } } impl<'de> Deserialize<'de> for DateTime { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>, { deserializer.deserialize_str(DateTimeVisitor) } } #[cfg(test)] mod test { static RAW: &str = r#""2016-05-03T14:26:57+00:00""#; deser_roundtrip!(datetime_deser, super::DateTime, RAW); serde_roundtrip!(datetime_serde, super::DateTime, super::DateTime::default()); }