1 use core::fmt; 2 use serde::{de, ser}; 3 4 use super::DateTime; 5 use crate::format::{write_rfc3339, SecondsFormat}; 6 use crate::naive::datetime::serde::serde_from; 7 #[cfg(feature = "clock")] 8 use crate::offset::Local; 9 use crate::offset::{FixedOffset, Offset, TimeZone, Utc}; 10 11 #[doc(hidden)] 12 #[derive(Debug)] 13 pub struct SecondsTimestampVisitor; 14 15 #[doc(hidden)] 16 #[derive(Debug)] 17 pub struct NanoSecondsTimestampVisitor; 18 19 #[doc(hidden)] 20 #[derive(Debug)] 21 pub struct MicroSecondsTimestampVisitor; 22 23 #[doc(hidden)] 24 #[derive(Debug)] 25 pub struct MilliSecondsTimestampVisitor; 26 27 /// Serialize into an ISO 8601 formatted string. 28 /// 29 /// See [the `serde` module](./serde/index.html) for alternate 30 /// serializations. 31 impl<Tz: TimeZone> ser::Serialize for DateTime<Tz> { serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,32 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 33 where 34 S: ser::Serializer, 35 { 36 struct FormatIso8601<'a, Tz: TimeZone> { 37 inner: &'a DateTime<Tz>, 38 } 39 40 impl<'a, Tz: TimeZone> fmt::Display for FormatIso8601<'a, Tz> { 41 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 42 let naive = self.inner.naive_local(); 43 let offset = self.inner.offset.fix(); 44 write_rfc3339(f, naive, offset, SecondsFormat::AutoSi, true) 45 } 46 } 47 48 serializer.collect_str(&FormatIso8601 { inner: self }) 49 } 50 } 51 52 struct DateTimeVisitor; 53 54 impl<'de> de::Visitor<'de> for DateTimeVisitor { 55 type Value = DateTime<FixedOffset>; 56 expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result57 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 58 formatter.write_str("a formatted date and time string or a unix timestamp") 59 } 60 visit_str<E>(self, value: &str) -> Result<Self::Value, E> where E: de::Error,61 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> 62 where 63 E: de::Error, 64 { 65 value.parse().map_err(E::custom) 66 } 67 } 68 69 /// Deserialize a value that optionally includes a timezone offset in its 70 /// string representation 71 /// 72 /// The value to be deserialized must be an rfc3339 string. 73 /// 74 /// See [the `serde` module](./serde/index.html) for alternate 75 /// deserialization formats. 76 impl<'de> de::Deserialize<'de> for DateTime<FixedOffset> { deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: de::Deserializer<'de>,77 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 78 where 79 D: de::Deserializer<'de>, 80 { 81 deserializer.deserialize_str(DateTimeVisitor) 82 } 83 } 84 85 /// Deserialize into a UTC value 86 /// 87 /// The value to be deserialized must be an rfc3339 string. 88 /// 89 /// See [the `serde` module](./serde/index.html) for alternate 90 /// deserialization formats. 91 impl<'de> de::Deserialize<'de> for DateTime<Utc> { deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: de::Deserializer<'de>,92 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 93 where 94 D: de::Deserializer<'de>, 95 { 96 deserializer.deserialize_str(DateTimeVisitor).map(|dt| dt.with_timezone(&Utc)) 97 } 98 } 99 100 /// Deserialize a value that includes no timezone in its string 101 /// representation 102 /// 103 /// The value to be deserialized must be an rfc3339 string. 104 /// 105 /// See [the `serde` module](./serde/index.html) for alternate 106 /// serialization formats. 107 #[cfg(feature = "clock")] 108 impl<'de> de::Deserialize<'de> for DateTime<Local> { deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: de::Deserializer<'de>,109 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 110 where 111 D: de::Deserializer<'de>, 112 { 113 deserializer.deserialize_str(DateTimeVisitor).map(|dt| dt.with_timezone(&Local)) 114 } 115 } 116 117 /// Ser/de to/from timestamps in nanoseconds 118 /// 119 /// Intended for use with `serde`'s `with` attribute. 120 /// 121 /// # Example: 122 /// 123 /// ```rust 124 /// # use chrono::{DateTime, Utc, NaiveDate}; 125 /// # use serde_derive::{Deserialize, Serialize}; 126 /// use chrono::serde::ts_nanoseconds; 127 /// #[derive(Deserialize, Serialize)] 128 /// struct S { 129 /// #[serde(with = "ts_nanoseconds")] 130 /// time: DateTime<Utc> 131 /// } 132 /// 133 /// let time = NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_nano_opt(02, 04, 59, 918355733).unwrap().and_local_timezone(Utc).unwrap(); 134 /// let my_s = S { 135 /// time: time.clone(), 136 /// }; 137 /// 138 /// let as_string = serde_json::to_string(&my_s)?; 139 /// assert_eq!(as_string, r#"{"time":1526522699918355733}"#); 140 /// let my_s: S = serde_json::from_str(&as_string)?; 141 /// assert_eq!(my_s.time, time); 142 /// # Ok::<(), serde_json::Error>(()) 143 /// ``` 144 pub mod ts_nanoseconds { 145 use core::fmt; 146 use serde::{de, ser}; 147 148 use crate::offset::TimeZone; 149 use crate::{DateTime, Utc}; 150 151 use super::{serde_from, NanoSecondsTimestampVisitor}; 152 153 /// Serialize a UTC datetime into an integer number of nanoseconds since the epoch 154 /// 155 /// Intended for use with `serde`s `serialize_with` attribute. 156 /// 157 /// # Errors 158 /// 159 /// An `i64` with nanosecond precision can span a range of ~584 years. This function returns an 160 /// error on an out of range `DateTime`. 161 /// 162 /// The dates that can be represented as nanoseconds are between 1677-09-21T00:12:44.0 and 163 /// 2262-04-11T23:47:16.854775804. 164 /// 165 /// # Example: 166 /// 167 /// ```rust 168 /// # use chrono::{DateTime, Utc, NaiveDate}; 169 /// # use serde_derive::Serialize; 170 /// use chrono::serde::ts_nanoseconds::serialize as to_nano_ts; 171 /// #[derive(Serialize)] 172 /// struct S { 173 /// #[serde(serialize_with = "to_nano_ts")] 174 /// time: DateTime<Utc> 175 /// } 176 /// 177 /// let my_s = S { 178 /// time: NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_nano_opt(02, 04, 59, 918355733).unwrap().and_local_timezone(Utc).unwrap(), 179 /// }; 180 /// let as_string = serde_json::to_string(&my_s)?; 181 /// assert_eq!(as_string, r#"{"time":1526522699918355733}"#); 182 /// # Ok::<(), serde_json::Error>(()) 183 /// ``` serialize<S>(dt: &DateTime<Utc>, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,184 pub fn serialize<S>(dt: &DateTime<Utc>, serializer: S) -> Result<S::Ok, S::Error> 185 where 186 S: ser::Serializer, 187 { 188 serializer.serialize_i64(dt.timestamp_nanos_opt().ok_or(ser::Error::custom( 189 "value out of range for a timestamp with nanosecond precision", 190 ))?) 191 } 192 193 /// Deserialize a [`DateTime`] from a nanosecond timestamp 194 /// 195 /// Intended for use with `serde`s `deserialize_with` attribute. 196 /// 197 /// # Example: 198 /// 199 /// ```rust 200 /// # use chrono::{DateTime, TimeZone, Utc}; 201 /// # use serde_derive::Deserialize; 202 /// use chrono::serde::ts_nanoseconds::deserialize as from_nano_ts; 203 /// #[derive(Debug, PartialEq, Deserialize)] 204 /// struct S { 205 /// #[serde(deserialize_with = "from_nano_ts")] 206 /// time: DateTime<Utc> 207 /// } 208 /// 209 /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355733 }"#)?; 210 /// assert_eq!(my_s, S { time: Utc.timestamp_opt(1526522699, 918355733).unwrap() }); 211 /// 212 /// let my_s: S = serde_json::from_str(r#"{ "time": -1 }"#)?; 213 /// assert_eq!(my_s, S { time: Utc.timestamp_opt(-1, 999_999_999).unwrap() }); 214 /// # Ok::<(), serde_json::Error>(()) 215 /// ``` deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error> where D: de::Deserializer<'de>,216 pub fn deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error> 217 where 218 D: de::Deserializer<'de>, 219 { 220 d.deserialize_i64(NanoSecondsTimestampVisitor) 221 } 222 223 impl<'de> de::Visitor<'de> for NanoSecondsTimestampVisitor { 224 type Value = DateTime<Utc>; 225 expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result226 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 227 formatter.write_str("a unix timestamp in nanoseconds") 228 } 229 230 /// Deserialize a timestamp in nanoseconds since the epoch visit_i64<E>(self, value: i64) -> Result<Self::Value, E> where E: de::Error,231 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E> 232 where 233 E: de::Error, 234 { 235 serde_from( 236 Utc.timestamp_opt( 237 value.div_euclid(1_000_000_000), 238 (value.rem_euclid(1_000_000_000)) as u32, 239 ), 240 &value, 241 ) 242 } 243 244 /// Deserialize a timestamp in nanoseconds since the epoch visit_u64<E>(self, value: u64) -> Result<Self::Value, E> where E: de::Error,245 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> 246 where 247 E: de::Error, 248 { 249 serde_from( 250 Utc.timestamp_opt((value / 1_000_000_000) as i64, (value % 1_000_000_000) as u32), 251 &value, 252 ) 253 } 254 } 255 } 256 257 /// Ser/de to/from optional timestamps in nanoseconds 258 /// 259 /// Intended for use with `serde`'s `with` attribute. 260 /// 261 /// # Example: 262 /// 263 /// ```rust 264 /// # use chrono::{DateTime, Utc, NaiveDate}; 265 /// # use serde_derive::{Deserialize, Serialize}; 266 /// use chrono::serde::ts_nanoseconds_option; 267 /// #[derive(Deserialize, Serialize)] 268 /// struct S { 269 /// #[serde(with = "ts_nanoseconds_option")] 270 /// time: Option<DateTime<Utc>> 271 /// } 272 /// 273 /// let time = Some(NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_nano_opt(02, 04, 59, 918355733).unwrap().and_local_timezone(Utc).unwrap()); 274 /// let my_s = S { 275 /// time: time.clone(), 276 /// }; 277 /// 278 /// let as_string = serde_json::to_string(&my_s)?; 279 /// assert_eq!(as_string, r#"{"time":1526522699918355733}"#); 280 /// let my_s: S = serde_json::from_str(&as_string)?; 281 /// assert_eq!(my_s.time, time); 282 /// # Ok::<(), serde_json::Error>(()) 283 /// ``` 284 pub mod ts_nanoseconds_option { 285 use core::fmt; 286 use serde::{de, ser}; 287 288 use crate::{DateTime, Utc}; 289 290 use super::NanoSecondsTimestampVisitor; 291 292 /// Serialize a UTC datetime into an integer number of nanoseconds since the epoch or none 293 /// 294 /// Intended for use with `serde`s `serialize_with` attribute. 295 /// 296 /// # Errors 297 /// 298 /// An `i64` with nanosecond precision can span a range of ~584 years. This function returns an 299 /// error on an out of range `DateTime`. 300 /// 301 /// The dates that can be represented as nanoseconds are between 1677-09-21T00:12:44.0 and 302 /// 2262-04-11T23:47:16.854775804. 303 /// 304 /// # Example: 305 /// 306 /// ```rust 307 /// # use chrono::{DateTime, Utc, NaiveDate}; 308 /// # use serde_derive::Serialize; 309 /// use chrono::serde::ts_nanoseconds_option::serialize as to_nano_tsopt; 310 /// #[derive(Serialize)] 311 /// struct S { 312 /// #[serde(serialize_with = "to_nano_tsopt")] 313 /// time: Option<DateTime<Utc>> 314 /// } 315 /// 316 /// let my_s = S { 317 /// time: Some(NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_nano_opt(02, 04, 59, 918355733).unwrap().and_local_timezone(Utc).unwrap()), 318 /// }; 319 /// let as_string = serde_json::to_string(&my_s)?; 320 /// assert_eq!(as_string, r#"{"time":1526522699918355733}"#); 321 /// # Ok::<(), serde_json::Error>(()) 322 /// ``` serialize<S>(opt: &Option<DateTime<Utc>>, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,323 pub fn serialize<S>(opt: &Option<DateTime<Utc>>, serializer: S) -> Result<S::Ok, S::Error> 324 where 325 S: ser::Serializer, 326 { 327 match *opt { 328 Some(ref dt) => serializer.serialize_some(&dt.timestamp_nanos_opt().ok_or( 329 ser::Error::custom("value out of range for a timestamp with nanosecond precision"), 330 )?), 331 None => serializer.serialize_none(), 332 } 333 } 334 335 /// Deserialize a `DateTime` from a nanosecond timestamp or none 336 /// 337 /// Intended for use with `serde`s `deserialize_with` attribute. 338 /// 339 /// # Example: 340 /// 341 /// ```rust 342 /// # use chrono::{DateTime, TimeZone, Utc}; 343 /// # use serde_derive::Deserialize; 344 /// use chrono::serde::ts_nanoseconds_option::deserialize as from_nano_tsopt; 345 /// #[derive(Debug, PartialEq, Deserialize)] 346 /// struct S { 347 /// #[serde(deserialize_with = "from_nano_tsopt")] 348 /// time: Option<DateTime<Utc>> 349 /// } 350 /// 351 /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355733 }"#)?; 352 /// assert_eq!(my_s, S { time: Utc.timestamp_opt(1526522699, 918355733).single() }); 353 /// # Ok::<(), serde_json::Error>(()) 354 /// ``` deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error> where D: de::Deserializer<'de>,355 pub fn deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error> 356 where 357 D: de::Deserializer<'de>, 358 { 359 d.deserialize_option(OptionNanoSecondsTimestampVisitor) 360 } 361 362 struct OptionNanoSecondsTimestampVisitor; 363 364 impl<'de> de::Visitor<'de> for OptionNanoSecondsTimestampVisitor { 365 type Value = Option<DateTime<Utc>>; 366 expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result367 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 368 formatter.write_str("a unix timestamp in nanoseconds or none") 369 } 370 371 /// Deserialize a timestamp in nanoseconds since the epoch visit_some<D>(self, d: D) -> Result<Self::Value, D::Error> where D: de::Deserializer<'de>,372 fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error> 373 where 374 D: de::Deserializer<'de>, 375 { 376 d.deserialize_i64(NanoSecondsTimestampVisitor).map(Some) 377 } 378 379 /// Deserialize a timestamp in nanoseconds since the epoch visit_none<E>(self) -> Result<Self::Value, E> where E: de::Error,380 fn visit_none<E>(self) -> Result<Self::Value, E> 381 where 382 E: de::Error, 383 { 384 Ok(None) 385 } 386 387 /// Deserialize a timestamp in nanoseconds since the epoch visit_unit<E>(self) -> Result<Self::Value, E> where E: de::Error,388 fn visit_unit<E>(self) -> Result<Self::Value, E> 389 where 390 E: de::Error, 391 { 392 Ok(None) 393 } 394 } 395 } 396 397 /// Ser/de to/from timestamps in microseconds 398 /// 399 /// Intended for use with `serde`'s `with` attribute. 400 /// 401 /// # Example: 402 /// 403 /// ```rust 404 /// # use chrono::{DateTime, Utc, NaiveDate}; 405 /// # use serde_derive::{Deserialize, Serialize}; 406 /// use chrono::serde::ts_microseconds; 407 /// #[derive(Deserialize, Serialize)] 408 /// struct S { 409 /// #[serde(with = "ts_microseconds")] 410 /// time: DateTime<Utc> 411 /// } 412 /// 413 /// let time = NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_micro_opt(02, 04, 59, 918355).unwrap().and_local_timezone(Utc).unwrap(); 414 /// let my_s = S { 415 /// time: time.clone(), 416 /// }; 417 /// 418 /// let as_string = serde_json::to_string(&my_s)?; 419 /// assert_eq!(as_string, r#"{"time":1526522699918355}"#); 420 /// let my_s: S = serde_json::from_str(&as_string)?; 421 /// assert_eq!(my_s.time, time); 422 /// # Ok::<(), serde_json::Error>(()) 423 /// ``` 424 pub mod ts_microseconds { 425 use core::fmt; 426 use serde::{de, ser}; 427 428 use super::{serde_from, MicroSecondsTimestampVisitor}; 429 use crate::offset::TimeZone; 430 use crate::{DateTime, Utc}; 431 432 /// Serialize a UTC datetime into an integer number of microseconds since the epoch 433 /// 434 /// Intended for use with `serde`s `serialize_with` attribute. 435 /// 436 /// # Example: 437 /// 438 /// ```rust 439 /// # use chrono::{DateTime, Utc, NaiveDate}; 440 /// # use serde_derive::Serialize; 441 /// use chrono::serde::ts_microseconds::serialize as to_micro_ts; 442 /// #[derive(Serialize)] 443 /// struct S { 444 /// #[serde(serialize_with = "to_micro_ts")] 445 /// time: DateTime<Utc> 446 /// } 447 /// 448 /// let my_s = S { 449 /// time: NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_micro_opt(02, 04, 59, 918355).unwrap().and_local_timezone(Utc).unwrap(), 450 /// }; 451 /// let as_string = serde_json::to_string(&my_s)?; 452 /// assert_eq!(as_string, r#"{"time":1526522699918355}"#); 453 /// # Ok::<(), serde_json::Error>(()) 454 /// ``` serialize<S>(dt: &DateTime<Utc>, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,455 pub fn serialize<S>(dt: &DateTime<Utc>, serializer: S) -> Result<S::Ok, S::Error> 456 where 457 S: ser::Serializer, 458 { 459 serializer.serialize_i64(dt.timestamp_micros()) 460 } 461 462 /// Deserialize a `DateTime` from a microsecond timestamp 463 /// 464 /// Intended for use with `serde`s `deserialize_with` attribute. 465 /// 466 /// # Example: 467 /// 468 /// ```rust 469 /// # use chrono::{DateTime, TimeZone, Utc}; 470 /// # use serde_derive::Deserialize; 471 /// use chrono::serde::ts_microseconds::deserialize as from_micro_ts; 472 /// #[derive(Debug, PartialEq, Deserialize)] 473 /// struct S { 474 /// #[serde(deserialize_with = "from_micro_ts")] 475 /// time: DateTime<Utc> 476 /// } 477 /// 478 /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355 }"#)?; 479 /// assert_eq!(my_s, S { time: Utc.timestamp_opt(1526522699, 918355000).unwrap() }); 480 /// 481 /// let my_s: S = serde_json::from_str(r#"{ "time": -1 }"#)?; 482 /// assert_eq!(my_s, S { time: Utc.timestamp_opt(-1, 999_999_000).unwrap() }); 483 /// # Ok::<(), serde_json::Error>(()) 484 /// ``` deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error> where D: de::Deserializer<'de>,485 pub fn deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error> 486 where 487 D: de::Deserializer<'de>, 488 { 489 d.deserialize_i64(MicroSecondsTimestampVisitor) 490 } 491 492 impl<'de> de::Visitor<'de> for MicroSecondsTimestampVisitor { 493 type Value = DateTime<Utc>; 494 expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result495 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 496 formatter.write_str("a unix timestamp in microseconds") 497 } 498 499 /// Deserialize a timestamp in milliseconds since the epoch visit_i64<E>(self, value: i64) -> Result<Self::Value, E> where E: de::Error,500 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E> 501 where 502 E: de::Error, 503 { 504 serde_from( 505 Utc.timestamp_opt( 506 value.div_euclid(1_000_000), 507 (value.rem_euclid(1_000_000) * 1_000) as u32, 508 ), 509 &value, 510 ) 511 } 512 513 /// Deserialize a timestamp in milliseconds since the epoch visit_u64<E>(self, value: u64) -> Result<Self::Value, E> where E: de::Error,514 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> 515 where 516 E: de::Error, 517 { 518 serde_from( 519 Utc.timestamp_opt((value / 1_000_000) as i64, ((value % 1_000_000) * 1_000) as u32), 520 &value, 521 ) 522 } 523 } 524 } 525 526 /// Ser/de to/from optional timestamps in microseconds 527 /// 528 /// Intended for use with `serde`'s `with` attribute. 529 /// 530 /// # Example: 531 /// 532 /// ```rust 533 /// # use chrono::{DateTime, Utc, NaiveDate}; 534 /// # use serde_derive::{Deserialize, Serialize}; 535 /// use chrono::serde::ts_microseconds_option; 536 /// #[derive(Deserialize, Serialize)] 537 /// struct S { 538 /// #[serde(with = "ts_microseconds_option")] 539 /// time: Option<DateTime<Utc>> 540 /// } 541 /// 542 /// let time = Some(NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_micro_opt(02, 04, 59, 918355).unwrap().and_local_timezone(Utc).unwrap()); 543 /// let my_s = S { 544 /// time: time.clone(), 545 /// }; 546 /// 547 /// let as_string = serde_json::to_string(&my_s)?; 548 /// assert_eq!(as_string, r#"{"time":1526522699918355}"#); 549 /// let my_s: S = serde_json::from_str(&as_string)?; 550 /// assert_eq!(my_s.time, time); 551 /// # Ok::<(), serde_json::Error>(()) 552 /// ``` 553 pub mod ts_microseconds_option { 554 use core::fmt; 555 use serde::{de, ser}; 556 557 use super::MicroSecondsTimestampVisitor; 558 use crate::{DateTime, Utc}; 559 560 /// Serialize a UTC datetime into an integer number of microseconds since the epoch or none 561 /// 562 /// Intended for use with `serde`s `serialize_with` attribute. 563 /// 564 /// # Example: 565 /// 566 /// ```rust 567 /// # use chrono::{DateTime, Utc, NaiveDate}; 568 /// # use serde_derive::Serialize; 569 /// use chrono::serde::ts_microseconds_option::serialize as to_micro_tsopt; 570 /// #[derive(Serialize)] 571 /// struct S { 572 /// #[serde(serialize_with = "to_micro_tsopt")] 573 /// time: Option<DateTime<Utc>> 574 /// } 575 /// 576 /// let my_s = S { 577 /// time: Some(NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_micro_opt(02, 04, 59, 918355).unwrap().and_local_timezone(Utc).unwrap()), 578 /// }; 579 /// let as_string = serde_json::to_string(&my_s)?; 580 /// assert_eq!(as_string, r#"{"time":1526522699918355}"#); 581 /// # Ok::<(), serde_json::Error>(()) 582 /// ``` serialize<S>(opt: &Option<DateTime<Utc>>, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,583 pub fn serialize<S>(opt: &Option<DateTime<Utc>>, serializer: S) -> Result<S::Ok, S::Error> 584 where 585 S: ser::Serializer, 586 { 587 match *opt { 588 Some(ref dt) => serializer.serialize_some(&dt.timestamp_micros()), 589 None => serializer.serialize_none(), 590 } 591 } 592 593 /// Deserialize a `DateTime` from a microsecond timestamp or none 594 /// 595 /// Intended for use with `serde`s `deserialize_with` attribute. 596 /// 597 /// # Example: 598 /// 599 /// ```rust 600 /// # use chrono::{DateTime, TimeZone, Utc}; 601 /// # use serde_derive::Deserialize; 602 /// use chrono::serde::ts_microseconds_option::deserialize as from_micro_tsopt; 603 /// #[derive(Debug, PartialEq, Deserialize)] 604 /// struct S { 605 /// #[serde(deserialize_with = "from_micro_tsopt")] 606 /// time: Option<DateTime<Utc>> 607 /// } 608 /// 609 /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355 }"#)?; 610 /// assert_eq!(my_s, S { time: Utc.timestamp_opt(1526522699, 918355000).single() }); 611 /// # Ok::<(), serde_json::Error>(()) 612 /// ``` deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error> where D: de::Deserializer<'de>,613 pub fn deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error> 614 where 615 D: de::Deserializer<'de>, 616 { 617 d.deserialize_option(OptionMicroSecondsTimestampVisitor) 618 } 619 620 struct OptionMicroSecondsTimestampVisitor; 621 622 impl<'de> de::Visitor<'de> for OptionMicroSecondsTimestampVisitor { 623 type Value = Option<DateTime<Utc>>; 624 expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result625 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 626 formatter.write_str("a unix timestamp in microseconds or none") 627 } 628 629 /// Deserialize a timestamp in microseconds since the epoch visit_some<D>(self, d: D) -> Result<Self::Value, D::Error> where D: de::Deserializer<'de>,630 fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error> 631 where 632 D: de::Deserializer<'de>, 633 { 634 d.deserialize_i64(MicroSecondsTimestampVisitor).map(Some) 635 } 636 637 /// Deserialize a timestamp in microseconds since the epoch visit_none<E>(self) -> Result<Self::Value, E> where E: de::Error,638 fn visit_none<E>(self) -> Result<Self::Value, E> 639 where 640 E: de::Error, 641 { 642 Ok(None) 643 } 644 645 /// Deserialize a timestamp in microseconds since the epoch visit_unit<E>(self) -> Result<Self::Value, E> where E: de::Error,646 fn visit_unit<E>(self) -> Result<Self::Value, E> 647 where 648 E: de::Error, 649 { 650 Ok(None) 651 } 652 } 653 } 654 655 /// Ser/de to/from timestamps in milliseconds 656 /// 657 /// Intended for use with `serde`s `with` attribute. 658 /// 659 /// # Example 660 /// 661 /// ```rust 662 /// # use chrono::{DateTime, Utc, NaiveDate}; 663 /// # use serde_derive::{Deserialize, Serialize}; 664 /// use chrono::serde::ts_milliseconds; 665 /// #[derive(Deserialize, Serialize)] 666 /// struct S { 667 /// #[serde(with = "ts_milliseconds")] 668 /// time: DateTime<Utc> 669 /// } 670 /// 671 /// let time = NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_milli_opt(02, 04, 59, 918).unwrap().and_local_timezone(Utc).unwrap(); 672 /// let my_s = S { 673 /// time: time.clone(), 674 /// }; 675 /// 676 /// let as_string = serde_json::to_string(&my_s)?; 677 /// assert_eq!(as_string, r#"{"time":1526522699918}"#); 678 /// let my_s: S = serde_json::from_str(&as_string)?; 679 /// assert_eq!(my_s.time, time); 680 /// # Ok::<(), serde_json::Error>(()) 681 /// ``` 682 pub mod ts_milliseconds { 683 use core::fmt; 684 use serde::{de, ser}; 685 686 use super::{serde_from, MilliSecondsTimestampVisitor}; 687 use crate::offset::TimeZone; 688 use crate::{DateTime, Utc}; 689 690 /// Serialize a UTC datetime into an integer number of milliseconds since the epoch 691 /// 692 /// Intended for use with `serde`s `serialize_with` attribute. 693 /// 694 /// # Example: 695 /// 696 /// ```rust 697 /// # use chrono::{DateTime, Utc, NaiveDate}; 698 /// # use serde_derive::Serialize; 699 /// use chrono::serde::ts_milliseconds::serialize as to_milli_ts; 700 /// #[derive(Serialize)] 701 /// struct S { 702 /// #[serde(serialize_with = "to_milli_ts")] 703 /// time: DateTime<Utc> 704 /// } 705 /// 706 /// let my_s = S { 707 /// time: NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_milli_opt(02, 04, 59, 918).unwrap().and_local_timezone(Utc).unwrap(), 708 /// }; 709 /// let as_string = serde_json::to_string(&my_s)?; 710 /// assert_eq!(as_string, r#"{"time":1526522699918}"#); 711 /// # Ok::<(), serde_json::Error>(()) 712 /// ``` serialize<S>(dt: &DateTime<Utc>, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,713 pub fn serialize<S>(dt: &DateTime<Utc>, serializer: S) -> Result<S::Ok, S::Error> 714 where 715 S: ser::Serializer, 716 { 717 serializer.serialize_i64(dt.timestamp_millis()) 718 } 719 720 /// Deserialize a `DateTime` from a millisecond timestamp 721 /// 722 /// Intended for use with `serde`s `deserialize_with` attribute. 723 /// 724 /// # Example: 725 /// 726 /// ```rust 727 /// # use chrono::{DateTime, TimeZone, Utc}; 728 /// # use serde_derive::Deserialize; 729 /// use chrono::serde::ts_milliseconds::deserialize as from_milli_ts; 730 /// #[derive(Debug, PartialEq, Deserialize)] 731 /// struct S { 732 /// #[serde(deserialize_with = "from_milli_ts")] 733 /// time: DateTime<Utc> 734 /// } 735 /// 736 /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918 }"#)?; 737 /// assert_eq!(my_s, S { time: Utc.timestamp_opt(1526522699, 918000000).unwrap() }); 738 /// 739 /// let my_s: S = serde_json::from_str(r#"{ "time": -1 }"#)?; 740 /// assert_eq!(my_s, S { time: Utc.timestamp_opt(-1, 999_000_000).unwrap() }); 741 /// # Ok::<(), serde_json::Error>(()) 742 /// ``` deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error> where D: de::Deserializer<'de>,743 pub fn deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error> 744 where 745 D: de::Deserializer<'de>, 746 { 747 d.deserialize_i64(MilliSecondsTimestampVisitor).map(|dt| dt.with_timezone(&Utc)) 748 } 749 750 impl<'de> de::Visitor<'de> for MilliSecondsTimestampVisitor { 751 type Value = DateTime<Utc>; 752 expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result753 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 754 formatter.write_str("a unix timestamp in milliseconds") 755 } 756 757 /// Deserialize a timestamp in milliseconds since the epoch visit_i64<E>(self, value: i64) -> Result<Self::Value, E> where E: de::Error,758 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E> 759 where 760 E: de::Error, 761 { 762 serde_from(Utc.timestamp_millis_opt(value), &value) 763 } 764 765 /// Deserialize a timestamp in milliseconds since the epoch visit_u64<E>(self, value: u64) -> Result<Self::Value, E> where E: de::Error,766 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> 767 where 768 E: de::Error, 769 { 770 serde_from( 771 Utc.timestamp_opt((value / 1000) as i64, ((value % 1000) * 1_000_000) as u32), 772 &value, 773 ) 774 } 775 } 776 } 777 778 /// Ser/de to/from optional timestamps in milliseconds 779 /// 780 /// Intended for use with `serde`s `with` attribute. 781 /// 782 /// # Example 783 /// 784 /// ```rust 785 /// # use chrono::{DateTime, Utc, NaiveDate}; 786 /// # use serde_derive::{Deserialize, Serialize}; 787 /// use chrono::serde::ts_milliseconds_option; 788 /// #[derive(Deserialize, Serialize)] 789 /// struct S { 790 /// #[serde(with = "ts_milliseconds_option")] 791 /// time: Option<DateTime<Utc>> 792 /// } 793 /// 794 /// let time = Some(NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_milli_opt(02, 04, 59, 918).unwrap().and_local_timezone(Utc).unwrap()); 795 /// let my_s = S { 796 /// time: time.clone(), 797 /// }; 798 /// 799 /// let as_string = serde_json::to_string(&my_s)?; 800 /// assert_eq!(as_string, r#"{"time":1526522699918}"#); 801 /// let my_s: S = serde_json::from_str(&as_string)?; 802 /// assert_eq!(my_s.time, time); 803 /// # Ok::<(), serde_json::Error>(()) 804 /// ``` 805 pub mod ts_milliseconds_option { 806 use core::fmt; 807 use serde::{de, ser}; 808 809 use super::MilliSecondsTimestampVisitor; 810 use crate::{DateTime, Utc}; 811 812 /// Serialize a UTC datetime into an integer number of milliseconds since the epoch or none 813 /// 814 /// Intended for use with `serde`s `serialize_with` attribute. 815 /// 816 /// # Example: 817 /// 818 /// ```rust 819 /// # use chrono::{DateTime, Utc, NaiveDate}; 820 /// # use serde_derive::Serialize; 821 /// use chrono::serde::ts_milliseconds_option::serialize as to_milli_tsopt; 822 /// #[derive(Serialize)] 823 /// struct S { 824 /// #[serde(serialize_with = "to_milli_tsopt")] 825 /// time: Option<DateTime<Utc>> 826 /// } 827 /// 828 /// let my_s = S { 829 /// time: Some(NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_milli_opt(02, 04, 59, 918).unwrap().and_local_timezone(Utc).unwrap()), 830 /// }; 831 /// let as_string = serde_json::to_string(&my_s)?; 832 /// assert_eq!(as_string, r#"{"time":1526522699918}"#); 833 /// # Ok::<(), serde_json::Error>(()) 834 /// ``` serialize<S>(opt: &Option<DateTime<Utc>>, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,835 pub fn serialize<S>(opt: &Option<DateTime<Utc>>, serializer: S) -> Result<S::Ok, S::Error> 836 where 837 S: ser::Serializer, 838 { 839 match *opt { 840 Some(ref dt) => serializer.serialize_some(&dt.timestamp_millis()), 841 None => serializer.serialize_none(), 842 } 843 } 844 845 /// Deserialize a `DateTime` from a millisecond timestamp or none 846 /// 847 /// Intended for use with `serde`s `deserialize_with` attribute. 848 /// 849 /// # Example: 850 /// 851 /// ```rust 852 /// # use chrono::{TimeZone, DateTime, Utc}; 853 /// # use serde_derive::Deserialize; 854 /// use chrono::serde::ts_milliseconds_option::deserialize as from_milli_tsopt; 855 /// 856 /// #[derive(Deserialize, PartialEq, Debug)] 857 /// #[serde(untagged)] 858 /// enum E<T> { 859 /// V(T), 860 /// } 861 /// 862 /// #[derive(Deserialize, PartialEq, Debug)] 863 /// struct S { 864 /// #[serde(default, deserialize_with = "from_milli_tsopt")] 865 /// time: Option<DateTime<Utc>> 866 /// } 867 /// 868 /// let my_s: E<S> = serde_json::from_str(r#"{ "time": 1526522699918 }"#)?; 869 /// assert_eq!(my_s, E::V(S { time: Some(Utc.timestamp_opt(1526522699, 918000000).unwrap()) })); 870 /// let s: E<S> = serde_json::from_str(r#"{ "time": null }"#)?; 871 /// assert_eq!(s, E::V(S { time: None })); 872 /// let t: E<S> = serde_json::from_str(r#"{}"#)?; 873 /// assert_eq!(t, E::V(S { time: None })); 874 /// # Ok::<(), serde_json::Error>(()) 875 /// ``` deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error> where D: de::Deserializer<'de>,876 pub fn deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error> 877 where 878 D: de::Deserializer<'de>, 879 { 880 d.deserialize_option(OptionMilliSecondsTimestampVisitor) 881 .map(|opt| opt.map(|dt| dt.with_timezone(&Utc))) 882 } 883 884 struct OptionMilliSecondsTimestampVisitor; 885 886 impl<'de> de::Visitor<'de> for OptionMilliSecondsTimestampVisitor { 887 type Value = Option<DateTime<Utc>>; 888 expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result889 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 890 formatter.write_str("a unix timestamp in milliseconds or none") 891 } 892 893 /// Deserialize a timestamp in milliseconds since the epoch visit_some<D>(self, d: D) -> Result<Self::Value, D::Error> where D: de::Deserializer<'de>,894 fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error> 895 where 896 D: de::Deserializer<'de>, 897 { 898 d.deserialize_i64(MilliSecondsTimestampVisitor).map(Some) 899 } 900 901 /// Deserialize a timestamp in milliseconds since the epoch visit_none<E>(self) -> Result<Self::Value, E> where E: de::Error,902 fn visit_none<E>(self) -> Result<Self::Value, E> 903 where 904 E: de::Error, 905 { 906 Ok(None) 907 } 908 909 /// Deserialize a timestamp in milliseconds since the epoch visit_unit<E>(self) -> Result<Self::Value, E> where E: de::Error,910 fn visit_unit<E>(self) -> Result<Self::Value, E> 911 where 912 E: de::Error, 913 { 914 Ok(None) 915 } 916 } 917 } 918 919 /// Ser/de to/from timestamps in seconds 920 /// 921 /// Intended for use with `serde`'s `with` attribute. 922 /// 923 /// # Example: 924 /// 925 /// ```rust 926 /// # use chrono::{TimeZone, DateTime, Utc}; 927 /// # use serde_derive::{Deserialize, Serialize}; 928 /// use chrono::serde::ts_seconds; 929 /// #[derive(Deserialize, Serialize)] 930 /// struct S { 931 /// #[serde(with = "ts_seconds")] 932 /// time: DateTime<Utc> 933 /// } 934 /// 935 /// let time = Utc.with_ymd_and_hms(2015, 5, 15, 10, 0, 0).unwrap(); 936 /// let my_s = S { 937 /// time: time.clone(), 938 /// }; 939 /// 940 /// let as_string = serde_json::to_string(&my_s)?; 941 /// assert_eq!(as_string, r#"{"time":1431684000}"#); 942 /// let my_s: S = serde_json::from_str(&as_string)?; 943 /// assert_eq!(my_s.time, time); 944 /// # Ok::<(), serde_json::Error>(()) 945 /// ``` 946 pub mod ts_seconds { 947 use core::fmt; 948 use serde::{de, ser}; 949 950 use super::{serde_from, SecondsTimestampVisitor}; 951 use crate::{DateTime, LocalResult, TimeZone, Utc}; 952 953 /// Serialize a UTC datetime into an integer number of seconds since the epoch 954 /// 955 /// Intended for use with `serde`s `serialize_with` attribute. 956 /// 957 /// # Example: 958 /// 959 /// ```rust 960 /// # use chrono::{TimeZone, DateTime, Utc}; 961 /// # use serde_derive::Serialize; 962 /// use chrono::serde::ts_seconds::serialize as to_ts; 963 /// #[derive(Serialize)] 964 /// struct S { 965 /// #[serde(serialize_with = "to_ts")] 966 /// time: DateTime<Utc> 967 /// } 968 /// 969 /// let my_s = S { 970 /// time: Utc.with_ymd_and_hms(2015, 5, 15, 10, 0, 0).unwrap(), 971 /// }; 972 /// let as_string = serde_json::to_string(&my_s)?; 973 /// assert_eq!(as_string, r#"{"time":1431684000}"#); 974 /// # Ok::<(), serde_json::Error>(()) 975 /// ``` serialize<S>(dt: &DateTime<Utc>, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,976 pub fn serialize<S>(dt: &DateTime<Utc>, serializer: S) -> Result<S::Ok, S::Error> 977 where 978 S: ser::Serializer, 979 { 980 serializer.serialize_i64(dt.timestamp()) 981 } 982 983 /// Deserialize a `DateTime` from a seconds timestamp 984 /// 985 /// Intended for use with `serde`s `deserialize_with` attribute. 986 /// 987 /// # Example: 988 /// 989 /// ```rust 990 /// # use chrono::{DateTime, TimeZone, Utc}; 991 /// # use serde_derive::Deserialize; 992 /// use chrono::serde::ts_seconds::deserialize as from_ts; 993 /// #[derive(Debug, PartialEq, Deserialize)] 994 /// struct S { 995 /// #[serde(deserialize_with = "from_ts")] 996 /// time: DateTime<Utc> 997 /// } 998 /// 999 /// let my_s: S = serde_json::from_str(r#"{ "time": 1431684000 }"#)?; 1000 /// assert_eq!(my_s, S { time: Utc.timestamp_opt(1431684000, 0).unwrap() }); 1001 /// # Ok::<(), serde_json::Error>(()) 1002 /// ``` deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error> where D: de::Deserializer<'de>,1003 pub fn deserialize<'de, D>(d: D) -> Result<DateTime<Utc>, D::Error> 1004 where 1005 D: de::Deserializer<'de>, 1006 { 1007 d.deserialize_i64(SecondsTimestampVisitor) 1008 } 1009 1010 impl<'de> de::Visitor<'de> for SecondsTimestampVisitor { 1011 type Value = DateTime<Utc>; 1012 expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result1013 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 1014 formatter.write_str("a unix timestamp in seconds") 1015 } 1016 1017 /// Deserialize a timestamp in seconds since the epoch visit_i64<E>(self, value: i64) -> Result<Self::Value, E> where E: de::Error,1018 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E> 1019 where 1020 E: de::Error, 1021 { 1022 serde_from(Utc.timestamp_opt(value, 0), &value) 1023 } 1024 1025 /// Deserialize a timestamp in seconds since the epoch visit_u64<E>(self, value: u64) -> Result<Self::Value, E> where E: de::Error,1026 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> 1027 where 1028 E: de::Error, 1029 { 1030 serde_from( 1031 if value > i64::MAX as u64 { 1032 LocalResult::None 1033 } else { 1034 Utc.timestamp_opt(value as i64, 0) 1035 }, 1036 &value, 1037 ) 1038 } 1039 } 1040 } 1041 1042 /// Ser/de to/from optional timestamps in seconds 1043 /// 1044 /// Intended for use with `serde`'s `with` attribute. 1045 /// 1046 /// # Example: 1047 /// 1048 /// ```rust 1049 /// # use chrono::{TimeZone, DateTime, Utc}; 1050 /// # use serde_derive::{Deserialize, Serialize}; 1051 /// use chrono::serde::ts_seconds_option; 1052 /// #[derive(Deserialize, Serialize)] 1053 /// struct S { 1054 /// #[serde(with = "ts_seconds_option")] 1055 /// time: Option<DateTime<Utc>> 1056 /// } 1057 /// 1058 /// let time = Some(Utc.with_ymd_and_hms(2015, 5, 15, 10, 0, 0).unwrap()); 1059 /// let my_s = S { 1060 /// time: time.clone(), 1061 /// }; 1062 /// 1063 /// let as_string = serde_json::to_string(&my_s)?; 1064 /// assert_eq!(as_string, r#"{"time":1431684000}"#); 1065 /// let my_s: S = serde_json::from_str(&as_string)?; 1066 /// assert_eq!(my_s.time, time); 1067 /// # Ok::<(), serde_json::Error>(()) 1068 /// ``` 1069 pub mod ts_seconds_option { 1070 use core::fmt; 1071 use serde::{de, ser}; 1072 1073 use super::SecondsTimestampVisitor; 1074 use crate::{DateTime, Utc}; 1075 1076 /// Serialize a UTC datetime into an integer number of seconds since the epoch or none 1077 /// 1078 /// Intended for use with `serde`s `serialize_with` attribute. 1079 /// 1080 /// # Example: 1081 /// 1082 /// ```rust 1083 /// # use chrono::{TimeZone, DateTime, Utc}; 1084 /// # use serde_derive::Serialize; 1085 /// use chrono::serde::ts_seconds_option::serialize as to_tsopt; 1086 /// #[derive(Serialize)] 1087 /// struct S { 1088 /// #[serde(serialize_with = "to_tsopt")] 1089 /// time: Option<DateTime<Utc>> 1090 /// } 1091 /// 1092 /// let my_s = S { 1093 /// time: Some(Utc.with_ymd_and_hms(2015, 5, 15, 10, 0, 0).unwrap()), 1094 /// }; 1095 /// let as_string = serde_json::to_string(&my_s)?; 1096 /// assert_eq!(as_string, r#"{"time":1431684000}"#); 1097 /// # Ok::<(), serde_json::Error>(()) 1098 /// ``` serialize<S>(opt: &Option<DateTime<Utc>>, serializer: S) -> Result<S::Ok, S::Error> where S: ser::Serializer,1099 pub fn serialize<S>(opt: &Option<DateTime<Utc>>, serializer: S) -> Result<S::Ok, S::Error> 1100 where 1101 S: ser::Serializer, 1102 { 1103 match *opt { 1104 Some(ref dt) => serializer.serialize_some(&dt.timestamp()), 1105 None => serializer.serialize_none(), 1106 } 1107 } 1108 1109 /// Deserialize a `DateTime` from a seconds timestamp or none 1110 /// 1111 /// Intended for use with `serde`s `deserialize_with` attribute. 1112 /// 1113 /// # Example: 1114 /// 1115 /// ```rust 1116 /// # use chrono::{DateTime, TimeZone, Utc}; 1117 /// # use serde_derive::Deserialize; 1118 /// use chrono::serde::ts_seconds_option::deserialize as from_tsopt; 1119 /// #[derive(Debug, PartialEq, Deserialize)] 1120 /// struct S { 1121 /// #[serde(deserialize_with = "from_tsopt")] 1122 /// time: Option<DateTime<Utc>> 1123 /// } 1124 /// 1125 /// let my_s: S = serde_json::from_str(r#"{ "time": 1431684000 }"#)?; 1126 /// assert_eq!(my_s, S { time: Utc.timestamp_opt(1431684000, 0).single() }); 1127 /// # Ok::<(), serde_json::Error>(()) 1128 /// ``` deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error> where D: de::Deserializer<'de>,1129 pub fn deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error> 1130 where 1131 D: de::Deserializer<'de>, 1132 { 1133 d.deserialize_option(OptionSecondsTimestampVisitor) 1134 } 1135 1136 struct OptionSecondsTimestampVisitor; 1137 1138 impl<'de> de::Visitor<'de> for OptionSecondsTimestampVisitor { 1139 type Value = Option<DateTime<Utc>>; 1140 expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result1141 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 1142 formatter.write_str("a unix timestamp in seconds or none") 1143 } 1144 1145 /// Deserialize a timestamp in seconds since the epoch visit_some<D>(self, d: D) -> Result<Self::Value, D::Error> where D: de::Deserializer<'de>,1146 fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error> 1147 where 1148 D: de::Deserializer<'de>, 1149 { 1150 d.deserialize_i64(SecondsTimestampVisitor).map(Some) 1151 } 1152 1153 /// Deserialize a timestamp in seconds since the epoch visit_none<E>(self) -> Result<Self::Value, E> where E: de::Error,1154 fn visit_none<E>(self) -> Result<Self::Value, E> 1155 where 1156 E: de::Error, 1157 { 1158 Ok(None) 1159 } 1160 1161 /// Deserialize a timestamp in seconds since the epoch visit_unit<E>(self) -> Result<Self::Value, E> where E: de::Error,1162 fn visit_unit<E>(self) -> Result<Self::Value, E> 1163 where 1164 E: de::Error, 1165 { 1166 Ok(None) 1167 } 1168 } 1169 } 1170 1171 #[cfg(test)] 1172 mod tests { 1173 #[cfg(feature = "clock")] 1174 use crate::datetime::test_decodable_json; 1175 use crate::datetime::test_encodable_json; 1176 use crate::{DateTime, FixedOffset, TimeZone, Utc}; 1177 use core::fmt; 1178 1179 #[test] test_serde_serialize()1180 fn test_serde_serialize() { 1181 test_encodable_json(serde_json::to_string, serde_json::to_string); 1182 } 1183 1184 #[cfg(feature = "clock")] 1185 #[test] test_serde_deserialize()1186 fn test_serde_deserialize() { 1187 test_decodable_json( 1188 |input| serde_json::from_str(input), 1189 |input| serde_json::from_str(input), 1190 |input| serde_json::from_str(input), 1191 ); 1192 } 1193 1194 #[test] test_serde_bincode()1195 fn test_serde_bincode() { 1196 // Bincode is relevant to test separately from JSON because 1197 // it is not self-describing. 1198 use bincode::{deserialize, serialize}; 1199 1200 let dt = Utc.with_ymd_and_hms(2014, 7, 24, 12, 34, 6).unwrap(); 1201 let encoded = serialize(&dt).unwrap(); 1202 let decoded: DateTime<Utc> = deserialize(&encoded).unwrap(); 1203 assert_eq!(dt, decoded); 1204 assert_eq!(dt.offset(), decoded.offset()); 1205 } 1206 1207 #[test] test_serde_no_offset_debug()1208 fn test_serde_no_offset_debug() { 1209 use crate::{LocalResult, NaiveDate, NaiveDateTime, Offset}; 1210 use core::fmt::Debug; 1211 1212 #[derive(Clone)] 1213 struct TestTimeZone; 1214 impl Debug for TestTimeZone { 1215 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 1216 write!(f, "TEST") 1217 } 1218 } 1219 impl TimeZone for TestTimeZone { 1220 type Offset = TestTimeZone; 1221 fn from_offset(_state: &TestTimeZone) -> TestTimeZone { 1222 TestTimeZone 1223 } 1224 fn offset_from_local_date(&self, _local: &NaiveDate) -> LocalResult<TestTimeZone> { 1225 LocalResult::Single(TestTimeZone) 1226 } 1227 fn offset_from_local_datetime( 1228 &self, 1229 _local: &NaiveDateTime, 1230 ) -> LocalResult<TestTimeZone> { 1231 LocalResult::Single(TestTimeZone) 1232 } 1233 fn offset_from_utc_date(&self, _utc: &NaiveDate) -> TestTimeZone { 1234 TestTimeZone 1235 } 1236 fn offset_from_utc_datetime(&self, _utc: &NaiveDateTime) -> TestTimeZone { 1237 TestTimeZone 1238 } 1239 } 1240 impl Offset for TestTimeZone { 1241 fn fix(&self) -> FixedOffset { 1242 FixedOffset::east_opt(15 * 60 * 60).unwrap() 1243 } 1244 } 1245 1246 let tz = TestTimeZone; 1247 assert_eq!(format!("{:?}", &tz), "TEST"); 1248 1249 let dt = tz.with_ymd_and_hms(2023, 4, 24, 21, 10, 33).unwrap(); 1250 let encoded = serde_json::to_string(&dt).unwrap(); 1251 dbg!(&encoded); 1252 let decoded: DateTime<FixedOffset> = serde_json::from_str(&encoded).unwrap(); 1253 assert_eq!(dt, decoded); 1254 assert_eq!(dt.offset().fix(), *decoded.offset()); 1255 } 1256 } 1257