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