1use num_traits::ToPrimitive;
8use oldtime::Duration as OldDuration;
9
10use {Datelike, Timelike};
11use Weekday;
12use div::div_rem;
13use offset::{TimeZone, Offset, LocalResult, FixedOffset};
14use naive::{NaiveDate, NaiveTime, NaiveDateTime};
15use DateTime;
16use super::{ParseResult, OUT_OF_RANGE, IMPOSSIBLE, NOT_ENOUGH};
17
18#[allow(missing_copy_implementations)]
26#[derive(Clone, PartialEq, Debug)]
27pub struct Parsed {
28 pub year: Option<i32>,
33
34 pub year_div_100: Option<i32>,
40
41 pub year_mod_100: Option<i32>,
43
44 pub isoyear: Option<i32>,
49
50 pub isoyear_div_100: Option<i32>,
57
58 pub isoyear_mod_100: Option<i32>,
61
62 pub month: Option<u32>,
64
65 pub week_from_sun: Option<u32>,
68
69 pub week_from_mon: Option<u32>,
72
73 pub isoweek: Option<u32>,
76
77 pub weekday: Option<Weekday>,
79
80 pub ordinal: Option<u32>,
82
83 pub day: Option<u32>,
85
86 pub hour_div_12: Option<u32>,
88
89 pub hour_mod_12: Option<u32>,
91
92 pub minute: Option<u32>,
94
95 pub second: Option<u32>,
97
98 pub nanosecond: Option<u32>,
100
101 pub timestamp: Option<i64>,
105
106 pub offset: Option<i32>,
108
109 _dummy: (),
111}
112
113#[inline]
116fn set_if_consistent<T: PartialEq>(old: &mut Option<T>, new: T) -> ParseResult<()> {
117 if let Some(ref old) = *old {
118 if *old == new {Ok(())} else {Err(IMPOSSIBLE)}
119 } else {
120 *old = Some(new);
121 Ok(())
122 }
123}
124
125impl Default for Parsed {
126 fn default() -> Parsed {
127 Parsed {
128 year: None, year_div_100: None, year_mod_100: None, isoyear: None,
129 isoyear_div_100: None, isoyear_mod_100: None, month: None,
130 week_from_sun: None, week_from_mon: None, isoweek: None, weekday: None,
131 ordinal: None, day: None, hour_div_12: None, hour_mod_12: None, minute: None,
132 second: None, nanosecond: None, timestamp: None, offset: None,
133 _dummy: (),
134 }
135 }
136}
137
138impl Parsed {
139 pub fn new() -> Parsed {
141 Parsed::default()
142 }
143
144 #[inline]
146 pub fn set_year(&mut self, value: i64) -> ParseResult<()> {
147 set_if_consistent(&mut self.year, value.to_i32().ok_or(OUT_OF_RANGE)?)
148 }
149
150 #[inline]
152 pub fn set_year_div_100(&mut self, value: i64) -> ParseResult<()> {
153 if value < 0 { return Err(OUT_OF_RANGE); }
154 set_if_consistent(&mut self.year_div_100, value.to_i32().ok_or(OUT_OF_RANGE)?)
155 }
156
157 #[inline]
159 pub fn set_year_mod_100(&mut self, value: i64) -> ParseResult<()> {
160 if value < 0 { return Err(OUT_OF_RANGE); }
161 set_if_consistent(&mut self.year_mod_100, value.to_i32().ok_or(OUT_OF_RANGE)?)
162 }
163
164 #[inline]
166 pub fn set_isoyear(&mut self, value: i64) -> ParseResult<()> {
167 set_if_consistent(&mut self.isoyear, value.to_i32().ok_or(OUT_OF_RANGE)?)
168 }
169
170 #[inline]
172 pub fn set_isoyear_div_100(&mut self, value: i64) -> ParseResult<()> {
173 if value < 0 { return Err(OUT_OF_RANGE); }
174 set_if_consistent(&mut self.isoyear_div_100, value.to_i32().ok_or(OUT_OF_RANGE)?)
175 }
176
177 #[inline]
179 pub fn set_isoyear_mod_100(&mut self, value: i64) -> ParseResult<()> {
180 if value < 0 { return Err(OUT_OF_RANGE); }
181 set_if_consistent(&mut self.isoyear_mod_100, value.to_i32().ok_or(OUT_OF_RANGE)?)
182 }
183
184 #[inline]
186 pub fn set_month(&mut self, value: i64) -> ParseResult<()> {
187 set_if_consistent(&mut self.month, value.to_u32().ok_or(OUT_OF_RANGE)?)
188 }
189
190 #[inline]
192 pub fn set_week_from_sun(&mut self, value: i64) -> ParseResult<()> {
193 set_if_consistent(&mut self.week_from_sun, value.to_u32().ok_or(OUT_OF_RANGE)?)
194 }
195
196 #[inline]
198 pub fn set_week_from_mon(&mut self, value: i64) -> ParseResult<()> {
199 set_if_consistent(&mut self.week_from_mon, value.to_u32().ok_or(OUT_OF_RANGE)?)
200 }
201
202 #[inline]
204 pub fn set_isoweek(&mut self, value: i64) -> ParseResult<()> {
205 set_if_consistent(&mut self.isoweek, value.to_u32().ok_or(OUT_OF_RANGE)?)
206 }
207
208 #[inline]
210 pub fn set_weekday(&mut self, value: Weekday) -> ParseResult<()> {
211 set_if_consistent(&mut self.weekday, value)
212 }
213
214 #[inline]
216 pub fn set_ordinal(&mut self, value: i64) -> ParseResult<()> {
217 set_if_consistent(&mut self.ordinal, value.to_u32().ok_or(OUT_OF_RANGE)?)
218 }
219
220 #[inline]
222 pub fn set_day(&mut self, value: i64) -> ParseResult<()> {
223 set_if_consistent(&mut self.day, value.to_u32().ok_or(OUT_OF_RANGE)?)
224 }
225
226 #[inline]
229 pub fn set_ampm(&mut self, value: bool) -> ParseResult<()> {
230 set_if_consistent(&mut self.hour_div_12, if value {1} else {0})
231 }
232
233 #[inline]
236 pub fn set_hour12(&mut self, value: i64) -> ParseResult<()> {
237 if value < 1 || value > 12 { return Err(OUT_OF_RANGE); }
238 set_if_consistent(&mut self.hour_mod_12, value as u32 % 12)
239 }
240
241 #[inline]
244 pub fn set_hour(&mut self, value: i64) -> ParseResult<()> {
245 let v = value.to_u32().ok_or(OUT_OF_RANGE)?;
246 set_if_consistent(&mut self.hour_div_12, v / 12)?;
247 set_if_consistent(&mut self.hour_mod_12, v % 12)?;
248 Ok(())
249 }
250
251 #[inline]
253 pub fn set_minute(&mut self, value: i64) -> ParseResult<()> {
254 set_if_consistent(&mut self.minute, value.to_u32().ok_or(OUT_OF_RANGE)?)
255 }
256
257 #[inline]
259 pub fn set_second(&mut self, value: i64) -> ParseResult<()> {
260 set_if_consistent(&mut self.second, value.to_u32().ok_or(OUT_OF_RANGE)?)
261 }
262
263 #[inline]
265 pub fn set_nanosecond(&mut self, value: i64) -> ParseResult<()> {
266 set_if_consistent(&mut self.nanosecond, value.to_u32().ok_or(OUT_OF_RANGE)?)
267 }
268
269 #[inline]
271 pub fn set_timestamp(&mut self, value: i64) -> ParseResult<()> {
272 set_if_consistent(&mut self.timestamp, value)
273 }
274
275 #[inline]
277 pub fn set_offset(&mut self, value: i64) -> ParseResult<()> {
278 set_if_consistent(&mut self.offset, value.to_i32().ok_or(OUT_OF_RANGE)?)
279 }
280
281 pub fn to_naive_date(&self) -> ParseResult<NaiveDate> {
293 fn resolve_year(y: Option<i32>, q: Option<i32>,
294 r: Option<i32>) -> ParseResult<Option<i32>> {
295 match (y, q, r) {
296 (y, None, None) => Ok(y),
299
300 (Some(y), q, r @ Some(0...99)) | (Some(y), q, r @ None) => {
305 if y < 0 { return Err(OUT_OF_RANGE); }
306 let (q_, r_) = div_rem(y, 100);
307 if q.unwrap_or(q_) == q_ && r.unwrap_or(r_) == r_ {
308 Ok(Some(y))
309 } else {
310 Err(IMPOSSIBLE)
311 }
312 },
313
314 (None, Some(q), Some(r @ 0...99)) => {
317 if q < 0 { return Err(OUT_OF_RANGE); }
318 let y = q.checked_mul(100).and_then(|v| v.checked_add(r));
319 Ok(Some(y.ok_or(OUT_OF_RANGE)?))
320 },
321
322 (None, None, Some(r @ 0...99)) => Ok(Some(r + if r < 70 {2000} else {1900})),
325
326 (None, Some(_), None) => Err(NOT_ENOUGH),
328 (_, _, Some(_)) => Err(OUT_OF_RANGE),
329 }
330 }
331
332 let given_year =
333 resolve_year(self.year, self.year_div_100, self.year_mod_100)?;
334 let given_isoyear =
335 resolve_year(self.isoyear, self.isoyear_div_100, self.isoyear_mod_100)?;
336
337 let verify_ymd = |date: NaiveDate| {
339 let year = date.year();
340 let (year_div_100, year_mod_100) = if year >= 0 {
341 let (q, r) = div_rem(year, 100);
342 (Some(q), Some(r))
343 } else {
344 (None, None) };
346 let month = date.month();
347 let day = date.day();
348 (self.year.unwrap_or(year) == year &&
349 self.year_div_100.or(year_div_100) == year_div_100 &&
350 self.year_mod_100.or(year_mod_100) == year_mod_100 &&
351 self.month.unwrap_or(month) == month &&
352 self.day.unwrap_or(day) == day)
353 };
354
355 let verify_isoweekdate = |date: NaiveDate| {
357 let week = date.iso_week();
358 let isoyear = week.year();
359 let isoweek = week.week();
360 let weekday = date.weekday();
361 let (isoyear_div_100, isoyear_mod_100) = if isoyear >= 0 {
362 let (q, r) = div_rem(isoyear, 100);
363 (Some(q), Some(r))
364 } else {
365 (None, None) };
367 (self.isoyear.unwrap_or(isoyear) == isoyear &&
368 self.isoyear_div_100.or(isoyear_div_100) == isoyear_div_100 &&
369 self.isoyear_mod_100.or(isoyear_mod_100) == isoyear_mod_100 &&
370 self.isoweek.unwrap_or(isoweek) == isoweek &&
371 self.weekday.unwrap_or(weekday) == weekday)
372 };
373
374 let verify_ordinal = |date: NaiveDate| {
376 let ordinal = date.ordinal();
377 let weekday = date.weekday();
378 let week_from_sun = (ordinal as i32 - weekday.num_days_from_sunday() as i32 + 7) / 7;
379 let week_from_mon = (ordinal as i32 - weekday.num_days_from_monday() as i32 + 7) / 7;
380 (self.ordinal.unwrap_or(ordinal) == ordinal &&
381 self.week_from_sun.map_or(week_from_sun, |v| v as i32) == week_from_sun &&
382 self.week_from_mon.map_or(week_from_mon, |v| v as i32) == week_from_mon)
383 };
384
385 let (verified, parsed_date) = match (given_year, given_isoyear, self) {
389 (Some(year), _, &Parsed { month: Some(month), day: Some(day), .. }) => {
390 let date = NaiveDate::from_ymd_opt(year, month, day).ok_or(OUT_OF_RANGE)?;
392 (verify_isoweekdate(date) && verify_ordinal(date), date)
393 },
394
395 (Some(year), _, &Parsed { ordinal: Some(ordinal), .. }) => {
396 let date = NaiveDate::from_yo_opt(year, ordinal).ok_or(OUT_OF_RANGE)?;
398 (verify_ymd(date) && verify_isoweekdate(date) && verify_ordinal(date), date)
399 },
400
401 (Some(year), _, &Parsed { week_from_sun: Some(week_from_sun),
402 weekday: Some(weekday), .. }) => {
403 let newyear = NaiveDate::from_yo_opt(year, 1).ok_or(OUT_OF_RANGE)?;
405 let firstweek = match newyear.weekday() {
406 Weekday::Sun => 0,
407 Weekday::Mon => 6,
408 Weekday::Tue => 5,
409 Weekday::Wed => 4,
410 Weekday::Thu => 3,
411 Weekday::Fri => 2,
412 Weekday::Sat => 1,
413 };
414
415 if week_from_sun > 53 { return Err(OUT_OF_RANGE); } let ndays = firstweek + (week_from_sun as i32 - 1) * 7 +
418 weekday.num_days_from_sunday() as i32;
419 let date = newyear.checked_add_signed(OldDuration::days(i64::from(ndays)))
420 .ok_or(OUT_OF_RANGE)?;
421 if date.year() != year { return Err(OUT_OF_RANGE); } (verify_ymd(date) && verify_isoweekdate(date) && verify_ordinal(date), date)
424 },
425
426 (Some(year), _, &Parsed { week_from_mon: Some(week_from_mon),
427 weekday: Some(weekday), .. }) => {
428 let newyear = NaiveDate::from_yo_opt(year, 1).ok_or(OUT_OF_RANGE)?;
430 let firstweek = match newyear.weekday() {
431 Weekday::Sun => 1,
432 Weekday::Mon => 0,
433 Weekday::Tue => 6,
434 Weekday::Wed => 5,
435 Weekday::Thu => 4,
436 Weekday::Fri => 3,
437 Weekday::Sat => 2,
438 };
439
440 if week_from_mon > 53 { return Err(OUT_OF_RANGE); } let ndays = firstweek + (week_from_mon as i32 - 1) * 7 +
443 weekday.num_days_from_monday() as i32;
444 let date = newyear.checked_add_signed(OldDuration::days(i64::from(ndays)))
445 .ok_or(OUT_OF_RANGE)?;
446 if date.year() != year { return Err(OUT_OF_RANGE); } (verify_ymd(date) && verify_isoweekdate(date) && verify_ordinal(date), date)
449 },
450
451 (_, Some(isoyear), &Parsed { isoweek: Some(isoweek), weekday: Some(weekday), .. }) => {
452 let date = NaiveDate::from_isoywd_opt(isoyear, isoweek, weekday);
454 let date = date.ok_or(OUT_OF_RANGE)?;
455 (verify_ymd(date) && verify_ordinal(date), date)
456 },
457
458 (_, _, _) => return Err(NOT_ENOUGH)
459 };
460
461 if verified {
462 Ok(parsed_date)
463 } else {
464 Err(IMPOSSIBLE)
465 }
466 }
467
468 pub fn to_naive_time(&self) -> ParseResult<NaiveTime> {
478 let hour_div_12 = match self.hour_div_12 {
479 Some(v @ 0...1) => v,
480 Some(_) => return Err(OUT_OF_RANGE),
481 None => return Err(NOT_ENOUGH),
482 };
483 let hour_mod_12 = match self.hour_mod_12 {
484 Some(v @ 0...11) => v,
485 Some(_) => return Err(OUT_OF_RANGE),
486 None => return Err(NOT_ENOUGH),
487 };
488 let hour = hour_div_12 * 12 + hour_mod_12;
489
490 let minute = match self.minute {
491 Some(v @ 0...59) => v,
492 Some(_) => return Err(OUT_OF_RANGE),
493 None => return Err(NOT_ENOUGH),
494 };
495
496 let (second, mut nano) = match self.second.unwrap_or(0) {
498 v @ 0...59 => (v, 0),
499 60 => (59, 1_000_000_000),
500 _ => return Err(OUT_OF_RANGE),
501 };
502 nano += match self.nanosecond {
503 Some(v @ 0...999_999_999) if self.second.is_some() => v,
504 Some(0...999_999_999) => return Err(NOT_ENOUGH), Some(_) => return Err(OUT_OF_RANGE),
506 None => 0,
507 };
508
509 NaiveTime::from_hms_nano_opt(hour, minute, second, nano).ok_or(OUT_OF_RANGE)
510 }
511
512 pub fn to_naive_datetime_with_offset(&self, offset: i32) -> ParseResult<NaiveDateTime> {
520 let date = self.to_naive_date();
521 let time = self.to_naive_time();
522 if let (Ok(date), Ok(time)) = (date, time) {
523 let datetime = date.and_time(time);
524
525 let timestamp = datetime.timestamp() - i64::from(offset);
528 if let Some(given_timestamp) = self.timestamp {
529 if given_timestamp != timestamp &&
531 !(datetime.nanosecond() >= 1_000_000_000 && given_timestamp == timestamp + 1) {
532 return Err(IMPOSSIBLE);
533 }
534 }
535
536 Ok(datetime)
537 } else if let Some(timestamp) = self.timestamp {
538 use super::ParseError as PE;
539 use super::ParseErrorKind::{OutOfRange, Impossible};
540
541 match (date, time) {
544 (Err(PE(OutOfRange)), _) | (_, Err(PE(OutOfRange))) => return Err(OUT_OF_RANGE),
545 (Err(PE(Impossible)), _) | (_, Err(PE(Impossible))) => return Err(IMPOSSIBLE),
546 (_, _) => {} }
548
549 let ts = timestamp.checked_add(i64::from(offset)).ok_or(OUT_OF_RANGE)?;
551 let datetime = NaiveDateTime::from_timestamp_opt(ts, 0);
552 let mut datetime = datetime.ok_or(OUT_OF_RANGE)?;
553
554 let mut parsed = self.clone();
557 if parsed.second == Some(60) {
558 match datetime.second() {
560 59 => {}
562 0 => { datetime -= OldDuration::seconds(1); }
564 _ => return Err(IMPOSSIBLE)
566 }
567 } else {
569 parsed.set_second(i64::from(datetime.second()))?;
570 }
571 parsed.set_year (i64::from(datetime.year()))?;
572 parsed.set_ordinal(i64::from(datetime.ordinal()))?; parsed.set_hour (i64::from(datetime.hour()))?;
574 parsed.set_minute (i64::from(datetime.minute()))?;
575
576 let date = parsed.to_naive_date()?;
578 let time = parsed.to_naive_time()?;
579 Ok(date.and_time(time))
580 } else {
581 date?;
583 time?;
584 unreachable!()
585 }
586 }
587
588 pub fn to_fixed_offset(&self) -> ParseResult<FixedOffset> {
590 self.offset.and_then(FixedOffset::east_opt).ok_or(OUT_OF_RANGE)
591 }
592
593 pub fn to_datetime(&self) -> ParseResult<DateTime<FixedOffset>> {
600 let offset = self.offset.ok_or(NOT_ENOUGH)?;
601 let datetime = self.to_naive_datetime_with_offset(offset)?;
602 let offset = FixedOffset::east_opt(offset).ok_or(OUT_OF_RANGE)?;
603 match offset.from_local_datetime(&datetime) {
604 LocalResult::None => Err(IMPOSSIBLE),
605 LocalResult::Single(t) => Ok(t),
606 LocalResult::Ambiguous(..) => Err(NOT_ENOUGH),
607 }
608 }
609
610 pub fn to_datetime_with_timezone<Tz: TimeZone>(&self, tz: &Tz) -> ParseResult<DateTime<Tz>> {
620 let mut guessed_offset = 0;
622 if let Some(timestamp) = self.timestamp {
623 let nanosecond = self.nanosecond.unwrap_or(0);
626 let dt = NaiveDateTime::from_timestamp_opt(timestamp, nanosecond);
627 let dt = dt.ok_or(OUT_OF_RANGE)?;
628 guessed_offset = tz.offset_from_utc_datetime(&dt).fix().local_minus_utc();
629 }
630
631 let check_offset = |dt: &DateTime<Tz>| {
633 if let Some(offset) = self.offset {
634 dt.offset().fix().local_minus_utc() == offset
635 } else {
636 true
637 }
638 };
639
640 let datetime = self.to_naive_datetime_with_offset(guessed_offset)?;
643 match tz.from_local_datetime(&datetime) {
644 LocalResult::None => Err(IMPOSSIBLE),
645 LocalResult::Single(t) => if check_offset(&t) {Ok(t)} else {Err(IMPOSSIBLE)},
646 LocalResult::Ambiguous(min, max) => {
647 match (check_offset(&min), check_offset(&max)) {
649 (false, false) => Err(IMPOSSIBLE),
650 (false, true) => Ok(max),
651 (true, false) => Ok(min),
652 (true, true) => Err(NOT_ENOUGH),
653 }
654 }
655 }
656 }
657}
658
659#[cfg(test)]
660mod tests {
661 use super::Parsed;
662 use super::super::{OUT_OF_RANGE, IMPOSSIBLE, NOT_ENOUGH};
663 use Datelike;
664 use Weekday::*;
665 use naive::{MIN_DATE, MAX_DATE, NaiveDate, NaiveTime};
666 use offset::{TimeZone, Utc, FixedOffset};
667
668 #[test]
669 fn test_parsed_set_fields() {
670 let mut p = Parsed::new();
672 assert_eq!(p.set_year(1987), Ok(()));
673 assert_eq!(p.set_year(1986), Err(IMPOSSIBLE));
674 assert_eq!(p.set_year(1988), Err(IMPOSSIBLE));
675 assert_eq!(p.set_year(1987), Ok(()));
676 assert_eq!(p.set_year_div_100(20), Ok(())); assert_eq!(p.set_year_div_100(21), Err(IMPOSSIBLE));
678 assert_eq!(p.set_year_div_100(19), Err(IMPOSSIBLE));
679 assert_eq!(p.set_year_mod_100(37), Ok(())); assert_eq!(p.set_year_mod_100(38), Err(IMPOSSIBLE));
681 assert_eq!(p.set_year_mod_100(36), Err(IMPOSSIBLE));
682
683 let mut p = Parsed::new();
684 assert_eq!(p.set_year(0), Ok(()));
685 assert_eq!(p.set_year_div_100(0), Ok(()));
686 assert_eq!(p.set_year_mod_100(0), Ok(()));
687
688 let mut p = Parsed::new();
689 assert_eq!(p.set_year_div_100(-1), Err(OUT_OF_RANGE));
690 assert_eq!(p.set_year_mod_100(-1), Err(OUT_OF_RANGE));
691 assert_eq!(p.set_year(-1), Ok(()));
692 assert_eq!(p.set_year(-2), Err(IMPOSSIBLE));
693 assert_eq!(p.set_year(0), Err(IMPOSSIBLE));
694
695 let mut p = Parsed::new();
696 assert_eq!(p.set_year_div_100(0x1_0000_0008), Err(OUT_OF_RANGE));
697 assert_eq!(p.set_year_div_100(8), Ok(()));
698 assert_eq!(p.set_year_div_100(0x1_0000_0008), Err(OUT_OF_RANGE));
699
700 let mut p = Parsed::new();
702 assert_eq!(p.set_month(7), Ok(()));
703 assert_eq!(p.set_month(1), Err(IMPOSSIBLE));
704 assert_eq!(p.set_month(6), Err(IMPOSSIBLE));
705 assert_eq!(p.set_month(8), Err(IMPOSSIBLE));
706 assert_eq!(p.set_month(12), Err(IMPOSSIBLE));
707
708 let mut p = Parsed::new();
709 assert_eq!(p.set_month(8), Ok(()));
710 assert_eq!(p.set_month(0x1_0000_0008), Err(OUT_OF_RANGE));
711
712 let mut p = Parsed::new();
714 assert_eq!(p.set_hour(12), Ok(()));
715 assert_eq!(p.set_hour(11), Err(IMPOSSIBLE));
716 assert_eq!(p.set_hour(13), Err(IMPOSSIBLE));
717 assert_eq!(p.set_hour(12), Ok(()));
718 assert_eq!(p.set_ampm(false), Err(IMPOSSIBLE));
719 assert_eq!(p.set_ampm(true), Ok(()));
720 assert_eq!(p.set_hour12(12), Ok(()));
721 assert_eq!(p.set_hour12(0), Err(OUT_OF_RANGE)); assert_eq!(p.set_hour12(1), Err(IMPOSSIBLE));
723 assert_eq!(p.set_hour12(11), Err(IMPOSSIBLE));
724
725 let mut p = Parsed::new();
726 assert_eq!(p.set_ampm(true), Ok(()));
727 assert_eq!(p.set_hour12(7), Ok(()));
728 assert_eq!(p.set_hour(7), Err(IMPOSSIBLE));
729 assert_eq!(p.set_hour(18), Err(IMPOSSIBLE));
730 assert_eq!(p.set_hour(19), Ok(()));
731
732 let mut p = Parsed::new();
734 assert_eq!(p.set_timestamp(1_234_567_890), Ok(()));
735 assert_eq!(p.set_timestamp(1_234_567_889), Err(IMPOSSIBLE));
736 assert_eq!(p.set_timestamp(1_234_567_891), Err(IMPOSSIBLE));
737 }
738
739 #[test]
740 fn test_parsed_to_naive_date() {
741 macro_rules! parse {
742 ($($k:ident: $v:expr),*) => (
743 Parsed { $($k: Some($v),)* ..Parsed::new() }.to_naive_date()
744 )
745 }
746
747 let ymd = |y,m,d| Ok(NaiveDate::from_ymd(y, m, d));
748
749 assert_eq!(parse!(), Err(NOT_ENOUGH));
751 assert_eq!(parse!(year: 1984), Err(NOT_ENOUGH));
752 assert_eq!(parse!(year: 1984, month: 1), Err(NOT_ENOUGH));
753 assert_eq!(parse!(year: 1984, month: 1, day: 2), ymd(1984, 1, 2));
754 assert_eq!(parse!(year: 1984, day: 2), Err(NOT_ENOUGH));
755 assert_eq!(parse!(year_div_100: 19), Err(NOT_ENOUGH));
756 assert_eq!(parse!(year_div_100: 19, year_mod_100: 84), Err(NOT_ENOUGH));
757 assert_eq!(parse!(year_div_100: 19, year_mod_100: 84, month: 1), Err(NOT_ENOUGH));
758 assert_eq!(parse!(year_div_100: 19, year_mod_100: 84, month: 1, day: 2), ymd(1984, 1, 2));
759 assert_eq!(parse!(year_div_100: 19, year_mod_100: 84, day: 2), Err(NOT_ENOUGH));
760 assert_eq!(parse!(year_div_100: 19, month: 1, day: 2), Err(NOT_ENOUGH));
761 assert_eq!(parse!(year_mod_100: 70, month: 1, day: 2), ymd(1970, 1, 2));
762 assert_eq!(parse!(year_mod_100: 69, month: 1, day: 2), ymd(2069, 1, 2));
763
764 assert_eq!(parse!(year_div_100: 19, year_mod_100: 84, month: 2, day: 29),
766 ymd(1984, 2, 29));
767 assert_eq!(parse!(year_div_100: 19, year_mod_100: 83, month: 2, day: 29),
768 Err(OUT_OF_RANGE));
769 assert_eq!(parse!(year_div_100: 19, year_mod_100: 83, month: 13, day: 1),
770 Err(OUT_OF_RANGE));
771 assert_eq!(parse!(year_div_100: 19, year_mod_100: 83, month: 12, day: 31),
772 ymd(1983, 12, 31));
773 assert_eq!(parse!(year_div_100: 19, year_mod_100: 83, month: 12, day: 32),
774 Err(OUT_OF_RANGE));
775 assert_eq!(parse!(year_div_100: 19, year_mod_100: 83, month: 12, day: 0),
776 Err(OUT_OF_RANGE));
777 assert_eq!(parse!(year_div_100: 19, year_mod_100: 100, month: 1, day: 1),
778 Err(OUT_OF_RANGE));
779 assert_eq!(parse!(year_div_100: 19, year_mod_100: -1, month: 1, day: 1),
780 Err(OUT_OF_RANGE));
781 assert_eq!(parse!(year_div_100: 0, year_mod_100: 0, month: 1, day: 1),
782 ymd(0, 1, 1));
783 assert_eq!(parse!(year_div_100: -1, year_mod_100: 42, month: 1, day: 1),
784 Err(OUT_OF_RANGE));
785 let max_year = MAX_DATE.year();
786 assert_eq!(parse!(year_div_100: max_year / 100,
787 year_mod_100: max_year % 100, month: 1, day: 1),
788 ymd(max_year, 1, 1));
789 assert_eq!(parse!(year_div_100: (max_year + 1) / 100,
790 year_mod_100: (max_year + 1) % 100, month: 1, day: 1),
791 Err(OUT_OF_RANGE));
792
793 assert_eq!(parse!(year: 1984, year_div_100: 19, month: 1, day: 1), ymd(1984, 1, 1));
795 assert_eq!(parse!(year: 1984, year_div_100: 20, month: 1, day: 1), Err(IMPOSSIBLE));
796 assert_eq!(parse!(year: 1984, year_mod_100: 84, month: 1, day: 1), ymd(1984, 1, 1));
797 assert_eq!(parse!(year: 1984, year_mod_100: 83, month: 1, day: 1), Err(IMPOSSIBLE));
798 assert_eq!(parse!(year: 1984, year_div_100: 19, year_mod_100: 84, month: 1, day: 1),
799 ymd(1984, 1, 1));
800 assert_eq!(parse!(year: 1984, year_div_100: 18, year_mod_100: 94, month: 1, day: 1),
801 Err(IMPOSSIBLE));
802 assert_eq!(parse!(year: 1984, year_div_100: 18, year_mod_100: 184, month: 1, day: 1),
803 Err(OUT_OF_RANGE));
804 assert_eq!(parse!(year: -1, year_div_100: 0, year_mod_100: -1, month: 1, day: 1),
805 Err(OUT_OF_RANGE));
806 assert_eq!(parse!(year: -1, year_div_100: -1, year_mod_100: 99, month: 1, day: 1),
807 Err(OUT_OF_RANGE));
808 assert_eq!(parse!(year: -1, year_div_100: 0, month: 1, day: 1), Err(OUT_OF_RANGE));
809 assert_eq!(parse!(year: -1, year_mod_100: 99, month: 1, day: 1), Err(OUT_OF_RANGE));
810
811 assert_eq!(parse!(year: 2000, week_from_mon: 0), Err(NOT_ENOUGH));
813 assert_eq!(parse!(year: 2000, week_from_sun: 0), Err(NOT_ENOUGH));
814 assert_eq!(parse!(year: 2000, weekday: Sun), Err(NOT_ENOUGH));
815 assert_eq!(parse!(year: 2000, week_from_mon: 0, weekday: Fri), Err(OUT_OF_RANGE));
816 assert_eq!(parse!(year: 2000, week_from_sun: 0, weekday: Fri), Err(OUT_OF_RANGE));
817 assert_eq!(parse!(year: 2000, week_from_mon: 0, weekday: Sat), ymd(2000, 1, 1));
818 assert_eq!(parse!(year: 2000, week_from_sun: 0, weekday: Sat), ymd(2000, 1, 1));
819 assert_eq!(parse!(year: 2000, week_from_mon: 0, weekday: Sun), ymd(2000, 1, 2));
820 assert_eq!(parse!(year: 2000, week_from_sun: 1, weekday: Sun), ymd(2000, 1, 2));
821 assert_eq!(parse!(year: 2000, week_from_mon: 1, weekday: Mon), ymd(2000, 1, 3));
822 assert_eq!(parse!(year: 2000, week_from_sun: 1, weekday: Mon), ymd(2000, 1, 3));
823 assert_eq!(parse!(year: 2000, week_from_mon: 1, weekday: Sat), ymd(2000, 1, 8));
824 assert_eq!(parse!(year: 2000, week_from_sun: 1, weekday: Sat), ymd(2000, 1, 8));
825 assert_eq!(parse!(year: 2000, week_from_mon: 1, weekday: Sun), ymd(2000, 1, 9));
826 assert_eq!(parse!(year: 2000, week_from_sun: 2, weekday: Sun), ymd(2000, 1, 9));
827 assert_eq!(parse!(year: 2000, week_from_mon: 2, weekday: Mon), ymd(2000, 1, 10));
828 assert_eq!(parse!(year: 2000, week_from_sun: 52, weekday: Sat), ymd(2000, 12, 30));
829 assert_eq!(parse!(year: 2000, week_from_sun: 53, weekday: Sun), ymd(2000, 12, 31));
830 assert_eq!(parse!(year: 2000, week_from_sun: 53, weekday: Mon), Err(OUT_OF_RANGE));
831 assert_eq!(parse!(year: 2000, week_from_sun: 0xffffffff, weekday: Mon), Err(OUT_OF_RANGE));
832 assert_eq!(parse!(year: 2006, week_from_sun: 0, weekday: Sat), Err(OUT_OF_RANGE));
833 assert_eq!(parse!(year: 2006, week_from_sun: 1, weekday: Sun), ymd(2006, 1, 1));
834
835 assert_eq!(parse!(year: 2000, week_from_mon: 1, week_from_sun: 1, weekday: Sat),
837 ymd(2000, 1, 8));
838 assert_eq!(parse!(year: 2000, week_from_mon: 1, week_from_sun: 2, weekday: Sun),
839 ymd(2000, 1, 9));
840 assert_eq!(parse!(year: 2000, week_from_mon: 1, week_from_sun: 1, weekday: Sun),
841 Err(IMPOSSIBLE));
842 assert_eq!(parse!(year: 2000, week_from_mon: 2, week_from_sun: 2, weekday: Sun),
843 Err(IMPOSSIBLE));
844
845 assert_eq!(parse!(isoyear: 2004, isoweek: 53), Err(NOT_ENOUGH));
847 assert_eq!(parse!(isoyear: 2004, isoweek: 53, weekday: Fri), ymd(2004, 12, 31));
848 assert_eq!(parse!(isoyear: 2004, isoweek: 53, weekday: Sat), ymd(2005, 1, 1));
849 assert_eq!(parse!(isoyear: 2004, isoweek: 0xffffffff, weekday: Sat), Err(OUT_OF_RANGE));
850 assert_eq!(parse!(isoyear: 2005, isoweek: 0, weekday: Thu), Err(OUT_OF_RANGE));
851 assert_eq!(parse!(isoyear: 2005, isoweek: 5, weekday: Thu), ymd(2005, 2, 3));
852 assert_eq!(parse!(isoyear: 2005, weekday: Thu), Err(NOT_ENOUGH));
853
854 assert_eq!(parse!(ordinal: 123), Err(NOT_ENOUGH));
856 assert_eq!(parse!(year: 2000, ordinal: 0), Err(OUT_OF_RANGE));
857 assert_eq!(parse!(year: 2000, ordinal: 1), ymd(2000, 1, 1));
858 assert_eq!(parse!(year: 2000, ordinal: 60), ymd(2000, 2, 29));
859 assert_eq!(parse!(year: 2000, ordinal: 61), ymd(2000, 3, 1));
860 assert_eq!(parse!(year: 2000, ordinal: 366), ymd(2000, 12, 31));
861 assert_eq!(parse!(year: 2000, ordinal: 367), Err(OUT_OF_RANGE));
862 assert_eq!(parse!(year: 2000, ordinal: 0xffffffff), Err(OUT_OF_RANGE));
863 assert_eq!(parse!(year: 2100, ordinal: 0), Err(OUT_OF_RANGE));
864 assert_eq!(parse!(year: 2100, ordinal: 1), ymd(2100, 1, 1));
865 assert_eq!(parse!(year: 2100, ordinal: 59), ymd(2100, 2, 28));
866 assert_eq!(parse!(year: 2100, ordinal: 60), ymd(2100, 3, 1));
867 assert_eq!(parse!(year: 2100, ordinal: 365), ymd(2100, 12, 31));
868 assert_eq!(parse!(year: 2100, ordinal: 366), Err(OUT_OF_RANGE));
869 assert_eq!(parse!(year: 2100, ordinal: 0xffffffff), Err(OUT_OF_RANGE));
870
871 assert_eq!(parse!(year: 2014, month: 12, day: 31, ordinal: 365, isoyear: 2015, isoweek: 1,
873 week_from_sun: 52, week_from_mon: 52, weekday: Wed),
874 ymd(2014, 12, 31));
875 assert_eq!(parse!(year: 2014, month: 12, ordinal: 365, isoyear: 2015, isoweek: 1,
876 week_from_sun: 52, week_from_mon: 52),
877 ymd(2014, 12, 31));
878 assert_eq!(parse!(year: 2014, month: 12, day: 31, ordinal: 365, isoyear: 2014, isoweek: 53,
879 week_from_sun: 52, week_from_mon: 52, weekday: Wed),
880 Err(IMPOSSIBLE)); assert_eq!(parse!(year: 2012, isoyear: 2015, isoweek: 1,
882 week_from_sun: 52, week_from_mon: 52),
883 Err(NOT_ENOUGH)); assert_eq!(parse!(year_div_100: 20, isoyear_mod_100: 15, ordinal: 366),
885 Err(NOT_ENOUGH)); }
887
888 #[test]
889 fn test_parsed_to_naive_time() {
890 macro_rules! parse {
891 ($($k:ident: $v:expr),*) => (
892 Parsed { $($k: Some($v),)* ..Parsed::new() }.to_naive_time()
893 )
894 }
895
896 let hms = |h,m,s| Ok(NaiveTime::from_hms(h, m, s));
897 let hmsn = |h,m,s,n| Ok(NaiveTime::from_hms_nano(h, m, s, n));
898
899 assert_eq!(parse!(), Err(NOT_ENOUGH));
901 assert_eq!(parse!(hour_div_12: 0), Err(NOT_ENOUGH));
902 assert_eq!(parse!(hour_div_12: 0, hour_mod_12: 1), Err(NOT_ENOUGH));
903 assert_eq!(parse!(hour_div_12: 0, hour_mod_12: 1, minute: 23), hms(1,23,0));
904 assert_eq!(parse!(hour_div_12: 0, hour_mod_12: 1, minute: 23, second: 45), hms(1,23,45));
905 assert_eq!(parse!(hour_div_12: 0, hour_mod_12: 1, minute: 23, second: 45,
906 nanosecond: 678_901_234),
907 hmsn(1,23,45,678_901_234));
908 assert_eq!(parse!(hour_div_12: 1, hour_mod_12: 11, minute: 45, second: 6), hms(23,45,6));
909 assert_eq!(parse!(hour_mod_12: 1, minute: 23), Err(NOT_ENOUGH));
910 assert_eq!(parse!(hour_div_12: 0, hour_mod_12: 1, minute: 23, nanosecond: 456_789_012),
911 Err(NOT_ENOUGH));
912
913 assert_eq!(parse!(hour_div_12: 2, hour_mod_12: 0, minute: 0), Err(OUT_OF_RANGE));
915 assert_eq!(parse!(hour_div_12: 1, hour_mod_12: 12, minute: 0), Err(OUT_OF_RANGE));
916 assert_eq!(parse!(hour_div_12: 0, hour_mod_12: 1, minute: 60), Err(OUT_OF_RANGE));
917 assert_eq!(parse!(hour_div_12: 0, hour_mod_12: 1, minute: 23, second: 61),
918 Err(OUT_OF_RANGE));
919 assert_eq!(parse!(hour_div_12: 0, hour_mod_12: 1, minute: 23, second: 34,
920 nanosecond: 1_000_000_000),
921 Err(OUT_OF_RANGE));
922
923 assert_eq!(parse!(hour_div_12: 0, hour_mod_12: 1, minute: 23, second: 60),
925 hmsn(1,23,59,1_000_000_000));
926 assert_eq!(parse!(hour_div_12: 0, hour_mod_12: 1, minute: 23, second: 60,
927 nanosecond: 999_999_999),
928 hmsn(1,23,59,1_999_999_999));
929 }
930
931 #[test]
932 fn test_parsed_to_naive_datetime_with_offset() {
933 macro_rules! parse {
934 (offset = $offset:expr; $($k:ident: $v:expr),*) => (
935 Parsed { $($k: Some($v),)* ..Parsed::new() }.to_naive_datetime_with_offset($offset)
936 );
937 ($($k:ident: $v:expr),*) => (parse!(offset = 0; $($k: $v),*))
938 }
939
940 let ymdhms = |y,m,d,h,n,s| Ok(NaiveDate::from_ymd(y, m, d).and_hms(h, n, s));
941 let ymdhmsn =
942 |y,m,d,h,n,s,nano| Ok(NaiveDate::from_ymd(y, m, d).and_hms_nano(h, n, s, nano));
943
944 assert_eq!(parse!(), Err(NOT_ENOUGH));
946 assert_eq!(parse!(year: 2015, month: 1, day: 30,
947 hour_div_12: 1, hour_mod_12: 2, minute: 38),
948 ymdhms(2015,1,30, 14,38,0));
949 assert_eq!(parse!(year: 1997, month: 1, day: 30,
950 hour_div_12: 1, hour_mod_12: 2, minute: 38, second: 5),
951 ymdhms(1997,1,30, 14,38,5));
952 assert_eq!(parse!(year: 2012, ordinal: 34, hour_div_12: 0, hour_mod_12: 5,
953 minute: 6, second: 7, nanosecond: 890_123_456),
954 ymdhmsn(2012,2,3, 5,6,7,890_123_456));
955 assert_eq!(parse!(timestamp: 0), ymdhms(1970,1,1, 0,0,0));
956 assert_eq!(parse!(timestamp: 1, nanosecond: 0), ymdhms(1970,1,1, 0,0,1));
957 assert_eq!(parse!(timestamp: 1, nanosecond: 1), ymdhmsn(1970,1,1, 0,0,1, 1));
958 assert_eq!(parse!(timestamp: 1_420_000_000), ymdhms(2014,12,31, 4,26,40));
959 assert_eq!(parse!(timestamp: -0x1_0000_0000), ymdhms(1833,11,24, 17,31,44));
960
961 assert_eq!(parse!(year: 2014, year_div_100: 20, year_mod_100: 14, month: 12, day: 31,
963 ordinal: 365, isoyear: 2015, isoyear_div_100: 20, isoyear_mod_100: 15,
964 isoweek: 1, week_from_sun: 52, week_from_mon: 52, weekday: Wed,
965 hour_div_12: 0, hour_mod_12: 4, minute: 26, second: 40,
966 nanosecond: 12_345_678, timestamp: 1_420_000_000),
967 ymdhmsn(2014,12,31, 4,26,40,12_345_678));
968 assert_eq!(parse!(year: 2014, year_div_100: 20, year_mod_100: 14, month: 12, day: 31,
969 ordinal: 365, isoyear: 2015, isoyear_div_100: 20, isoyear_mod_100: 15,
970 isoweek: 1, week_from_sun: 52, week_from_mon: 52, weekday: Wed,
971 hour_div_12: 0, hour_mod_12: 4, minute: 26, second: 40,
972 nanosecond: 12_345_678, timestamp: 1_419_999_999),
973 Err(IMPOSSIBLE));
974 assert_eq!(parse!(offset = 32400;
975 year: 2014, year_div_100: 20, year_mod_100: 14, month: 12, day: 31,
976 ordinal: 365, isoyear: 2015, isoyear_div_100: 20, isoyear_mod_100: 15,
977 isoweek: 1, week_from_sun: 52, week_from_mon: 52, weekday: Wed,
978 hour_div_12: 0, hour_mod_12: 4, minute: 26, second: 40,
979 nanosecond: 12_345_678, timestamp: 1_419_967_600),
980 ymdhmsn(2014,12,31, 4,26,40,12_345_678));
981
982 let max_days_from_year_1970 =
984 MAX_DATE.signed_duration_since(NaiveDate::from_ymd(1970,1,1));
985 let year_0_from_year_1970 =
986 NaiveDate::from_ymd(0,1,1).signed_duration_since(NaiveDate::from_ymd(1970,1,1));
987 let min_days_from_year_1970 =
988 MIN_DATE.signed_duration_since(NaiveDate::from_ymd(1970,1,1));
989 assert_eq!(parse!(timestamp: min_days_from_year_1970.num_seconds()),
990 ymdhms(MIN_DATE.year(),1,1, 0,0,0));
991 assert_eq!(parse!(timestamp: year_0_from_year_1970.num_seconds()),
992 ymdhms(0,1,1, 0,0,0));
993 assert_eq!(parse!(timestamp: max_days_from_year_1970.num_seconds() + 86399),
994 ymdhms(MAX_DATE.year(),12,31, 23,59,59));
995
996 assert_eq!(parse!(second: 59, timestamp: 1_341_100_798), Err(IMPOSSIBLE));
998 assert_eq!(parse!(second: 59, timestamp: 1_341_100_799), ymdhms(2012,6,30, 23,59,59));
999 assert_eq!(parse!(second: 59, timestamp: 1_341_100_800), Err(IMPOSSIBLE));
1000 assert_eq!(parse!(second: 60, timestamp: 1_341_100_799),
1001 ymdhmsn(2012,6,30, 23,59,59,1_000_000_000));
1002 assert_eq!(parse!(second: 60, timestamp: 1_341_100_800),
1003 ymdhmsn(2012,6,30, 23,59,59,1_000_000_000));
1004 assert_eq!(parse!(second: 0, timestamp: 1_341_100_800), ymdhms(2012,7,1, 0,0,0));
1005 assert_eq!(parse!(second: 1, timestamp: 1_341_100_800), Err(IMPOSSIBLE));
1006 assert_eq!(parse!(second: 60, timestamp: 1_341_100_801), Err(IMPOSSIBLE));
1007
1008 assert_eq!(parse!(year: 2012, ordinal: 182, hour_div_12: 1, hour_mod_12: 11,
1011 minute: 59, second: 59, timestamp: 1_341_100_798),
1012 Err(IMPOSSIBLE));
1013 assert_eq!(parse!(year: 2012, ordinal: 182, hour_div_12: 1, hour_mod_12: 11,
1014 minute: 59, second: 59, timestamp: 1_341_100_799),
1015 ymdhms(2012,6,30, 23,59,59));
1016 assert_eq!(parse!(year: 2012, ordinal: 182, hour_div_12: 1, hour_mod_12: 11,
1017 minute: 59, second: 59, timestamp: 1_341_100_800),
1018 Err(IMPOSSIBLE));
1019 assert_eq!(parse!(year: 2012, ordinal: 182, hour_div_12: 1, hour_mod_12: 11,
1020 minute: 59, second: 60, timestamp: 1_341_100_799),
1021 ymdhmsn(2012,6,30, 23,59,59,1_000_000_000));
1022 assert_eq!(parse!(year: 2012, ordinal: 182, hour_div_12: 1, hour_mod_12: 11,
1023 minute: 59, second: 60, timestamp: 1_341_100_800),
1024 ymdhmsn(2012,6,30, 23,59,59,1_000_000_000));
1025 assert_eq!(parse!(year: 2012, ordinal: 183, hour_div_12: 0, hour_mod_12: 0,
1026 minute: 0, second: 0, timestamp: 1_341_100_800),
1027 ymdhms(2012,7,1, 0,0,0));
1028 assert_eq!(parse!(year: 2012, ordinal: 183, hour_div_12: 0, hour_mod_12: 0,
1029 minute: 0, second: 1, timestamp: 1_341_100_800),
1030 Err(IMPOSSIBLE));
1031 assert_eq!(parse!(year: 2012, ordinal: 182, hour_div_12: 1, hour_mod_12: 11,
1032 minute: 59, second: 60, timestamp: 1_341_100_801),
1033 Err(IMPOSSIBLE));
1034
1035 assert_eq!(parse!(year: 2015, month: 1, day: 20, weekday: Tue,
1037 hour_div_12: 2, hour_mod_12: 1, minute: 35, second: 20),
1038 Err(OUT_OF_RANGE)); }
1040
1041 #[test]
1042 fn test_parsed_to_datetime() {
1043 macro_rules! parse {
1044 ($($k:ident: $v:expr),*) => (
1045 Parsed { $($k: Some($v),)* ..Parsed::new() }.to_datetime()
1046 )
1047 }
1048
1049 let ymdhmsn = |y,m,d,h,n,s,nano,off| Ok(FixedOffset::east(off).ymd(y, m, d)
1050 .and_hms_nano(h, n, s, nano));
1051
1052 assert_eq!(parse!(offset: 0), Err(NOT_ENOUGH));
1053 assert_eq!(parse!(year: 2014, ordinal: 365, hour_div_12: 0, hour_mod_12: 4,
1054 minute: 26, second: 40, nanosecond: 12_345_678),
1055 Err(NOT_ENOUGH));
1056 assert_eq!(parse!(year: 2014, ordinal: 365, hour_div_12: 0, hour_mod_12: 4,
1057 minute: 26, second: 40, nanosecond: 12_345_678, offset: 0),
1058 ymdhmsn(2014,12,31, 4,26,40,12_345_678, 0));
1059 assert_eq!(parse!(year: 2014, ordinal: 365, hour_div_12: 1, hour_mod_12: 1,
1060 minute: 26, second: 40, nanosecond: 12_345_678, offset: 32400),
1061 ymdhmsn(2014,12,31, 13,26,40,12_345_678, 32400));
1062 assert_eq!(parse!(year: 2014, ordinal: 365, hour_div_12: 0, hour_mod_12: 1,
1063 minute: 42, second: 4, nanosecond: 12_345_678, offset: -9876),
1064 ymdhmsn(2014,12,31, 1,42,4,12_345_678, -9876));
1065 assert_eq!(parse!(year: 2015, ordinal: 1, hour_div_12: 0, hour_mod_12: 4,
1066 minute: 26, second: 40, nanosecond: 12_345_678, offset: 86_400),
1067 Err(OUT_OF_RANGE)); }
1069
1070 #[test]
1071 fn test_parsed_to_datetime_with_timezone() {
1072 macro_rules! parse {
1073 ($tz:expr; $($k:ident: $v:expr),*) => (
1074 Parsed { $($k: Some($v),)* ..Parsed::new() }.to_datetime_with_timezone(&$tz)
1075 )
1076 }
1077
1078 assert_eq!(parse!(Utc;
1080 year: 2014, ordinal: 365, hour_div_12: 0, hour_mod_12: 4,
1081 minute: 26, second: 40, nanosecond: 12_345_678, offset: 0),
1082 Ok(Utc.ymd(2014, 12, 31).and_hms_nano(4, 26, 40, 12_345_678)));
1083 assert_eq!(parse!(Utc;
1084 year: 2014, ordinal: 365, hour_div_12: 1, hour_mod_12: 1,
1085 minute: 26, second: 40, nanosecond: 12_345_678, offset: 32400),
1086 Err(IMPOSSIBLE));
1087 assert_eq!(parse!(FixedOffset::east(32400);
1088 year: 2014, ordinal: 365, hour_div_12: 0, hour_mod_12: 4,
1089 minute: 26, second: 40, nanosecond: 12_345_678, offset: 0),
1090 Err(IMPOSSIBLE));
1091 assert_eq!(parse!(FixedOffset::east(32400);
1092 year: 2014, ordinal: 365, hour_div_12: 1, hour_mod_12: 1,
1093 minute: 26, second: 40, nanosecond: 12_345_678, offset: 32400),
1094 Ok(FixedOffset::east(32400).ymd(2014, 12, 31)
1095 .and_hms_nano(13, 26, 40, 12_345_678)));
1096
1097 assert_eq!(parse!(Utc; timestamp: 1_420_000_000, offset: 0),
1099 Ok(Utc.ymd(2014, 12, 31).and_hms(4, 26, 40)));
1100 assert_eq!(parse!(Utc; timestamp: 1_420_000_000, offset: 32400),
1101 Err(IMPOSSIBLE));
1102 assert_eq!(parse!(FixedOffset::east(32400); timestamp: 1_420_000_000, offset: 0),
1103 Err(IMPOSSIBLE));
1104 assert_eq!(parse!(FixedOffset::east(32400); timestamp: 1_420_000_000, offset: 32400),
1105 Ok(FixedOffset::east(32400).ymd(2014, 12, 31).and_hms(13, 26, 40)));
1106
1107 }
1109}
1110