1use super::{IMPOSSIBLE, NOT_ENOUGH, OUT_OF_RANGE, ParseResult};
8use crate::naive::{NaiveDate, NaiveDateTime, NaiveTime};
9use crate::offset::{FixedOffset, MappedLocalTime, Offset, TimeZone};
10use crate::{DateTime, Datelike, TimeDelta, Timelike, Weekday};
11
12#[allow(clippy::manual_non_exhaustive)]
128#[derive(Clone, PartialEq, Eq, Debug, Default, Hash)]
129pub struct Parsed {
130    #[doc(hidden)]
131    pub year: Option<i32>,
132    #[doc(hidden)]
133    pub year_div_100: Option<i32>,
134    #[doc(hidden)]
135    pub year_mod_100: Option<i32>,
136    #[doc(hidden)]
137    pub isoyear: Option<i32>,
138    #[doc(hidden)]
139    pub isoyear_div_100: Option<i32>,
140    #[doc(hidden)]
141    pub isoyear_mod_100: Option<i32>,
142    #[doc(hidden)]
143    pub quarter: Option<u32>,
144    #[doc(hidden)]
145    pub month: Option<u32>,
146    #[doc(hidden)]
147    pub week_from_sun: Option<u32>,
148    #[doc(hidden)]
149    pub week_from_mon: Option<u32>,
150    #[doc(hidden)]
151    pub isoweek: Option<u32>,
152    #[doc(hidden)]
153    pub weekday: Option<Weekday>,
154    #[doc(hidden)]
155    pub ordinal: Option<u32>,
156    #[doc(hidden)]
157    pub day: Option<u32>,
158    #[doc(hidden)]
159    pub hour_div_12: Option<u32>,
160    #[doc(hidden)]
161    pub hour_mod_12: Option<u32>,
162    #[doc(hidden)]
163    pub minute: Option<u32>,
164    #[doc(hidden)]
165    pub second: Option<u32>,
166    #[doc(hidden)]
167    pub nanosecond: Option<u32>,
168    #[doc(hidden)]
169    pub timestamp: Option<i64>,
170    #[doc(hidden)]
171    pub offset: Option<i32>,
172    #[doc(hidden)]
173    _dummy: (),
174}
175
176#[inline]
179fn set_if_consistent<T: PartialEq>(old: &mut Option<T>, new: T) -> ParseResult<()> {
180    match old {
181        Some(old) if *old != new => Err(IMPOSSIBLE),
182        _ => {
183            *old = Some(new);
184            Ok(())
185        }
186    }
187}
188
189impl Parsed {
190    #[must_use]
192    pub fn new() -> Parsed {
193        Parsed::default()
194    }
195
196    #[inline]
207    pub fn set_year(&mut self, value: i64) -> ParseResult<()> {
208        set_if_consistent(&mut self.year, i32::try_from(value).map_err(|_| OUT_OF_RANGE)?)
209    }
210
211    #[inline]
219    pub fn set_year_div_100(&mut self, value: i64) -> ParseResult<()> {
220        if !(0..=i32::MAX as i64).contains(&value) {
221            return Err(OUT_OF_RANGE);
222        }
223        set_if_consistent(&mut self.year_div_100, value as i32)
224    }
225
226    #[inline]
241    pub fn set_year_mod_100(&mut self, value: i64) -> ParseResult<()> {
242        if !(0..100).contains(&value) {
243            return Err(OUT_OF_RANGE);
244        }
245        set_if_consistent(&mut self.year_mod_100, value as i32)
246    }
247
248    #[inline]
262    pub fn set_isoyear(&mut self, value: i64) -> ParseResult<()> {
263        set_if_consistent(&mut self.isoyear, i32::try_from(value).map_err(|_| OUT_OF_RANGE)?)
264    }
265
266    #[inline]
277    pub fn set_isoyear_div_100(&mut self, value: i64) -> ParseResult<()> {
278        if !(0..=i32::MAX as i64).contains(&value) {
279            return Err(OUT_OF_RANGE);
280        }
281        set_if_consistent(&mut self.isoyear_div_100, value as i32)
282    }
283
284    #[inline]
302    pub fn set_isoyear_mod_100(&mut self, value: i64) -> ParseResult<()> {
303        if !(0..100).contains(&value) {
304            return Err(OUT_OF_RANGE);
305        }
306        set_if_consistent(&mut self.isoyear_mod_100, value as i32)
307    }
308
309    #[inline]
319    pub fn set_quarter(&mut self, value: i64) -> ParseResult<()> {
320        if !(1..=4).contains(&value) {
321            return Err(OUT_OF_RANGE);
322        }
323        set_if_consistent(&mut self.quarter, value as u32)
324    }
325
326    #[inline]
334    pub fn set_month(&mut self, value: i64) -> ParseResult<()> {
335        if !(1..=12).contains(&value) {
336            return Err(OUT_OF_RANGE);
337        }
338        set_if_consistent(&mut self.month, value as u32)
339    }
340
341    #[inline]
351    pub fn set_week_from_sun(&mut self, value: i64) -> ParseResult<()> {
352        if !(0..=53).contains(&value) {
353            return Err(OUT_OF_RANGE);
354        }
355        set_if_consistent(&mut self.week_from_sun, value as u32)
356    }
357
358    #[inline]
369    pub fn set_week_from_mon(&mut self, value: i64) -> ParseResult<()> {
370        if !(0..=53).contains(&value) {
371            return Err(OUT_OF_RANGE);
372        }
373        set_if_consistent(&mut self.week_from_mon, value as u32)
374    }
375
376    #[inline]
386    pub fn set_isoweek(&mut self, value: i64) -> ParseResult<()> {
387        if !(1..=53).contains(&value) {
388            return Err(OUT_OF_RANGE);
389        }
390        set_if_consistent(&mut self.isoweek, value as u32)
391    }
392
393    #[inline]
399    pub fn set_weekday(&mut self, value: Weekday) -> ParseResult<()> {
400        set_if_consistent(&mut self.weekday, value)
401    }
402
403    #[inline]
411    pub fn set_ordinal(&mut self, value: i64) -> ParseResult<()> {
412        if !(1..=366).contains(&value) {
413            return Err(OUT_OF_RANGE);
414        }
415        set_if_consistent(&mut self.ordinal, value as u32)
416    }
417
418    #[inline]
426    pub fn set_day(&mut self, value: i64) -> ParseResult<()> {
427        if !(1..=31).contains(&value) {
428            return Err(OUT_OF_RANGE);
429        }
430        set_if_consistent(&mut self.day, value as u32)
431    }
432
433    #[inline]
441    pub fn set_ampm(&mut self, value: bool) -> ParseResult<()> {
442        set_if_consistent(&mut self.hour_div_12, value as u32)
443    }
444
445    #[inline]
457    pub fn set_hour12(&mut self, mut value: i64) -> ParseResult<()> {
458        if !(1..=12).contains(&value) {
459            return Err(OUT_OF_RANGE);
460        }
461        if value == 12 {
462            value = 0
463        }
464        set_if_consistent(&mut self.hour_mod_12, value as u32)
465    }
466
467    #[inline]
477    pub fn set_hour(&mut self, value: i64) -> ParseResult<()> {
478        let (hour_div_12, hour_mod_12) = match value {
479            hour @ 0..=11 => (0, hour as u32),
480            hour @ 12..=23 => (1, hour as u32 - 12),
481            _ => return Err(OUT_OF_RANGE),
482        };
483        set_if_consistent(&mut self.hour_div_12, hour_div_12)?;
484        set_if_consistent(&mut self.hour_mod_12, hour_mod_12)
485    }
486
487    #[inline]
495    pub fn set_minute(&mut self, value: i64) -> ParseResult<()> {
496        if !(0..=59).contains(&value) {
497            return Err(OUT_OF_RANGE);
498        }
499        set_if_consistent(&mut self.minute, value as u32)
500    }
501
502    #[inline]
512    pub fn set_second(&mut self, value: i64) -> ParseResult<()> {
513        if !(0..=60).contains(&value) {
514            return Err(OUT_OF_RANGE);
515        }
516        set_if_consistent(&mut self.second, value as u32)
517    }
518
519    #[inline]
529    pub fn set_nanosecond(&mut self, value: i64) -> ParseResult<()> {
530        if !(0..=999_999_999).contains(&value) {
531            return Err(OUT_OF_RANGE);
532        }
533        set_if_consistent(&mut self.nanosecond, value as u32)
534    }
535
536    #[inline]
545    pub fn set_timestamp(&mut self, value: i64) -> ParseResult<()> {
546        set_if_consistent(&mut self.timestamp, value)
547    }
548
549    #[inline]
559    pub fn set_offset(&mut self, value: i64) -> ParseResult<()> {
560        set_if_consistent(&mut self.offset, i32::try_from(value).map_err(|_| OUT_OF_RANGE)?)
561    }
562
563    pub fn to_naive_date(&self) -> ParseResult<NaiveDate> {
587        fn resolve_year(
588            y: Option<i32>,
589            q: Option<i32>,
590            r: Option<i32>,
591        ) -> ParseResult<Option<i32>> {
592            match (y, q, r) {
593                (y, None, None) => Ok(y),
596
597                (Some(y), q, r @ Some(0..=99)) | (Some(y), q, r @ None) => {
602                    if y < 0 {
603                        return Err(IMPOSSIBLE);
604                    }
605                    let q_ = y / 100;
606                    let r_ = y % 100;
607                    if q.unwrap_or(q_) == q_ && r.unwrap_or(r_) == r_ {
608                        Ok(Some(y))
609                    } else {
610                        Err(IMPOSSIBLE)
611                    }
612                }
613
614                (None, Some(q), Some(r @ 0..=99)) => {
617                    if q < 0 {
618                        return Err(IMPOSSIBLE);
619                    }
620                    let y = q.checked_mul(100).and_then(|v| v.checked_add(r));
621                    Ok(Some(y.ok_or(OUT_OF_RANGE)?))
622                }
623
624                (None, None, Some(r @ 0..=99)) => Ok(Some(r + if r < 70 { 2000 } else { 1900 })),
627
628                (None, Some(_), None) => Err(NOT_ENOUGH),
630                (_, _, Some(_)) => Err(OUT_OF_RANGE),
631            }
632        }
633
634        let given_year = resolve_year(self.year, self.year_div_100, self.year_mod_100)?;
635        let given_isoyear = resolve_year(self.isoyear, self.isoyear_div_100, self.isoyear_mod_100)?;
636
637        let verify_ymd = |date: NaiveDate| {
639            let year = date.year();
640            let (year_div_100, year_mod_100) = if year >= 0 {
641                (Some(year / 100), Some(year % 100))
642            } else {
643                (None, None) };
645            let month = date.month();
646            let day = date.day();
647            self.year.unwrap_or(year) == year
648                && self.year_div_100.or(year_div_100) == year_div_100
649                && self.year_mod_100.or(year_mod_100) == year_mod_100
650                && self.month.unwrap_or(month) == month
651                && self.day.unwrap_or(day) == day
652        };
653
654        let verify_isoweekdate = |date: NaiveDate| {
656            let week = date.iso_week();
657            let isoyear = week.year();
658            let isoweek = week.week();
659            let weekday = date.weekday();
660            let (isoyear_div_100, isoyear_mod_100) = if isoyear >= 0 {
661                (Some(isoyear / 100), Some(isoyear % 100))
662            } else {
663                (None, None) };
665            self.isoyear.unwrap_or(isoyear) == isoyear
666                && self.isoyear_div_100.or(isoyear_div_100) == isoyear_div_100
667                && self.isoyear_mod_100.or(isoyear_mod_100) == isoyear_mod_100
668                && self.isoweek.unwrap_or(isoweek) == isoweek
669                && self.weekday.unwrap_or(weekday) == weekday
670        };
671
672        let verify_ordinal = |date: NaiveDate| {
674            let ordinal = date.ordinal();
675            let week_from_sun = date.weeks_from(Weekday::Sun);
676            let week_from_mon = date.weeks_from(Weekday::Mon);
677            self.ordinal.unwrap_or(ordinal) == ordinal
678                && self.week_from_sun.map_or(week_from_sun, |v| v as i32) == week_from_sun
679                && self.week_from_mon.map_or(week_from_mon, |v| v as i32) == week_from_mon
680        };
681
682        let (verified, parsed_date) = match (given_year, given_isoyear, self) {
686            (Some(year), _, &Parsed { month: Some(month), day: Some(day), .. }) => {
687                let date = NaiveDate::from_ymd_opt(year, month, day).ok_or(OUT_OF_RANGE)?;
689                (verify_isoweekdate(date) && verify_ordinal(date), date)
690            }
691
692            (Some(year), _, &Parsed { ordinal: Some(ordinal), .. }) => {
693                let date = NaiveDate::from_yo_opt(year, ordinal).ok_or(OUT_OF_RANGE)?;
695                (verify_ymd(date) && verify_isoweekdate(date) && verify_ordinal(date), date)
696            }
697
698            (Some(year), _, &Parsed { week_from_sun: Some(week), weekday: Some(weekday), .. }) => {
699                let date = resolve_week_date(year, week, weekday, Weekday::Sun)?;
701                (verify_ymd(date) && verify_isoweekdate(date) && verify_ordinal(date), date)
702            }
703
704            (Some(year), _, &Parsed { week_from_mon: Some(week), weekday: Some(weekday), .. }) => {
705                let date = resolve_week_date(year, week, weekday, Weekday::Mon)?;
707                (verify_ymd(date) && verify_isoweekdate(date) && verify_ordinal(date), date)
708            }
709
710            (_, Some(isoyear), &Parsed { isoweek: Some(isoweek), weekday: Some(weekday), .. }) => {
711                let date = NaiveDate::from_isoywd_opt(isoyear, isoweek, weekday);
713                let date = date.ok_or(OUT_OF_RANGE)?;
714                (verify_ymd(date) && verify_ordinal(date), date)
715            }
716
717            (_, _, _) => return Err(NOT_ENOUGH),
718        };
719
720        if !verified {
721            return Err(IMPOSSIBLE);
722        } else if let Some(parsed) = self.quarter {
723            if parsed != parsed_date.quarter() {
724                return Err(IMPOSSIBLE);
725            }
726        }
727
728        Ok(parsed_date)
729    }
730
731    pub fn to_naive_time(&self) -> ParseResult<NaiveTime> {
749        let hour_div_12 = match self.hour_div_12 {
750            Some(v @ 0..=1) => v,
751            Some(_) => return Err(OUT_OF_RANGE),
752            None => return Err(NOT_ENOUGH),
753        };
754        let hour_mod_12 = match self.hour_mod_12 {
755            Some(v @ 0..=11) => v,
756            Some(_) => return Err(OUT_OF_RANGE),
757            None => return Err(NOT_ENOUGH),
758        };
759        let hour = hour_div_12 * 12 + hour_mod_12;
760
761        let minute = match self.minute {
762            Some(v @ 0..=59) => v,
763            Some(_) => return Err(OUT_OF_RANGE),
764            None => return Err(NOT_ENOUGH),
765        };
766
767        let (second, mut nano) = match self.second.unwrap_or(0) {
769            v @ 0..=59 => (v, 0),
770            60 => (59, 1_000_000_000),
771            _ => return Err(OUT_OF_RANGE),
772        };
773        nano += match self.nanosecond {
774            Some(v @ 0..=999_999_999) if self.second.is_some() => v,
775            Some(0..=999_999_999) => return Err(NOT_ENOUGH), Some(_) => return Err(OUT_OF_RANGE),
777            None => 0,
778        };
779
780        NaiveTime::from_hms_nano_opt(hour, minute, second, nano).ok_or(OUT_OF_RANGE)
781    }
782
783    pub fn to_naive_datetime_with_offset(&self, offset: i32) -> ParseResult<NaiveDateTime> {
803        let date = self.to_naive_date();
804        let time = self.to_naive_time();
805        if let (Ok(date), Ok(time)) = (date, time) {
806            let datetime = date.and_time(time);
807
808            let timestamp = datetime.and_utc().timestamp() - i64::from(offset);
811            if let Some(given_timestamp) = self.timestamp {
812                if given_timestamp != timestamp
814                    && !(datetime.nanosecond() >= 1_000_000_000 && given_timestamp == timestamp + 1)
815                {
816                    return Err(IMPOSSIBLE);
817                }
818            }
819
820            Ok(datetime)
821        } else if let Some(timestamp) = self.timestamp {
822            use super::ParseError as PE;
823            use super::ParseErrorKind::{Impossible, OutOfRange};
824
825            match (date, time) {
828                (Err(PE(OutOfRange)), _) | (_, Err(PE(OutOfRange))) => return Err(OUT_OF_RANGE),
829                (Err(PE(Impossible)), _) | (_, Err(PE(Impossible))) => return Err(IMPOSSIBLE),
830                (_, _) => {} }
832
833            let ts = timestamp.checked_add(i64::from(offset)).ok_or(OUT_OF_RANGE)?;
835            let mut datetime = DateTime::from_timestamp_secs(ts).ok_or(OUT_OF_RANGE)?.naive_utc();
836
837            let mut parsed = self.clone();
840            if parsed.second == Some(60) {
841                match datetime.second() {
843                    59 => {}
845                    0 => {
847                        datetime -= TimeDelta::try_seconds(1).unwrap();
848                    }
849                    _ => return Err(IMPOSSIBLE),
851                }
852            } else {
854                parsed.set_second(i64::from(datetime.second()))?;
855            }
856            parsed.set_year(i64::from(datetime.year()))?;
857            parsed.set_ordinal(i64::from(datetime.ordinal()))?; parsed.set_hour(i64::from(datetime.hour()))?;
859            parsed.set_minute(i64::from(datetime.minute()))?;
860
861            let date = parsed.to_naive_date()?;
863            let time = parsed.to_naive_time()?;
864            Ok(date.and_time(time))
865        } else {
866            date?;
868            time?;
869            unreachable!()
870        }
871    }
872
873    pub fn to_fixed_offset(&self) -> ParseResult<FixedOffset> {
881        FixedOffset::east_opt(self.offset.ok_or(NOT_ENOUGH)?).ok_or(OUT_OF_RANGE)
882    }
883
884    pub fn to_datetime(&self) -> ParseResult<DateTime<FixedOffset>> {
903        let offset = match (self.offset, self.timestamp) {
905            (Some(off), _) => off,
906            (None, Some(_)) => 0, (None, None) => return Err(NOT_ENOUGH),
908        };
909        let datetime = self.to_naive_datetime_with_offset(offset)?;
910        let offset = FixedOffset::east_opt(offset).ok_or(OUT_OF_RANGE)?;
911
912        match offset.from_local_datetime(&datetime) {
913            MappedLocalTime::None => Err(IMPOSSIBLE),
914            MappedLocalTime::Single(t) => Ok(t),
915            MappedLocalTime::Ambiguous(..) => Err(NOT_ENOUGH),
916        }
917    }
918
919    pub fn to_datetime_with_timezone<Tz: TimeZone>(&self, tz: &Tz) -> ParseResult<DateTime<Tz>> {
945        let mut guessed_offset = 0;
947        if let Some(timestamp) = self.timestamp {
948            let nanosecond = self.nanosecond.unwrap_or(0);
951            let dt =
952                DateTime::from_timestamp(timestamp, nanosecond).ok_or(OUT_OF_RANGE)?.naive_utc();
953            guessed_offset = tz.offset_from_utc_datetime(&dt).fix().local_minus_utc();
954        }
955
956        let check_offset = |dt: &DateTime<Tz>| {
958            if let Some(offset) = self.offset {
959                dt.offset().fix().local_minus_utc() == offset
960            } else {
961                true
962            }
963        };
964
965        let datetime = self.to_naive_datetime_with_offset(guessed_offset)?;
968        match tz.from_local_datetime(&datetime) {
969            MappedLocalTime::None => Err(IMPOSSIBLE),
970            MappedLocalTime::Single(t) => {
971                if check_offset(&t) {
972                    Ok(t)
973                } else {
974                    Err(IMPOSSIBLE)
975                }
976            }
977            MappedLocalTime::Ambiguous(min, max) => {
978                match (check_offset(&min), check_offset(&max)) {
980                    (false, false) => Err(IMPOSSIBLE),
981                    (false, true) => Ok(max),
982                    (true, false) => Ok(min),
983                    (true, true) => Err(NOT_ENOUGH),
984                }
985            }
986        }
987    }
988
989    #[inline]
993    pub fn year(&self) -> Option<i32> {
994        self.year
995    }
996
997    #[inline]
1001    pub fn year_div_100(&self) -> Option<i32> {
1002        self.year_div_100
1003    }
1004
1005    #[inline]
1009    pub fn year_mod_100(&self) -> Option<i32> {
1010        self.year_mod_100
1011    }
1012
1013    #[inline]
1019    pub fn isoyear(&self) -> Option<i32> {
1020        self.isoyear
1021    }
1022
1023    #[inline]
1029    pub fn isoyear_div_100(&self) -> Option<i32> {
1030        self.isoyear_div_100
1031    }
1032
1033    #[inline]
1039    pub fn isoyear_mod_100(&self) -> Option<i32> {
1040        self.isoyear_mod_100
1041    }
1042
1043    #[inline]
1047    pub fn quarter(&self) -> Option<u32> {
1048        self.quarter
1049    }
1050
1051    #[inline]
1055    pub fn month(&self) -> Option<u32> {
1056        self.month
1057    }
1058
1059    #[inline]
1063    pub fn week_from_sun(&self) -> Option<u32> {
1064        self.week_from_sun
1065    }
1066
1067    #[inline]
1071    pub fn week_from_mon(&self) -> Option<u32> {
1072        self.week_from_mon
1073    }
1074
1075    #[inline]
1081    pub fn isoweek(&self) -> Option<u32> {
1082        self.isoweek
1083    }
1084
1085    #[inline]
1089    pub fn weekday(&self) -> Option<Weekday> {
1090        self.weekday
1091    }
1092
1093    #[inline]
1097    pub fn ordinal(&self) -> Option<u32> {
1098        self.ordinal
1099    }
1100
1101    #[inline]
1105    pub fn day(&self) -> Option<u32> {
1106        self.day
1107    }
1108
1109    #[inline]
1115    pub fn hour_div_12(&self) -> Option<u32> {
1116        self.hour_div_12
1117    }
1118
1119    pub fn hour_mod_12(&self) -> Option<u32> {
1123        self.hour_mod_12
1124    }
1125
1126    #[inline]
1130    pub fn minute(&self) -> Option<u32> {
1131        self.minute
1132    }
1133
1134    #[inline]
1138    pub fn second(&self) -> Option<u32> {
1139        self.second
1140    }
1141
1142    #[inline]
1146    pub fn nanosecond(&self) -> Option<u32> {
1147        self.nanosecond
1148    }
1149
1150    #[inline]
1154    pub fn timestamp(&self) -> Option<i64> {
1155        self.timestamp
1156    }
1157
1158    #[inline]
1162    pub fn offset(&self) -> Option<i32> {
1163        self.offset
1164    }
1165}
1166
1167fn resolve_week_date(
1172    year: i32,
1173    week: u32,
1174    weekday: Weekday,
1175    week_start_day: Weekday,
1176) -> ParseResult<NaiveDate> {
1177    if week > 53 {
1178        return Err(OUT_OF_RANGE);
1179    }
1180
1181    let first_day_of_year = NaiveDate::from_yo_opt(year, 1).ok_or(OUT_OF_RANGE)?;
1182    let first_week_start = 1 + week_start_day.days_since(first_day_of_year.weekday()) as i32;
1184    let weekday = weekday.days_since(week_start_day) as i32;
1186    let ordinal = first_week_start + (week as i32 - 1) * 7 + weekday;
1187    if ordinal <= 0 {
1188        return Err(IMPOSSIBLE);
1189    }
1190    first_day_of_year.with_ordinal(ordinal as u32).ok_or(IMPOSSIBLE)
1191}
1192
1193#[cfg(test)]
1194mod tests {
1195    use super::super::{IMPOSSIBLE, NOT_ENOUGH, OUT_OF_RANGE};
1196    use super::Parsed;
1197    use crate::Datelike;
1198    use crate::Weekday::*;
1199    use crate::naive::{NaiveDate, NaiveTime};
1200    use crate::offset::{FixedOffset, TimeZone, Utc};
1201
1202    #[test]
1203    fn test_parsed_set_fields() {
1204        let mut p = Parsed::new();
1206        assert_eq!(p.set_year(1987), Ok(()));
1207        assert_eq!(p.set_year(1986), Err(IMPOSSIBLE));
1208        assert_eq!(p.set_year(1988), Err(IMPOSSIBLE));
1209        assert_eq!(p.set_year(1987), Ok(()));
1210        assert_eq!(p.set_year_div_100(20), Ok(())); assert_eq!(p.set_year_div_100(21), Err(IMPOSSIBLE));
1212        assert_eq!(p.set_year_div_100(19), Err(IMPOSSIBLE));
1213        assert_eq!(p.set_year_mod_100(37), Ok(())); assert_eq!(p.set_year_mod_100(38), Err(IMPOSSIBLE));
1215        assert_eq!(p.set_year_mod_100(36), Err(IMPOSSIBLE));
1216
1217        let mut p = Parsed::new();
1218        assert_eq!(p.set_year(0), Ok(()));
1219        assert_eq!(p.set_year_div_100(0), Ok(()));
1220        assert_eq!(p.set_year_mod_100(0), Ok(()));
1221
1222        let mut p = Parsed::new();
1223        assert_eq!(p.set_year_div_100(-1), Err(OUT_OF_RANGE));
1224        assert_eq!(p.set_year_mod_100(-1), Err(OUT_OF_RANGE));
1225        assert_eq!(p.set_year(-1), Ok(()));
1226        assert_eq!(p.set_year(-2), Err(IMPOSSIBLE));
1227        assert_eq!(p.set_year(0), Err(IMPOSSIBLE));
1228
1229        let mut p = Parsed::new();
1230        assert_eq!(p.set_year_div_100(0x1_0000_0008), Err(OUT_OF_RANGE));
1231        assert_eq!(p.set_year_div_100(8), Ok(()));
1232        assert_eq!(p.set_year_div_100(0x1_0000_0008), Err(OUT_OF_RANGE));
1233
1234        let mut p = Parsed::new();
1236        assert_eq!(p.set_month(7), Ok(()));
1237        assert_eq!(p.set_month(1), Err(IMPOSSIBLE));
1238        assert_eq!(p.set_month(6), Err(IMPOSSIBLE));
1239        assert_eq!(p.set_month(8), Err(IMPOSSIBLE));
1240        assert_eq!(p.set_month(12), Err(IMPOSSIBLE));
1241
1242        let mut p = Parsed::new();
1243        assert_eq!(p.set_month(8), Ok(()));
1244        assert_eq!(p.set_month(0x1_0000_0008), Err(OUT_OF_RANGE));
1245
1246        let mut p = Parsed::new();
1248        assert_eq!(p.set_hour(12), Ok(()));
1249        assert_eq!(p.set_hour(11), Err(IMPOSSIBLE));
1250        assert_eq!(p.set_hour(13), Err(IMPOSSIBLE));
1251        assert_eq!(p.set_hour(12), Ok(()));
1252        assert_eq!(p.set_ampm(false), Err(IMPOSSIBLE));
1253        assert_eq!(p.set_ampm(true), Ok(()));
1254        assert_eq!(p.set_hour12(12), Ok(()));
1255        assert_eq!(p.set_hour12(0), Err(OUT_OF_RANGE)); assert_eq!(p.set_hour12(1), Err(IMPOSSIBLE));
1257        assert_eq!(p.set_hour12(11), Err(IMPOSSIBLE));
1258
1259        let mut p = Parsed::new();
1260        assert_eq!(p.set_ampm(true), Ok(()));
1261        assert_eq!(p.set_hour12(7), Ok(()));
1262        assert_eq!(p.set_hour(7), Err(IMPOSSIBLE));
1263        assert_eq!(p.set_hour(18), Err(IMPOSSIBLE));
1264        assert_eq!(p.set_hour(19), Ok(()));
1265
1266        let mut p = Parsed::new();
1268        assert_eq!(p.set_timestamp(1_234_567_890), Ok(()));
1269        assert_eq!(p.set_timestamp(1_234_567_889), Err(IMPOSSIBLE));
1270        assert_eq!(p.set_timestamp(1_234_567_891), Err(IMPOSSIBLE));
1271    }
1272
1273    #[test]
1274    fn test_parsed_set_range() {
1275        assert_eq!(Parsed::new().set_year(i32::MIN as i64 - 1), Err(OUT_OF_RANGE));
1276        assert!(Parsed::new().set_year(i32::MIN as i64).is_ok());
1277        assert!(Parsed::new().set_year(i32::MAX as i64).is_ok());
1278        assert_eq!(Parsed::new().set_year(i32::MAX as i64 + 1), Err(OUT_OF_RANGE));
1279
1280        assert_eq!(Parsed::new().set_year_div_100(-1), Err(OUT_OF_RANGE));
1281        assert!(Parsed::new().set_year_div_100(0).is_ok());
1282        assert!(Parsed::new().set_year_div_100(i32::MAX as i64).is_ok());
1283        assert_eq!(Parsed::new().set_year_div_100(i32::MAX as i64 + 1), Err(OUT_OF_RANGE));
1284
1285        assert_eq!(Parsed::new().set_year_mod_100(-1), Err(OUT_OF_RANGE));
1286        assert!(Parsed::new().set_year_mod_100(0).is_ok());
1287        assert!(Parsed::new().set_year_mod_100(99).is_ok());
1288        assert_eq!(Parsed::new().set_year_mod_100(100), Err(OUT_OF_RANGE));
1289
1290        assert_eq!(Parsed::new().set_isoyear(i32::MIN as i64 - 1), Err(OUT_OF_RANGE));
1291        assert!(Parsed::new().set_isoyear(i32::MIN as i64).is_ok());
1292        assert!(Parsed::new().set_isoyear(i32::MAX as i64).is_ok());
1293        assert_eq!(Parsed::new().set_isoyear(i32::MAX as i64 + 1), Err(OUT_OF_RANGE));
1294
1295        assert_eq!(Parsed::new().set_isoyear_div_100(-1), Err(OUT_OF_RANGE));
1296        assert!(Parsed::new().set_isoyear_div_100(0).is_ok());
1297        assert!(Parsed::new().set_isoyear_div_100(99).is_ok());
1298        assert_eq!(Parsed::new().set_isoyear_div_100(i32::MAX as i64 + 1), Err(OUT_OF_RANGE));
1299
1300        assert_eq!(Parsed::new().set_isoyear_mod_100(-1), Err(OUT_OF_RANGE));
1301        assert!(Parsed::new().set_isoyear_mod_100(0).is_ok());
1302        assert!(Parsed::new().set_isoyear_mod_100(99).is_ok());
1303        assert_eq!(Parsed::new().set_isoyear_mod_100(100), Err(OUT_OF_RANGE));
1304
1305        assert_eq!(Parsed::new().set_quarter(0), Err(OUT_OF_RANGE));
1306        assert!(Parsed::new().set_quarter(1).is_ok());
1307        assert!(Parsed::new().set_quarter(4).is_ok());
1308        assert_eq!(Parsed::new().set_quarter(5), Err(OUT_OF_RANGE));
1309
1310        assert_eq!(Parsed::new().set_month(0), Err(OUT_OF_RANGE));
1311        assert!(Parsed::new().set_month(1).is_ok());
1312        assert!(Parsed::new().set_month(12).is_ok());
1313        assert_eq!(Parsed::new().set_month(13), Err(OUT_OF_RANGE));
1314
1315        assert_eq!(Parsed::new().set_week_from_sun(-1), Err(OUT_OF_RANGE));
1316        assert!(Parsed::new().set_week_from_sun(0).is_ok());
1317        assert!(Parsed::new().set_week_from_sun(53).is_ok());
1318        assert_eq!(Parsed::new().set_week_from_sun(54), Err(OUT_OF_RANGE));
1319
1320        assert_eq!(Parsed::new().set_week_from_mon(-1), Err(OUT_OF_RANGE));
1321        assert!(Parsed::new().set_week_from_mon(0).is_ok());
1322        assert!(Parsed::new().set_week_from_mon(53).is_ok());
1323        assert_eq!(Parsed::new().set_week_from_mon(54), Err(OUT_OF_RANGE));
1324
1325        assert_eq!(Parsed::new().set_isoweek(0), Err(OUT_OF_RANGE));
1326        assert!(Parsed::new().set_isoweek(1).is_ok());
1327        assert!(Parsed::new().set_isoweek(53).is_ok());
1328        assert_eq!(Parsed::new().set_isoweek(54), Err(OUT_OF_RANGE));
1329
1330        assert_eq!(Parsed::new().set_ordinal(0), Err(OUT_OF_RANGE));
1331        assert!(Parsed::new().set_ordinal(1).is_ok());
1332        assert!(Parsed::new().set_ordinal(366).is_ok());
1333        assert_eq!(Parsed::new().set_ordinal(367), Err(OUT_OF_RANGE));
1334
1335        assert_eq!(Parsed::new().set_day(0), Err(OUT_OF_RANGE));
1336        assert!(Parsed::new().set_day(1).is_ok());
1337        assert!(Parsed::new().set_day(31).is_ok());
1338        assert_eq!(Parsed::new().set_day(32), Err(OUT_OF_RANGE));
1339
1340        assert_eq!(Parsed::new().set_hour12(0), Err(OUT_OF_RANGE));
1341        assert!(Parsed::new().set_hour12(1).is_ok());
1342        assert!(Parsed::new().set_hour12(12).is_ok());
1343        assert_eq!(Parsed::new().set_hour12(13), Err(OUT_OF_RANGE));
1344
1345        assert_eq!(Parsed::new().set_hour(-1), Err(OUT_OF_RANGE));
1346        assert!(Parsed::new().set_hour(0).is_ok());
1347        assert!(Parsed::new().set_hour(23).is_ok());
1348        assert_eq!(Parsed::new().set_hour(24), Err(OUT_OF_RANGE));
1349
1350        assert_eq!(Parsed::new().set_minute(-1), Err(OUT_OF_RANGE));
1351        assert!(Parsed::new().set_minute(0).is_ok());
1352        assert!(Parsed::new().set_minute(59).is_ok());
1353        assert_eq!(Parsed::new().set_minute(60), Err(OUT_OF_RANGE));
1354
1355        assert_eq!(Parsed::new().set_second(-1), Err(OUT_OF_RANGE));
1356        assert!(Parsed::new().set_second(0).is_ok());
1357        assert!(Parsed::new().set_second(60).is_ok());
1358        assert_eq!(Parsed::new().set_second(61), Err(OUT_OF_RANGE));
1359
1360        assert_eq!(Parsed::new().set_nanosecond(-1), Err(OUT_OF_RANGE));
1361        assert!(Parsed::new().set_nanosecond(0).is_ok());
1362        assert!(Parsed::new().set_nanosecond(999_999_999).is_ok());
1363        assert_eq!(Parsed::new().set_nanosecond(1_000_000_000), Err(OUT_OF_RANGE));
1364
1365        assert!(Parsed::new().set_timestamp(i64::MIN).is_ok());
1366        assert!(Parsed::new().set_timestamp(i64::MAX).is_ok());
1367
1368        assert_eq!(Parsed::new().set_offset(i32::MIN as i64 - 1), Err(OUT_OF_RANGE));
1369        assert!(Parsed::new().set_offset(i32::MIN as i64).is_ok());
1370        assert!(Parsed::new().set_offset(i32::MAX as i64).is_ok());
1371        assert_eq!(Parsed::new().set_offset(i32::MAX as i64 + 1), Err(OUT_OF_RANGE));
1372    }
1373
1374    #[test]
1375    fn test_parsed_to_naive_date() {
1376        macro_rules! parse {
1377            ($($k:ident: $v:expr),*) => (
1378                Parsed { $($k: Some($v),)* ..Parsed::new() }.to_naive_date()
1379            )
1380        }
1381
1382        let ymd = |y, m, d| Ok(NaiveDate::from_ymd_opt(y, m, d).unwrap());
1383
1384        assert_eq!(parse!(), Err(NOT_ENOUGH));
1386        assert_eq!(parse!(year: 1984), Err(NOT_ENOUGH));
1387        assert_eq!(parse!(year: 1984, month: 1), Err(NOT_ENOUGH));
1388        assert_eq!(parse!(year: 1984, month: 1, day: 2), ymd(1984, 1, 2));
1389        assert_eq!(parse!(year: 1984, day: 2), Err(NOT_ENOUGH));
1390        assert_eq!(parse!(year_div_100: 19), Err(NOT_ENOUGH));
1391        assert_eq!(parse!(year_div_100: 19, year_mod_100: 84), Err(NOT_ENOUGH));
1392        assert_eq!(parse!(year_div_100: 19, year_mod_100: 84, month: 1), Err(NOT_ENOUGH));
1393        assert_eq!(parse!(year_div_100: 19, year_mod_100: 84, month: 1, day: 2), ymd(1984, 1, 2));
1394        assert_eq!(parse!(year_div_100: 19, year_mod_100: 84, day: 2), Err(NOT_ENOUGH));
1395        assert_eq!(parse!(year_div_100: 19, month: 1, day: 2), Err(NOT_ENOUGH));
1396        assert_eq!(parse!(year_mod_100: 70, month: 1, day: 2), ymd(1970, 1, 2));
1397        assert_eq!(parse!(year_mod_100: 69, month: 1, day: 2), ymd(2069, 1, 2));
1398
1399        assert_eq!(parse!(year_div_100: 19, year_mod_100: 84, month: 2, day: 29), ymd(1984, 2, 29));
1401        assert_eq!(
1402            parse!(year_div_100: 19, year_mod_100: 83, month: 2, day: 29),
1403            Err(OUT_OF_RANGE)
1404        );
1405        assert_eq!(
1406            parse!(year_div_100: 19, year_mod_100: 83, month: 13, day: 1),
1407            Err(OUT_OF_RANGE)
1408        );
1409        assert_eq!(
1410            parse!(year_div_100: 19, year_mod_100: 83, month: 12, day: 31),
1411            ymd(1983, 12, 31)
1412        );
1413        assert_eq!(
1414            parse!(year_div_100: 19, year_mod_100: 83, month: 12, day: 32),
1415            Err(OUT_OF_RANGE)
1416        );
1417        assert_eq!(
1418            parse!(year_div_100: 19, year_mod_100: 83, month: 12, day: 0),
1419            Err(OUT_OF_RANGE)
1420        );
1421        assert_eq!(
1422            parse!(year_div_100: 19, year_mod_100: 100, month: 1, day: 1),
1423            Err(OUT_OF_RANGE)
1424        );
1425        assert_eq!(parse!(year_div_100: 19, year_mod_100: -1, month: 1, day: 1), Err(OUT_OF_RANGE));
1426        assert_eq!(parse!(year_div_100: 0, year_mod_100: 0, month: 1, day: 1), ymd(0, 1, 1));
1427        assert_eq!(parse!(year_div_100: -1, year_mod_100: 42, month: 1, day: 1), Err(IMPOSSIBLE));
1428        let max_year = NaiveDate::MAX.year();
1429        assert_eq!(
1430            parse!(year_div_100: max_year / 100,
1431                          year_mod_100: max_year % 100, month: 1, day: 1),
1432            ymd(max_year, 1, 1)
1433        );
1434        assert_eq!(
1435            parse!(year_div_100: (max_year + 1) / 100,
1436                          year_mod_100: (max_year + 1) % 100, month: 1, day: 1),
1437            Err(OUT_OF_RANGE)
1438        );
1439
1440        assert_eq!(parse!(year: 1984, year_div_100: 19, month: 1, day: 1), ymd(1984, 1, 1));
1442        assert_eq!(parse!(year: 1984, year_div_100: 20, month: 1, day: 1), Err(IMPOSSIBLE));
1443        assert_eq!(parse!(year: 1984, year_mod_100: 84, month: 1, day: 1), ymd(1984, 1, 1));
1444        assert_eq!(parse!(year: 1984, year_mod_100: 83, month: 1, day: 1), Err(IMPOSSIBLE));
1445        assert_eq!(
1446            parse!(year: 1984, year_div_100: 19, year_mod_100: 84, month: 1, day: 1),
1447            ymd(1984, 1, 1)
1448        );
1449        assert_eq!(
1450            parse!(year: 1984, year_div_100: 18, year_mod_100: 94, month: 1, day: 1),
1451            Err(IMPOSSIBLE)
1452        );
1453        assert_eq!(
1454            parse!(year: 1984, year_div_100: 18, year_mod_100: 184, month: 1, day: 1),
1455            Err(OUT_OF_RANGE)
1456        );
1457        assert_eq!(
1458            parse!(year: -1, year_div_100: 0, year_mod_100: -1, month: 1, day: 1),
1459            Err(OUT_OF_RANGE)
1460        );
1461        assert_eq!(
1462            parse!(year: -1, year_div_100: -1, year_mod_100: 99, month: 1, day: 1),
1463            Err(IMPOSSIBLE)
1464        );
1465        assert_eq!(parse!(year: -1, year_div_100: 0, month: 1, day: 1), Err(IMPOSSIBLE));
1466        assert_eq!(parse!(year: -1, year_mod_100: 99, month: 1, day: 1), Err(IMPOSSIBLE));
1467
1468        assert_eq!(parse!(year: 2000, quarter: 1), Err(NOT_ENOUGH));
1470        assert_eq!(parse!(year: 2000, quarter: 1, month: 1, day: 1), ymd(2000, 1, 1));
1471        assert_eq!(parse!(year: 2000, quarter: 2, month: 4, day: 1), ymd(2000, 4, 1));
1472        assert_eq!(parse!(year: 2000, quarter: 3, month: 7, day: 1), ymd(2000, 7, 1));
1473        assert_eq!(parse!(year: 2000, quarter: 4, month: 10, day: 1), ymd(2000, 10, 1));
1474
1475        assert_eq!(parse!(year: 2000, quarter: 2, month: 3, day: 31), Err(IMPOSSIBLE));
1477        assert_eq!(parse!(year: 2000, quarter: 4, month: 3, day: 31), Err(IMPOSSIBLE));
1478
1479        assert_eq!(parse!(year: 2000, week_from_mon: 0), Err(NOT_ENOUGH));
1481        assert_eq!(parse!(year: 2000, week_from_sun: 0), Err(NOT_ENOUGH));
1482        assert_eq!(parse!(year: 2000, weekday: Sun), Err(NOT_ENOUGH));
1483        assert_eq!(parse!(year: 2000, week_from_mon: 0, weekday: Fri), Err(IMPOSSIBLE));
1484        assert_eq!(parse!(year: 2000, week_from_sun: 0, weekday: Fri), Err(IMPOSSIBLE));
1485        assert_eq!(parse!(year: 2000, week_from_mon: 0, weekday: Sat), ymd(2000, 1, 1));
1486        assert_eq!(parse!(year: 2000, week_from_sun: 0, weekday: Sat), ymd(2000, 1, 1));
1487        assert_eq!(parse!(year: 2000, week_from_mon: 0, weekday: Sun), ymd(2000, 1, 2));
1488        assert_eq!(parse!(year: 2000, week_from_sun: 1, weekday: Sun), ymd(2000, 1, 2));
1489        assert_eq!(parse!(year: 2000, week_from_mon: 1, weekday: Mon), ymd(2000, 1, 3));
1490        assert_eq!(parse!(year: 2000, week_from_sun: 1, weekday: Mon), ymd(2000, 1, 3));
1491        assert_eq!(parse!(year: 2000, week_from_mon: 1, weekday: Sat), ymd(2000, 1, 8));
1492        assert_eq!(parse!(year: 2000, week_from_sun: 1, weekday: Sat), ymd(2000, 1, 8));
1493        assert_eq!(parse!(year: 2000, week_from_mon: 1, weekday: Sun), ymd(2000, 1, 9));
1494        assert_eq!(parse!(year: 2000, week_from_sun: 2, weekday: Sun), ymd(2000, 1, 9));
1495        assert_eq!(parse!(year: 2000, week_from_mon: 2, weekday: Mon), ymd(2000, 1, 10));
1496        assert_eq!(parse!(year: 2000, week_from_sun: 52, weekday: Sat), ymd(2000, 12, 30));
1497        assert_eq!(parse!(year: 2000, week_from_sun: 53, weekday: Sun), ymd(2000, 12, 31));
1498        assert_eq!(parse!(year: 2000, week_from_sun: 53, weekday: Mon), Err(IMPOSSIBLE));
1499        assert_eq!(parse!(year: 2000, week_from_sun: 0xffffffff, weekday: Mon), Err(OUT_OF_RANGE));
1500        assert_eq!(parse!(year: 2006, week_from_sun: 0, weekday: Sat), Err(IMPOSSIBLE));
1501        assert_eq!(parse!(year: 2006, week_from_sun: 1, weekday: Sun), ymd(2006, 1, 1));
1502
1503        assert_eq!(
1505            parse!(year: 2000, week_from_mon: 1, week_from_sun: 1, weekday: Sat),
1506            ymd(2000, 1, 8)
1507        );
1508        assert_eq!(
1509            parse!(year: 2000, week_from_mon: 1, week_from_sun: 2, weekday: Sun),
1510            ymd(2000, 1, 9)
1511        );
1512        assert_eq!(
1513            parse!(year: 2000, week_from_mon: 1, week_from_sun: 1, weekday: Sun),
1514            Err(IMPOSSIBLE)
1515        );
1516        assert_eq!(
1517            parse!(year: 2000, week_from_mon: 2, week_from_sun: 2, weekday: Sun),
1518            Err(IMPOSSIBLE)
1519        );
1520
1521        assert_eq!(parse!(isoyear: 2004, isoweek: 53), Err(NOT_ENOUGH));
1523        assert_eq!(parse!(isoyear: 2004, isoweek: 53, weekday: Fri), ymd(2004, 12, 31));
1524        assert_eq!(parse!(isoyear: 2004, isoweek: 53, weekday: Sat), ymd(2005, 1, 1));
1525        assert_eq!(parse!(isoyear: 2004, isoweek: 0xffffffff, weekday: Sat), Err(OUT_OF_RANGE));
1526        assert_eq!(parse!(isoyear: 2005, isoweek: 0, weekday: Thu), Err(OUT_OF_RANGE));
1527        assert_eq!(parse!(isoyear: 2005, isoweek: 5, weekday: Thu), ymd(2005, 2, 3));
1528        assert_eq!(parse!(isoyear: 2005, weekday: Thu), Err(NOT_ENOUGH));
1529
1530        assert_eq!(parse!(ordinal: 123), Err(NOT_ENOUGH));
1532        assert_eq!(parse!(year: 2000, ordinal: 0), Err(OUT_OF_RANGE));
1533        assert_eq!(parse!(year: 2000, ordinal: 1), ymd(2000, 1, 1));
1534        assert_eq!(parse!(year: 2000, ordinal: 60), ymd(2000, 2, 29));
1535        assert_eq!(parse!(year: 2000, ordinal: 61), ymd(2000, 3, 1));
1536        assert_eq!(parse!(year: 2000, ordinal: 366), ymd(2000, 12, 31));
1537        assert_eq!(parse!(year: 2000, ordinal: 367), Err(OUT_OF_RANGE));
1538        assert_eq!(parse!(year: 2000, ordinal: 0xffffffff), Err(OUT_OF_RANGE));
1539        assert_eq!(parse!(year: 2100, ordinal: 0), Err(OUT_OF_RANGE));
1540        assert_eq!(parse!(year: 2100, ordinal: 1), ymd(2100, 1, 1));
1541        assert_eq!(parse!(year: 2100, ordinal: 59), ymd(2100, 2, 28));
1542        assert_eq!(parse!(year: 2100, ordinal: 60), ymd(2100, 3, 1));
1543        assert_eq!(parse!(year: 2100, ordinal: 365), ymd(2100, 12, 31));
1544        assert_eq!(parse!(year: 2100, ordinal: 366), Err(OUT_OF_RANGE));
1545        assert_eq!(parse!(year: 2100, ordinal: 0xffffffff), Err(OUT_OF_RANGE));
1546
1547        assert_eq!(
1549            parse!(year: 2014, month: 12, day: 31, ordinal: 365, isoyear: 2015, isoweek: 1,
1550                          week_from_sun: 52, week_from_mon: 52, weekday: Wed),
1551            ymd(2014, 12, 31)
1552        );
1553        assert_eq!(
1554            parse!(year: 2014, month: 12, ordinal: 365, isoyear: 2015, isoweek: 1,
1555                          week_from_sun: 52, week_from_mon: 52),
1556            ymd(2014, 12, 31)
1557        );
1558        assert_eq!(
1559            parse!(year: 2014, month: 12, day: 31, ordinal: 365, isoyear: 2014, isoweek: 53,
1560                          week_from_sun: 52, week_from_mon: 52, weekday: Wed),
1561            Err(IMPOSSIBLE)
1562        ); assert_eq!(
1564            parse!(year: 2012, isoyear: 2015, isoweek: 1,
1565                          week_from_sun: 52, week_from_mon: 52),
1566            Err(NOT_ENOUGH)
1567        ); assert_eq!(parse!(year_div_100: 20, isoyear_mod_100: 15, ordinal: 366), Err(NOT_ENOUGH));
1569        }
1571
1572    #[test]
1573    fn test_parsed_to_naive_time() {
1574        macro_rules! parse {
1575            ($($k:ident: $v:expr),*) => (
1576                Parsed { $($k: Some($v),)* ..Parsed::new() }.to_naive_time()
1577            )
1578        }
1579
1580        let hms = |h, m, s| Ok(NaiveTime::from_hms_opt(h, m, s).unwrap());
1581        let hmsn = |h, m, s, n| Ok(NaiveTime::from_hms_nano_opt(h, m, s, n).unwrap());
1582
1583        assert_eq!(parse!(), Err(NOT_ENOUGH));
1585        assert_eq!(parse!(hour_div_12: 0), Err(NOT_ENOUGH));
1586        assert_eq!(parse!(hour_div_12: 0, hour_mod_12: 1), Err(NOT_ENOUGH));
1587        assert_eq!(parse!(hour_div_12: 0, hour_mod_12: 1, minute: 23), hms(1, 23, 0));
1588        assert_eq!(parse!(hour_div_12: 0, hour_mod_12: 1, minute: 23, second: 45), hms(1, 23, 45));
1589        assert_eq!(
1590            parse!(hour_div_12: 0, hour_mod_12: 1, minute: 23, second: 45,
1591                          nanosecond: 678_901_234),
1592            hmsn(1, 23, 45, 678_901_234)
1593        );
1594        assert_eq!(parse!(hour_div_12: 1, hour_mod_12: 11, minute: 45, second: 6), hms(23, 45, 6));
1595        assert_eq!(parse!(hour_mod_12: 1, minute: 23), Err(NOT_ENOUGH));
1596        assert_eq!(
1597            parse!(hour_div_12: 0, hour_mod_12: 1, minute: 23, nanosecond: 456_789_012),
1598            Err(NOT_ENOUGH)
1599        );
1600
1601        assert_eq!(parse!(hour_div_12: 2, hour_mod_12: 0, minute: 0), Err(OUT_OF_RANGE));
1603        assert_eq!(parse!(hour_div_12: 1, hour_mod_12: 12, minute: 0), Err(OUT_OF_RANGE));
1604        assert_eq!(parse!(hour_div_12: 0, hour_mod_12: 1, minute: 60), Err(OUT_OF_RANGE));
1605        assert_eq!(
1606            parse!(hour_div_12: 0, hour_mod_12: 1, minute: 23, second: 61),
1607            Err(OUT_OF_RANGE)
1608        );
1609        assert_eq!(
1610            parse!(hour_div_12: 0, hour_mod_12: 1, minute: 23, second: 34,
1611                          nanosecond: 1_000_000_000),
1612            Err(OUT_OF_RANGE)
1613        );
1614
1615        assert_eq!(
1617            parse!(hour_div_12: 0, hour_mod_12: 1, minute: 23, second: 60),
1618            hmsn(1, 23, 59, 1_000_000_000)
1619        );
1620        assert_eq!(
1621            parse!(hour_div_12: 0, hour_mod_12: 1, minute: 23, second: 60,
1622                          nanosecond: 999_999_999),
1623            hmsn(1, 23, 59, 1_999_999_999)
1624        );
1625    }
1626
1627    #[test]
1628    fn test_parsed_to_naive_datetime_with_offset() {
1629        macro_rules! parse {
1630            (offset = $offset:expr; $($k:ident: $v:expr),*) => (
1631                Parsed { $($k: Some($v),)* ..Parsed::new() }.to_naive_datetime_with_offset($offset)
1632            );
1633            ($($k:ident: $v:expr),*) => (parse!(offset = 0; $($k: $v),*))
1634        }
1635
1636        let ymdhms = |y, m, d, h, n, s| {
1637            Ok(NaiveDate::from_ymd_opt(y, m, d).unwrap().and_hms_opt(h, n, s).unwrap())
1638        };
1639        let ymdhmsn = |y, m, d, h, n, s, nano| {
1640            Ok(NaiveDate::from_ymd_opt(y, m, d).unwrap().and_hms_nano_opt(h, n, s, nano).unwrap())
1641        };
1642
1643        assert_eq!(parse!(), Err(NOT_ENOUGH));
1645        assert_eq!(
1646            parse!(year: 2015, month: 1, day: 30,
1647                          hour_div_12: 1, hour_mod_12: 2, minute: 38),
1648            ymdhms(2015, 1, 30, 14, 38, 0)
1649        );
1650        assert_eq!(
1651            parse!(year: 1997, month: 1, day: 30,
1652                          hour_div_12: 1, hour_mod_12: 2, minute: 38, second: 5),
1653            ymdhms(1997, 1, 30, 14, 38, 5)
1654        );
1655        assert_eq!(
1656            parse!(year: 2012, ordinal: 34, hour_div_12: 0, hour_mod_12: 5,
1657                          minute: 6, second: 7, nanosecond: 890_123_456),
1658            ymdhmsn(2012, 2, 3, 5, 6, 7, 890_123_456)
1659        );
1660        assert_eq!(parse!(timestamp: 0), ymdhms(1970, 1, 1, 0, 0, 0));
1661        assert_eq!(parse!(timestamp: 1, nanosecond: 0), ymdhms(1970, 1, 1, 0, 0, 1));
1662        assert_eq!(parse!(timestamp: 1, nanosecond: 1), ymdhmsn(1970, 1, 1, 0, 0, 1, 1));
1663        assert_eq!(parse!(timestamp: 1_420_000_000), ymdhms(2014, 12, 31, 4, 26, 40));
1664        assert_eq!(parse!(timestamp: -0x1_0000_0000), ymdhms(1833, 11, 24, 17, 31, 44));
1665
1666        assert_eq!(
1668            parse!(year: 2014, year_div_100: 20, year_mod_100: 14, month: 12, day: 31,
1669                          ordinal: 365, isoyear: 2015, isoyear_div_100: 20, isoyear_mod_100: 15,
1670                          isoweek: 1, week_from_sun: 52, week_from_mon: 52, weekday: Wed,
1671                          hour_div_12: 0, hour_mod_12: 4, minute: 26, second: 40,
1672                          nanosecond: 12_345_678, timestamp: 1_420_000_000),
1673            ymdhmsn(2014, 12, 31, 4, 26, 40, 12_345_678)
1674        );
1675        assert_eq!(
1676            parse!(year: 2014, year_div_100: 20, year_mod_100: 14, month: 12, day: 31,
1677                          ordinal: 365, isoyear: 2015, isoyear_div_100: 20, isoyear_mod_100: 15,
1678                          isoweek: 1, week_from_sun: 52, week_from_mon: 52, weekday: Wed,
1679                          hour_div_12: 0, hour_mod_12: 4, minute: 26, second: 40,
1680                          nanosecond: 12_345_678, timestamp: 1_419_999_999),
1681            Err(IMPOSSIBLE)
1682        );
1683        assert_eq!(
1684            parse!(offset = 32400;
1685                          year: 2014, year_div_100: 20, year_mod_100: 14, month: 12, day: 31,
1686                          ordinal: 365, isoyear: 2015, isoyear_div_100: 20, isoyear_mod_100: 15,
1687                          isoweek: 1, week_from_sun: 52, week_from_mon: 52, weekday: Wed,
1688                          hour_div_12: 0, hour_mod_12: 4, minute: 26, second: 40,
1689                          nanosecond: 12_345_678, timestamp: 1_419_967_600),
1690            ymdhmsn(2014, 12, 31, 4, 26, 40, 12_345_678)
1691        );
1692
1693        let max_days_from_year_1970 =
1695            NaiveDate::MAX.signed_duration_since(NaiveDate::from_ymd_opt(1970, 1, 1).unwrap());
1696        let year_0_from_year_1970 = NaiveDate::from_ymd_opt(0, 1, 1)
1697            .unwrap()
1698            .signed_duration_since(NaiveDate::from_ymd_opt(1970, 1, 1).unwrap());
1699        let min_days_from_year_1970 =
1700            NaiveDate::MIN.signed_duration_since(NaiveDate::from_ymd_opt(1970, 1, 1).unwrap());
1701        assert_eq!(
1702            parse!(timestamp: min_days_from_year_1970.num_seconds()),
1703            ymdhms(NaiveDate::MIN.year(), 1, 1, 0, 0, 0)
1704        );
1705        assert_eq!(
1706            parse!(timestamp: year_0_from_year_1970.num_seconds()),
1707            ymdhms(0, 1, 1, 0, 0, 0)
1708        );
1709        assert_eq!(
1710            parse!(timestamp: max_days_from_year_1970.num_seconds() + 86399),
1711            ymdhms(NaiveDate::MAX.year(), 12, 31, 23, 59, 59)
1712        );
1713
1714        assert_eq!(parse!(second: 59, timestamp: 1_341_100_798), Err(IMPOSSIBLE));
1716        assert_eq!(parse!(second: 59, timestamp: 1_341_100_799), ymdhms(2012, 6, 30, 23, 59, 59));
1717        assert_eq!(parse!(second: 59, timestamp: 1_341_100_800), Err(IMPOSSIBLE));
1718        assert_eq!(
1719            parse!(second: 60, timestamp: 1_341_100_799),
1720            ymdhmsn(2012, 6, 30, 23, 59, 59, 1_000_000_000)
1721        );
1722        assert_eq!(
1723            parse!(second: 60, timestamp: 1_341_100_800),
1724            ymdhmsn(2012, 6, 30, 23, 59, 59, 1_000_000_000)
1725        );
1726        assert_eq!(parse!(second: 0, timestamp: 1_341_100_800), ymdhms(2012, 7, 1, 0, 0, 0));
1727        assert_eq!(parse!(second: 1, timestamp: 1_341_100_800), Err(IMPOSSIBLE));
1728        assert_eq!(parse!(second: 60, timestamp: 1_341_100_801), Err(IMPOSSIBLE));
1729
1730        assert_eq!(
1733            parse!(year: 2012, ordinal: 182, hour_div_12: 1, hour_mod_12: 11,
1734                          minute: 59, second: 59, timestamp: 1_341_100_798),
1735            Err(IMPOSSIBLE)
1736        );
1737        assert_eq!(
1738            parse!(year: 2012, ordinal: 182, hour_div_12: 1, hour_mod_12: 11,
1739                          minute: 59, second: 59, timestamp: 1_341_100_799),
1740            ymdhms(2012, 6, 30, 23, 59, 59)
1741        );
1742        assert_eq!(
1743            parse!(year: 2012, ordinal: 182, hour_div_12: 1, hour_mod_12: 11,
1744                          minute: 59, second: 59, timestamp: 1_341_100_800),
1745            Err(IMPOSSIBLE)
1746        );
1747        assert_eq!(
1748            parse!(year: 2012, ordinal: 182, hour_div_12: 1, hour_mod_12: 11,
1749                          minute: 59, second: 60, timestamp: 1_341_100_799),
1750            ymdhmsn(2012, 6, 30, 23, 59, 59, 1_000_000_000)
1751        );
1752        assert_eq!(
1753            parse!(year: 2012, ordinal: 182, hour_div_12: 1, hour_mod_12: 11,
1754                          minute: 59, second: 60, timestamp: 1_341_100_800),
1755            ymdhmsn(2012, 6, 30, 23, 59, 59, 1_000_000_000)
1756        );
1757        assert_eq!(
1758            parse!(year: 2012, ordinal: 183, hour_div_12: 0, hour_mod_12: 0,
1759                          minute: 0, second: 0, timestamp: 1_341_100_800),
1760            ymdhms(2012, 7, 1, 0, 0, 0)
1761        );
1762        assert_eq!(
1763            parse!(year: 2012, ordinal: 183, hour_div_12: 0, hour_mod_12: 0,
1764                          minute: 0, second: 1, timestamp: 1_341_100_800),
1765            Err(IMPOSSIBLE)
1766        );
1767        assert_eq!(
1768            parse!(year: 2012, ordinal: 182, hour_div_12: 1, hour_mod_12: 11,
1769                          minute: 59, second: 60, timestamp: 1_341_100_801),
1770            Err(IMPOSSIBLE)
1771        );
1772
1773        assert_eq!(
1775            parse!(year: 2015, month: 1, day: 20, weekday: Tue,
1776                          hour_div_12: 2, hour_mod_12: 1, minute: 35, second: 20),
1777            Err(OUT_OF_RANGE)
1778        ); }
1780
1781    #[test]
1782    fn test_parsed_to_datetime() {
1783        macro_rules! parse {
1784            ($($k:ident: $v:expr),*) => (
1785                Parsed { $($k: Some($v),)* ..Parsed::new() }.to_datetime()
1786            )
1787        }
1788
1789        let ymdhmsn = |y, m, d, h, n, s, nano, off| {
1790            Ok(FixedOffset::east_opt(off)
1791                .unwrap()
1792                .from_local_datetime(
1793                    &NaiveDate::from_ymd_opt(y, m, d)
1794                        .unwrap()
1795                        .and_hms_nano_opt(h, n, s, nano)
1796                        .unwrap(),
1797                )
1798                .unwrap())
1799        };
1800
1801        assert_eq!(parse!(offset: 0), Err(NOT_ENOUGH));
1802        assert_eq!(
1803            parse!(year: 2014, ordinal: 365, hour_div_12: 0, hour_mod_12: 4,
1804                          minute: 26, second: 40, nanosecond: 12_345_678),
1805            Err(NOT_ENOUGH)
1806        );
1807        assert_eq!(
1808            parse!(year: 2014, ordinal: 365, hour_div_12: 0, hour_mod_12: 4,
1809                          minute: 26, second: 40, nanosecond: 12_345_678, offset: 0),
1810            ymdhmsn(2014, 12, 31, 4, 26, 40, 12_345_678, 0)
1811        );
1812        assert_eq!(
1813            parse!(year: 2014, ordinal: 365, hour_div_12: 1, hour_mod_12: 1,
1814                          minute: 26, second: 40, nanosecond: 12_345_678, offset: 32400),
1815            ymdhmsn(2014, 12, 31, 13, 26, 40, 12_345_678, 32400)
1816        );
1817        assert_eq!(
1818            parse!(year: 2014, ordinal: 365, hour_div_12: 0, hour_mod_12: 1,
1819                          minute: 42, second: 4, nanosecond: 12_345_678, offset: -9876),
1820            ymdhmsn(2014, 12, 31, 1, 42, 4, 12_345_678, -9876)
1821        );
1822        assert_eq!(
1823            parse!(year: 2015, ordinal: 1, hour_div_12: 0, hour_mod_12: 4,
1824                          minute: 26, second: 40, nanosecond: 12_345_678, offset: 86_400),
1825            Err(OUT_OF_RANGE)
1826        ); }
1828
1829    #[test]
1830    fn test_parsed_to_datetime_with_timezone() {
1831        macro_rules! parse {
1832            ($tz:expr; $($k:ident: $v:expr),*) => (
1833                Parsed { $($k: Some($v),)* ..Parsed::new() }.to_datetime_with_timezone(&$tz)
1834            )
1835        }
1836
1837        assert_eq!(
1839            parse!(Utc;
1840                          year: 2014, ordinal: 365, hour_div_12: 0, hour_mod_12: 4,
1841                          minute: 26, second: 40, nanosecond: 12_345_678, offset: 0),
1842            Ok(Utc
1843                .from_local_datetime(
1844                    &NaiveDate::from_ymd_opt(2014, 12, 31)
1845                        .unwrap()
1846                        .and_hms_nano_opt(4, 26, 40, 12_345_678)
1847                        .unwrap()
1848                )
1849                .unwrap())
1850        );
1851        assert_eq!(
1852            parse!(Utc;
1853                          year: 2014, ordinal: 365, hour_div_12: 1, hour_mod_12: 1,
1854                          minute: 26, second: 40, nanosecond: 12_345_678, offset: 32400),
1855            Err(IMPOSSIBLE)
1856        );
1857        assert_eq!(
1858            parse!(FixedOffset::east_opt(32400).unwrap();
1859                          year: 2014, ordinal: 365, hour_div_12: 0, hour_mod_12: 4,
1860                          minute: 26, second: 40, nanosecond: 12_345_678, offset: 0),
1861            Err(IMPOSSIBLE)
1862        );
1863        assert_eq!(
1864            parse!(FixedOffset::east_opt(32400).unwrap();
1865                          year: 2014, ordinal: 365, hour_div_12: 1, hour_mod_12: 1,
1866                          minute: 26, second: 40, nanosecond: 12_345_678, offset: 32400),
1867            Ok(FixedOffset::east_opt(32400)
1868                .unwrap()
1869                .from_local_datetime(
1870                    &NaiveDate::from_ymd_opt(2014, 12, 31)
1871                        .unwrap()
1872                        .and_hms_nano_opt(13, 26, 40, 12_345_678)
1873                        .unwrap()
1874                )
1875                .unwrap())
1876        );
1877
1878        assert_eq!(
1880            parse!(Utc; timestamp: 1_420_000_000, offset: 0),
1881            Ok(Utc.with_ymd_and_hms(2014, 12, 31, 4, 26, 40).unwrap())
1882        );
1883        assert_eq!(parse!(Utc; timestamp: 1_420_000_000, offset: 32400), Err(IMPOSSIBLE));
1884        assert_eq!(
1885            parse!(FixedOffset::east_opt(32400).unwrap(); timestamp: 1_420_000_000, offset: 0),
1886            Err(IMPOSSIBLE)
1887        );
1888        assert_eq!(
1889            parse!(FixedOffset::east_opt(32400).unwrap(); timestamp: 1_420_000_000, offset: 32400),
1890            Ok(FixedOffset::east_opt(32400)
1891                .unwrap()
1892                .with_ymd_and_hms(2014, 12, 31, 13, 26, 40)
1893                .unwrap())
1894        );
1895
1896        }
1898
1899    #[test]
1900    fn issue_551() {
1901        use crate::Weekday;
1902        let mut parsed = Parsed::new();
1903
1904        parsed.year = Some(2002);
1905        parsed.week_from_mon = Some(22);
1906        parsed.weekday = Some(Weekday::Mon);
1907        assert_eq!(NaiveDate::from_ymd_opt(2002, 6, 3).unwrap(), parsed.to_naive_date().unwrap());
1908
1909        parsed.year = Some(2001);
1910        assert_eq!(NaiveDate::from_ymd_opt(2001, 5, 28).unwrap(), parsed.to_naive_date().unwrap());
1911    }
1912}