summaryrefslogtreecommitdiffstats
path: root/vendor/chrono/src/naive
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/chrono/src/naive')
-rw-r--r--vendor/chrono/src/naive/date.rs1765
-rw-r--r--vendor/chrono/src/naive/datetime.rs2507
-rw-r--r--vendor/chrono/src/naive/datetime/mod.rs1946
-rw-r--r--vendor/chrono/src/naive/datetime/rustc_serialize.rs73
-rw-r--r--vendor/chrono/src/naive/datetime/serde.rs1133
-rw-r--r--vendor/chrono/src/naive/datetime/tests.rs343
-rw-r--r--vendor/chrono/src/naive/internals.rs277
-rw-r--r--vendor/chrono/src/naive/isoweek.rs66
-rw-r--r--vendor/chrono/src/naive/mod.rs39
-rw-r--r--vendor/chrono/src/naive/time/mod.rs (renamed from vendor/chrono/src/naive/time.rs)940
-rw-r--r--vendor/chrono/src/naive/time/rustc_serialize.rs29
-rw-r--r--vendor/chrono/src/naive/time/serde.rs65
-rw-r--r--vendor/chrono/src/naive/time/tests.rs317
13 files changed, 5562 insertions, 3938 deletions
diff --git a/vendor/chrono/src/naive/date.rs b/vendor/chrono/src/naive/date.rs
index 3e34e2074..64af978f3 100644
--- a/vendor/chrono/src/naive/date.rs
+++ b/vendor/chrono/src/naive/date.rs
@@ -5,18 +5,27 @@
#[cfg(any(feature = "alloc", feature = "std", test))]
use core::borrow::Borrow;
-use core::ops::{Add, AddAssign, Sub, SubAssign};
+use core::convert::TryFrom;
+use core::ops::{Add, AddAssign, RangeInclusive, Sub, SubAssign};
use core::{fmt, str};
+
+use num_integer::div_mod_floor;
use num_traits::ToPrimitive;
-use oldtime::Duration as OldDuration;
+#[cfg(feature = "rkyv")]
+use rkyv::{Archive, Deserialize, Serialize};
+
+/// L10n locales.
+#[cfg(feature = "unstable-locales")]
+use pure_rust_locales::Locale;
-use div::div_mod_floor;
#[cfg(any(feature = "alloc", feature = "std", test))]
-use format::DelayedFormat;
-use format::{parse, ParseError, ParseResult, Parsed, StrftimeItems};
-use format::{Item, Numeric, Pad};
-use naive::{IsoWeek, NaiveDateTime, NaiveTime};
-use {Datelike, Weekday};
+use crate::format::DelayedFormat;
+use crate::format::{parse, write_hundreds, ParseError, ParseResult, Parsed, StrftimeItems};
+use crate::format::{Item, Numeric, Pad};
+use crate::month::Months;
+use crate::naive::{IsoWeek, NaiveDateTime, NaiveTime};
+use crate::oldtime::Duration as OldDuration;
+use crate::{Datelike, Duration, Weekday};
use super::internals::{self, DateImpl, Mdf, Of, YearFlags};
use super::isoweek;
@@ -42,11 +51,91 @@ const MAX_DAYS_FROM_YEAR_0: i32 =
const MIN_DAYS_FROM_YEAR_0: i32 = (MIN_YEAR + 400_000) * 365 + (MIN_YEAR + 400_000) / 4
- (MIN_YEAR + 400_000) / 100
+ (MIN_YEAR + 400_000) / 400
- - 146097_000;
+ - 146_097_000;
#[cfg(test)] // only used for testing, but duplicated in naive::datetime
const MAX_BITS: usize = 44;
+/// A week represented by a [`NaiveDate`] and a [`Weekday`] which is the first
+/// day of the week.
+#[derive(Debug)]
+pub struct NaiveWeek {
+ date: NaiveDate,
+ start: Weekday,
+}
+
+impl NaiveWeek {
+ /// Returns a date representing the first day of the week.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, Weekday};
+ ///
+ /// let date = NaiveDate::from_ymd_opt(2022, 4, 18).unwrap();
+ /// let week = date.week(Weekday::Mon);
+ /// assert!(week.first_day() <= date);
+ /// ```
+ #[inline]
+ pub fn first_day(&self) -> NaiveDate {
+ let start = self.start.num_days_from_monday();
+ let end = self.date.weekday().num_days_from_monday();
+ let days = if start > end { 7 - start + end } else { end - start };
+ self.date - Duration::days(days.into())
+ }
+
+ /// Returns a date representing the last day of the week.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, Weekday};
+ ///
+ /// let date = NaiveDate::from_ymd_opt(2022, 4, 18).unwrap();
+ /// let week = date.week(Weekday::Mon);
+ /// assert!(week.last_day() >= date);
+ /// ```
+ #[inline]
+ pub fn last_day(&self) -> NaiveDate {
+ self.first_day() + Duration::days(6)
+ }
+
+ /// Returns a [`RangeInclusive<T>`] representing the whole week bounded by
+ /// [first_day](./struct.NaiveWeek.html#method.first_day) and
+ /// [last_day](./struct.NaiveWeek.html#method.last_day) functions.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, Weekday};
+ ///
+ /// let date = NaiveDate::from_ymd_opt(2022, 4, 18).unwrap();
+ /// let week = date.week(Weekday::Mon);
+ /// let days = week.days();
+ /// assert!(days.contains(&date));
+ /// ```
+ #[inline]
+ pub fn days(&self) -> RangeInclusive<NaiveDate> {
+ self.first_day()..=self.last_day()
+ }
+}
+
+/// A duration in calendar days.
+///
+/// This is useful because when using `Duration` it is possible
+/// that adding `Duration::days(1)` doesn't increment the day value as expected due to it being a
+/// fixed number of seconds. This difference applies only when dealing with `DateTime<TimeZone>` data types
+/// and in other cases `Duration::days(n)` and `Days::new(n)` are equivalent.
+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd)]
+pub struct Days(pub(crate) u64);
+
+impl Days {
+ /// Construct a new `Days` from a number of days
+ pub const fn new(num: u64) -> Self {
+ Self(num)
+ }
+}
+
/// ISO 8601 calendar date without timezone.
/// Allows for every [proleptic Gregorian date](#calendar-date)
/// from Jan 1, 262145 BCE to Dec 31, 262143 CE.
@@ -96,35 +185,48 @@ const MAX_BITS: usize = 44;
///
/// This is currently the internal format of Chrono's date types.
#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Copy, Clone)]
+#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
pub struct NaiveDate {
ymdf: DateImpl, // (year << 13) | of
}
/// The minimum possible `NaiveDate` (January 1, 262145 BCE).
-pub const MIN_DATE: NaiveDate = NaiveDate { ymdf: (MIN_YEAR << 13) | (1 << 4) | 0o07 /*FE*/ };
+#[deprecated(since = "0.4.20", note = "Use NaiveDate::MIN instead")]
+pub const MIN_DATE: NaiveDate = NaiveDate::MIN;
/// The maximum possible `NaiveDate` (December 31, 262143 CE).
-pub const MAX_DATE: NaiveDate = NaiveDate { ymdf: (MAX_YEAR << 13) | (365 << 4) | 0o17 /*F*/ };
+#[deprecated(since = "0.4.20", note = "Use NaiveDate::MAX instead")]
+pub const MAX_DATE: NaiveDate = NaiveDate::MAX;
+
+#[cfg(feature = "arbitrary")]
+impl arbitrary::Arbitrary<'_> for NaiveDate {
+ fn arbitrary(u: &mut arbitrary::Unstructured) -> arbitrary::Result<NaiveDate> {
+ let year = u.int_in_range(MIN_YEAR..=MAX_YEAR)?;
+ let max_days = YearFlags::from_year(year).ndays();
+ let ord = u.int_in_range(1..=max_days)?;
+ NaiveDate::from_yo_opt(year, ord).ok_or(arbitrary::Error::IncorrectFormat)
+ }
+}
-// as it is hard to verify year flags in `MIN_DATE` and `MAX_DATE`,
+// as it is hard to verify year flags in `NaiveDate::MIN` and `NaiveDate::MAX`,
// we use a separate run-time test.
#[test]
fn test_date_bounds() {
- let calculated_min = NaiveDate::from_ymd(MIN_YEAR, 1, 1);
- let calculated_max = NaiveDate::from_ymd(MAX_YEAR, 12, 31);
+ let calculated_min = NaiveDate::from_ymd_opt(MIN_YEAR, 1, 1).unwrap();
+ let calculated_max = NaiveDate::from_ymd_opt(MAX_YEAR, 12, 31).unwrap();
assert!(
- MIN_DATE == calculated_min,
- "`MIN_DATE` should have a year flag {:?}",
+ NaiveDate::MIN == calculated_min,
+ "`NaiveDate::MIN` should have a year flag {:?}",
calculated_min.of().flags()
);
assert!(
- MAX_DATE == calculated_max,
- "`MAX_DATE` should have a year flag {:?}",
+ NaiveDate::MAX == calculated_max,
+ "`NaiveDate::MAX` should have a year flag {:?}",
calculated_max.of().flags()
);
// let's also check that the entire range do not exceed 2^44 seconds
// (sometimes used for bounding `Duration` against overflow)
- let maxsecs = MAX_DATE.signed_duration_since(MIN_DATE).num_seconds();
+ let maxsecs = NaiveDate::MAX.signed_duration_since(NaiveDate::MIN).num_seconds();
let maxsecs = maxsecs + 86401; // also take care of DateTime
assert!(
maxsecs < (1 << MAX_BITS),
@@ -134,9 +236,12 @@ fn test_date_bounds() {
}
impl NaiveDate {
+ pub(crate) fn weeks_from(&self, day: Weekday) -> i32 {
+ (self.ordinal() as i32 - self.weekday().num_days_from(day) as i32 + 6) / 7
+ }
/// Makes a new `NaiveDate` from year and packed ordinal-flags, with a verification.
fn from_of(year: i32, of: Of) -> Option<NaiveDate> {
- if year >= MIN_YEAR && year <= MAX_YEAR && of.valid() {
+ if (MIN_YEAR..=MAX_YEAR).contains(&year) && of.valid() {
let Of(of) = of;
Some(NaiveDate { ymdf: (year << 13) | (of as DateImpl) })
} else {
@@ -153,22 +258,7 @@ impl NaiveDate {
/// (year, month and day).
///
/// Panics on the out-of-range date, invalid month and/or day.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, Datelike, Weekday};
- ///
- /// let d = NaiveDate::from_ymd(2015, 3, 14);
- /// assert_eq!(d.year(), 2015);
- /// assert_eq!(d.month(), 3);
- /// assert_eq!(d.day(), 14);
- /// assert_eq!(d.ordinal(), 73); // day of year
- /// assert_eq!(d.iso_week().year(), 2015);
- /// assert_eq!(d.iso_week().week(), 11);
- /// assert_eq!(d.weekday(), Weekday::Sat);
- /// assert_eq!(d.num_days_from_ce(), 735671); // days since January 1, 1 CE
- /// ~~~~
+ #[deprecated(since = "0.4.23", note = "use `from_ymd_opt()` instead")]
pub fn from_ymd(year: i32, month: u32, day: u32) -> NaiveDate {
NaiveDate::from_ymd_opt(year, month, day).expect("invalid or out-of-range date")
}
@@ -180,7 +270,7 @@ impl NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::NaiveDate;
///
/// let from_ymd_opt = NaiveDate::from_ymd_opt;
@@ -191,32 +281,17 @@ impl NaiveDate {
/// assert!(from_ymd_opt(-4, 2, 29).is_some()); // 5 BCE is a leap year
/// assert!(from_ymd_opt(400000, 1, 1).is_none());
/// assert!(from_ymd_opt(-400000, 1, 1).is_none());
- /// ~~~~
+ /// ```
pub fn from_ymd_opt(year: i32, month: u32, day: u32) -> Option<NaiveDate> {
let flags = YearFlags::from_year(year);
- NaiveDate::from_mdf(year, Mdf::new(month, day, flags))
+ NaiveDate::from_mdf(year, Mdf::new(month, day, flags)?)
}
/// Makes a new `NaiveDate` from the [ordinal date](#ordinal-date)
/// (year and day of the year).
///
/// Panics on the out-of-range date and/or invalid day of year.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, Datelike, Weekday};
- ///
- /// let d = NaiveDate::from_yo(2015, 73);
- /// assert_eq!(d.ordinal(), 73);
- /// assert_eq!(d.year(), 2015);
- /// assert_eq!(d.month(), 3);
- /// assert_eq!(d.day(), 14);
- /// assert_eq!(d.iso_week().year(), 2015);
- /// assert_eq!(d.iso_week().week(), 11);
- /// assert_eq!(d.weekday(), Weekday::Sat);
- /// assert_eq!(d.num_days_from_ce(), 735671); // days since January 1, 1 CE
- /// ~~~~
+ #[deprecated(since = "0.4.23", note = "use `from_yo_opt()` instead")]
pub fn from_yo(year: i32, ordinal: u32) -> NaiveDate {
NaiveDate::from_yo_opt(year, ordinal).expect("invalid or out-of-range date")
}
@@ -228,7 +303,7 @@ impl NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::NaiveDate;
///
/// let from_yo_opt = NaiveDate::from_yo_opt;
@@ -240,10 +315,10 @@ impl NaiveDate {
/// assert!(from_yo_opt(-4, 366).is_some()); // 5 BCE is a leap year
/// assert!(from_yo_opt(400000, 1).is_none());
/// assert!(from_yo_opt(-400000, 1).is_none());
- /// ~~~~
+ /// ```
pub fn from_yo_opt(year: i32, ordinal: u32) -> Option<NaiveDate> {
let flags = YearFlags::from_year(year);
- NaiveDate::from_of(year, Of::new(ordinal, flags))
+ NaiveDate::from_of(year, Of::new(ordinal, flags)?)
}
/// Makes a new `NaiveDate` from the [ISO week date](#week-date)
@@ -251,22 +326,7 @@ impl NaiveDate {
/// The resulting `NaiveDate` may have a different year from the input year.
///
/// Panics on the out-of-range date and/or invalid week number.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, Datelike, Weekday};
- ///
- /// let d = NaiveDate::from_isoywd(2015, 11, Weekday::Sat);
- /// assert_eq!(d.iso_week().year(), 2015);
- /// assert_eq!(d.iso_week().week(), 11);
- /// assert_eq!(d.weekday(), Weekday::Sat);
- /// assert_eq!(d.year(), 2015);
- /// assert_eq!(d.month(), 3);
- /// assert_eq!(d.day(), 14);
- /// assert_eq!(d.ordinal(), 73); // day of year
- /// assert_eq!(d.num_days_from_ce(), 735671); // days since January 1, 1 CE
- /// ~~~~
+ #[deprecated(since = "0.4.23", note = "use `from_isoywd_opt()` instead")]
pub fn from_isoywd(year: i32, week: u32, weekday: Weekday) -> NaiveDate {
NaiveDate::from_isoywd_opt(year, week, weekday).expect("invalid or out-of-range date")
}
@@ -279,7 +339,7 @@ impl NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Weekday};
///
/// let from_ymd = NaiveDate::from_ymd;
@@ -292,11 +352,11 @@ impl NaiveDate {
///
/// assert_eq!(from_isoywd_opt(400000, 10, Weekday::Fri), None);
/// assert_eq!(from_isoywd_opt(-400000, 10, Weekday::Sat), None);
- /// ~~~~
+ /// ```
///
/// The year number of ISO week date may differ from that of the calendar date.
///
- /// ~~~~
+ /// ```
/// # use chrono::{NaiveDate, Weekday};
/// # let from_ymd = NaiveDate::from_ymd;
/// # let from_isoywd_opt = NaiveDate::from_isoywd_opt;
@@ -314,7 +374,7 @@ impl NaiveDate {
/// assert_eq!(from_isoywd_opt(2015, 53, Weekday::Sun), Some(from_ymd(2016, 1, 3)));
/// assert_eq!(from_isoywd_opt(2015, 54, Weekday::Mon), None);
/// assert_eq!(from_isoywd_opt(2016, 1, Weekday::Mon), Some(from_ymd(2016, 1, 4)));
- /// ~~~~
+ /// ```
pub fn from_isoywd_opt(year: i32, week: u32, weekday: Weekday) -> Option<NaiveDate> {
let flags = YearFlags::from_year(year);
let nweeks = flags.nisoweeks();
@@ -327,18 +387,18 @@ impl NaiveDate {
let prevflags = YearFlags::from_year(year - 1);
NaiveDate::from_of(
year - 1,
- Of::new(weekord + prevflags.ndays() - delta, prevflags),
+ Of::new(weekord + prevflags.ndays() - delta, prevflags)?,
)
} else {
let ordinal = weekord - delta;
let ndays = flags.ndays();
if ordinal <= ndays {
// this year
- NaiveDate::from_of(year, Of::new(ordinal, flags))
+ NaiveDate::from_of(year, Of::new(ordinal, flags)?)
} else {
// ordinal > ndays, next year
let nextflags = YearFlags::from_year(year + 1);
- NaiveDate::from_of(year + 1, Of::new(ordinal - ndays, nextflags))
+ NaiveDate::from_of(year + 1, Of::new(ordinal - ndays, nextflags)?)
}
}
} else {
@@ -350,45 +410,7 @@ impl NaiveDate {
/// January 1, 1 being day 1.
///
/// Panics if the date is out of range.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, Datelike, Weekday};
- ///
- /// let d = NaiveDate::from_num_days_from_ce(735671);
- /// assert_eq!(d.num_days_from_ce(), 735671); // days since January 1, 1 CE
- /// assert_eq!(d.year(), 2015);
- /// assert_eq!(d.month(), 3);
- /// assert_eq!(d.day(), 14);
- /// assert_eq!(d.ordinal(), 73); // day of year
- /// assert_eq!(d.iso_week().year(), 2015);
- /// assert_eq!(d.iso_week().week(), 11);
- /// assert_eq!(d.weekday(), Weekday::Sat);
- /// ~~~~
- ///
- /// While not directly supported by Chrono,
- /// it is easy to convert from the Julian day number
- /// (January 1, 4713 BCE in the *Julian* calendar being Day 0)
- /// to Gregorian with this method.
- /// (Note that this panics when `jd` is out of range.)
- ///
- /// ~~~~
- /// use chrono::NaiveDate;
- ///
- /// fn jd_to_date(jd: i32) -> NaiveDate {
- /// // keep in mind that the Julian day number is 0-based
- /// // while this method requires an 1-based number.
- /// NaiveDate::from_num_days_from_ce(jd - 1721425)
- /// }
- ///
- /// // January 1, 4713 BCE in Julian = November 24, 4714 BCE in Gregorian
- /// assert_eq!(jd_to_date(0), NaiveDate::from_ymd(-4713, 11, 24));
- ///
- /// assert_eq!(jd_to_date(1721426), NaiveDate::from_ymd(1, 1, 1));
- /// assert_eq!(jd_to_date(2450000), NaiveDate::from_ymd(1995, 10, 9));
- /// assert_eq!(jd_to_date(2451545), NaiveDate::from_ymd(2000, 1, 1));
- /// ~~~~
+ #[deprecated(since = "0.4.23", note = "use `from_num_days_from_ce_opt()` instead")]
#[inline]
pub fn from_num_days_from_ce(days: i32) -> NaiveDate {
NaiveDate::from_num_days_from_ce_opt(days).expect("out-of-range date")
@@ -401,11 +423,11 @@ impl NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::NaiveDate;
///
/// let from_ndays_opt = NaiveDate::from_num_days_from_ce_opt;
- /// let from_ymd = NaiveDate::from_ymd;
+ /// let from_ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
///
/// assert_eq!(from_ndays_opt(730_000), Some(from_ymd(1999, 9, 3)));
/// assert_eq!(from_ndays_opt(1), Some(from_ymd(1, 1, 1)));
@@ -413,13 +435,13 @@ impl NaiveDate {
/// assert_eq!(from_ndays_opt(-1), Some(from_ymd(0, 12, 30)));
/// assert_eq!(from_ndays_opt(100_000_000), None);
/// assert_eq!(from_ndays_opt(-100_000_000), None);
- /// ~~~~
+ /// ```
pub fn from_num_days_from_ce_opt(days: i32) -> Option<NaiveDate> {
let days = days + 365; // make December 31, 1 BCE equal to day 0
let (year_div_400, cycle) = div_mod_floor(days, 146_097);
let (year_mod_400, ordinal) = internals::cycle_to_yo(cycle as u32);
let flags = YearFlags::from_year_mod_400(year_mod_400 as i32);
- NaiveDate::from_of(year_div_400 * 400 + year_mod_400 as i32, Of::new(ordinal, flags))
+ NaiveDate::from_of(year_div_400 * 400 + year_mod_400 as i32, Of::new(ordinal, flags)?)
}
/// Makes a new `NaiveDate` by counting the number of occurrences of a particular day-of-week
@@ -432,21 +454,7 @@ impl NaiveDate {
/// of `weekday` in `month` (eg. the 6th Friday of March 2017) then this function will panic.
///
/// `n` is 1-indexed. Passing `n=0` will cause a panic.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, Weekday};
- ///
- /// let from_weekday_of_month = NaiveDate::from_weekday_of_month;
- /// let from_ymd = NaiveDate::from_ymd;
- ///
- /// assert_eq!(from_weekday_of_month(2018, 8, Weekday::Wed, 1), from_ymd(2018, 8, 1));
- /// assert_eq!(from_weekday_of_month(2018, 8, Weekday::Fri, 1), from_ymd(2018, 8, 3));
- /// assert_eq!(from_weekday_of_month(2018, 8, Weekday::Tue, 2), from_ymd(2018, 8, 14));
- /// assert_eq!(from_weekday_of_month(2018, 8, Weekday::Fri, 4), from_ymd(2018, 8, 24));
- /// assert_eq!(from_weekday_of_month(2018, 8, Weekday::Fri, 5), from_ymd(2018, 8, 31));
- /// ~~~~
+ #[deprecated(since = "0.4.23", note = "use `from_weekday_of_month_opt()` instead")]
pub fn from_weekday_of_month(year: i32, month: u32, weekday: Weekday, n: u8) -> NaiveDate {
NaiveDate::from_weekday_of_month_opt(year, month, weekday, n).expect("out-of-range date")
}
@@ -455,11 +463,11 @@ impl NaiveDate {
/// since the beginning of the given month. For instance, if you want the 2nd Friday of March
/// 2017, you would use `NaiveDate::from_weekday_of_month(2017, 3, Weekday::Fri, 2)`. `n` is 1-indexed.
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Weekday};
/// assert_eq!(NaiveDate::from_weekday_of_month_opt(2017, 3, Weekday::Fri, 2),
/// NaiveDate::from_ymd_opt(2017, 3, 10))
- /// ~~~~
+ /// ```
///
/// Returns `None` if `n` out-of-range; ie. if `n` is larger than the number of `weekday` in
/// `month` (eg. the 6th Friday of March 2017), or if `n == 0`.
@@ -472,7 +480,7 @@ impl NaiveDate {
if n == 0 {
return None;
}
- let first = NaiveDate::from_ymd(year, month, 1).weekday();
+ let first = NaiveDate::from_ymd_opt(year, month, 1)?.weekday();
let first_to_dow = (7 + weekday.number_from_monday() - first.number_from_monday()) % 7;
let day = (u32::from(n) - 1) * 7 + first_to_dow + 1;
NaiveDate::from_ymd_opt(year, month, day)
@@ -484,64 +492,223 @@ impl NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::NaiveDate;
///
/// let parse_from_str = NaiveDate::parse_from_str;
///
/// assert_eq!(parse_from_str("2015-09-05", "%Y-%m-%d"),
- /// Ok(NaiveDate::from_ymd(2015, 9, 5)));
+ /// Ok(NaiveDate::from_ymd_opt(2015, 9, 5).unwrap()));
/// assert_eq!(parse_from_str("5sep2015", "%d%b%Y"),
- /// Ok(NaiveDate::from_ymd(2015, 9, 5)));
- /// ~~~~
+ /// Ok(NaiveDate::from_ymd_opt(2015, 9, 5).unwrap()));
+ /// ```
///
/// Time and offset is ignored for the purpose of parsing.
///
- /// ~~~~
+ /// ```
/// # use chrono::NaiveDate;
/// # let parse_from_str = NaiveDate::parse_from_str;
/// assert_eq!(parse_from_str("2014-5-17T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
- /// Ok(NaiveDate::from_ymd(2014, 5, 17)));
- /// ~~~~
+ /// Ok(NaiveDate::from_ymd_opt(2014, 5, 17).unwrap()));
+ /// ```
///
/// Out-of-bound dates or insufficient fields are errors.
///
- /// ~~~~
+ /// ```
/// # use chrono::NaiveDate;
/// # let parse_from_str = NaiveDate::parse_from_str;
/// assert!(parse_from_str("2015/9", "%Y/%m").is_err());
/// assert!(parse_from_str("2015/9/31", "%Y/%m/%d").is_err());
- /// ~~~~
+ /// ```
///
/// All parsed fields should be consistent to each other, otherwise it's an error.
///
- /// ~~~~
+ /// ```
/// # use chrono::NaiveDate;
/// # let parse_from_str = NaiveDate::parse_from_str;
/// assert!(parse_from_str("Sat, 09 Aug 2013", "%a, %d %b %Y").is_err());
- /// ~~~~
+ /// ```
pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveDate> {
let mut parsed = Parsed::new();
parse(&mut parsed, s, StrftimeItems::new(fmt))?;
parsed.to_naive_date()
}
+ /// Add a duration in [`Months`] to the date
+ ///
+ /// If the day would be out of range for the resulting month, use the last day for that month.
+ ///
+ /// Returns `None` if the resulting date would be out of range.
+ ///
+ /// ```
+ /// # use chrono::{NaiveDate, Months};
+ /// assert_eq!(
+ /// NaiveDate::from_ymd_opt(2022, 2, 20).unwrap().checked_add_months(Months::new(6)),
+ /// Some(NaiveDate::from_ymd_opt(2022, 8, 20).unwrap())
+ /// );
+ /// assert_eq!(
+ /// NaiveDate::from_ymd_opt(2022, 7, 31).unwrap().checked_add_months(Months::new(2)),
+ /// Some(NaiveDate::from_ymd_opt(2022, 9, 30).unwrap())
+ /// );
+ /// ```
+ pub fn checked_add_months(self, months: Months) -> Option<Self> {
+ if months.0 == 0 {
+ return Some(self);
+ }
+
+ match months.0 <= core::i32::MAX as u32 {
+ true => self.diff_months(months.0 as i32),
+ false => None,
+ }
+ }
+
+ /// Subtract a duration in [`Months`] from the date
+ ///
+ /// If the day would be out of range for the resulting month, use the last day for that month.
+ ///
+ /// Returns `None` if the resulting date would be out of range.
+ ///
+ /// ```
+ /// # use chrono::{NaiveDate, Months};
+ /// assert_eq!(
+ /// NaiveDate::from_ymd_opt(2022, 2, 20).unwrap().checked_sub_months(Months::new(6)),
+ /// Some(NaiveDate::from_ymd_opt(2021, 8, 20).unwrap())
+ /// );
+ ///
+ /// assert_eq!(
+ /// NaiveDate::from_ymd_opt(2014, 1, 1).unwrap()
+ /// .checked_sub_months(Months::new(core::i32::MAX as u32 + 1)),
+ /// None
+ /// );
+ /// ```
+ pub fn checked_sub_months(self, months: Months) -> Option<Self> {
+ if months.0 == 0 {
+ return Some(self);
+ }
+
+ // Copy `i32::MAX` here so we don't have to do a complicated cast
+ match months.0 <= 2_147_483_647 {
+ true => self.diff_months(-(months.0 as i32)),
+ false => None,
+ }
+ }
+
+ fn diff_months(self, months: i32) -> Option<Self> {
+ let (years, left) = ((months / 12), (months % 12));
+
+ // Determine new year (without taking months into account for now
+
+ let year = if (years > 0 && years > (MAX_YEAR - self.year()))
+ || (years < 0 && years < (MIN_YEAR - self.year()))
+ {
+ return None;
+ } else {
+ self.year() + years
+ };
+
+ // Determine new month
+
+ let month = self.month() as i32 + left;
+ let (year, month) = if month <= 0 {
+ if year == MIN_YEAR {
+ return None;
+ }
+
+ (year - 1, month + 12)
+ } else if month > 12 {
+ if year == MAX_YEAR {
+ return None;
+ }
+
+ (year + 1, month - 12)
+ } else {
+ (year, month)
+ };
+
+ // Clamp original day in case new month is shorter
+
+ let flags = YearFlags::from_year(year);
+ let feb_days = if flags.ndays() == 366 { 29 } else { 28 };
+ let days = [31, feb_days, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+ let day = Ord::min(self.day(), days[(month - 1) as usize]);
+
+ NaiveDate::from_mdf(year, Mdf::new(month as u32, day, flags)?)
+ }
+
+ /// Add a duration in [`Days`] to the date
+ ///
+ /// Returns `None` if the resulting date would be out of range.
+ ///
+ /// ```
+ /// # use chrono::{NaiveDate, Days};
+ /// assert_eq!(
+ /// NaiveDate::from_ymd_opt(2022, 2, 20).unwrap().checked_add_days(Days::new(9)),
+ /// Some(NaiveDate::from_ymd_opt(2022, 3, 1).unwrap())
+ /// );
+ /// assert_eq!(
+ /// NaiveDate::from_ymd_opt(2022, 7, 31).unwrap().checked_add_days(Days::new(2)),
+ /// Some(NaiveDate::from_ymd_opt(2022, 8, 2).unwrap())
+ /// );
+ /// assert_eq!(
+ /// NaiveDate::from_ymd_opt(2022, 7, 31).unwrap().checked_add_days(Days::new(1000000000000)),
+ /// None
+ /// );
+ /// ```
+ pub fn checked_add_days(self, days: Days) -> Option<Self> {
+ if days.0 == 0 {
+ return Some(self);
+ }
+
+ i64::try_from(days.0).ok().and_then(|d| self.diff_days(d))
+ }
+
+ /// Subtract a duration in [`Days`] from the date
+ ///
+ /// Returns `None` if the resulting date would be out of range.
+ ///
+ /// ```
+ /// # use chrono::{NaiveDate, Days};
+ /// assert_eq!(
+ /// NaiveDate::from_ymd_opt(2022, 2, 20).unwrap().checked_sub_days(Days::new(6)),
+ /// Some(NaiveDate::from_ymd_opt(2022, 2, 14).unwrap())
+ /// );
+ /// assert_eq!(
+ /// NaiveDate::from_ymd_opt(2022, 2, 20).unwrap().checked_sub_days(Days::new(1000000000000)),
+ /// None
+ /// );
+ /// ```
+ pub fn checked_sub_days(self, days: Days) -> Option<Self> {
+ if days.0 == 0 {
+ return Some(self);
+ }
+
+ i64::try_from(days.0).ok().and_then(|d| self.diff_days(-d))
+ }
+
+ fn diff_days(self, days: i64) -> Option<Self> {
+ let secs = days.checked_mul(86400)?; // 86400 seconds in one day
+ if secs >= core::i64::MAX / 1000 || secs <= core::i64::MIN / 1000 {
+ return None; // See the `time` 0.1 crate. Outside these bounds, `Duration::seconds` will panic
+ }
+ self.checked_add_signed(Duration::seconds(secs))
+ }
+
/// Makes a new `NaiveDateTime` from the current date and given `NaiveTime`.
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, NaiveTime, NaiveDateTime};
///
- /// let d = NaiveDate::from_ymd(2015, 6, 3);
- /// let t = NaiveTime::from_hms_milli(12, 34, 56, 789);
+ /// let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
+ /// let t = NaiveTime::from_hms_milli_opt(12, 34, 56, 789).unwrap();
///
/// let dt: NaiveDateTime = d.and_time(t);
/// assert_eq!(dt.date(), d);
/// assert_eq!(dt.time(), t);
- /// ~~~~
+ /// ```
#[inline]
- pub fn and_time(&self, time: NaiveTime) -> NaiveDateTime {
+ pub const fn and_time(&self, time: NaiveTime) -> NaiveDateTime {
NaiveDateTime::new(*self, time)
}
@@ -551,19 +718,7 @@ impl NaiveDate {
/// use `NaiveDate::and_hms_*` methods with a subsecond parameter instead.
///
/// Panics on invalid hour, minute and/or second.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Datelike, Timelike, Weekday};
- ///
- /// let d = NaiveDate::from_ymd(2015, 6, 3);
- ///
- /// let dt: NaiveDateTime = d.and_hms(12, 34, 56);
- /// assert_eq!(dt.year(), 2015);
- /// assert_eq!(dt.weekday(), Weekday::Wed);
- /// assert_eq!(dt.second(), 56);
- /// ~~~~
+ #[deprecated(since = "0.4.23", note = "use `and_hms_opt()` instead")]
#[inline]
pub fn and_hms(&self, hour: u32, min: u32, sec: u32) -> NaiveDateTime {
self.and_hms_opt(hour, min, sec).expect("invalid time")
@@ -578,15 +733,15 @@ impl NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::NaiveDate;
///
- /// let d = NaiveDate::from_ymd(2015, 6, 3);
+ /// let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
/// assert!(d.and_hms_opt(12, 34, 56).is_some());
/// assert!(d.and_hms_opt(12, 34, 60).is_none()); // use `and_hms_milli_opt` instead
/// assert!(d.and_hms_opt(12, 60, 56).is_none());
/// assert!(d.and_hms_opt(24, 34, 56).is_none());
- /// ~~~~
+ /// ```
#[inline]
pub fn and_hms_opt(&self, hour: u32, min: u32, sec: u32) -> Option<NaiveDateTime> {
NaiveTime::from_hms_opt(hour, min, sec).map(|time| self.and_time(time))
@@ -598,20 +753,7 @@ impl NaiveDate {
/// in order to represent the [leap second](./struct.NaiveTime.html#leap-second-handling).
///
/// Panics on invalid hour, minute, second and/or millisecond.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Datelike, Timelike, Weekday};
- ///
- /// let d = NaiveDate::from_ymd(2015, 6, 3);
- ///
- /// let dt: NaiveDateTime = d.and_hms_milli(12, 34, 56, 789);
- /// assert_eq!(dt.year(), 2015);
- /// assert_eq!(dt.weekday(), Weekday::Wed);
- /// assert_eq!(dt.second(), 56);
- /// assert_eq!(dt.nanosecond(), 789_000_000);
- /// ~~~~
+ #[deprecated(since = "0.4.23", note = "use `and_hms_milli_opt()` instead")]
#[inline]
pub fn and_hms_milli(&self, hour: u32, min: u32, sec: u32, milli: u32) -> NaiveDateTime {
self.and_hms_milli_opt(hour, min, sec, milli).expect("invalid time")
@@ -626,17 +768,17 @@ impl NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::NaiveDate;
///
- /// let d = NaiveDate::from_ymd(2015, 6, 3);
+ /// let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
/// assert!(d.and_hms_milli_opt(12, 34, 56, 789).is_some());
/// assert!(d.and_hms_milli_opt(12, 34, 59, 1_789).is_some()); // leap second
/// assert!(d.and_hms_milli_opt(12, 34, 59, 2_789).is_none());
/// assert!(d.and_hms_milli_opt(12, 34, 60, 789).is_none());
/// assert!(d.and_hms_milli_opt(12, 60, 56, 789).is_none());
/// assert!(d.and_hms_milli_opt(24, 34, 56, 789).is_none());
- /// ~~~~
+ /// ```
#[inline]
pub fn and_hms_milli_opt(
&self,
@@ -657,17 +799,18 @@ impl NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, NaiveDateTime, Datelike, Timelike, Weekday};
///
- /// let d = NaiveDate::from_ymd(2015, 6, 3);
+ /// let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
///
/// let dt: NaiveDateTime = d.and_hms_micro(12, 34, 56, 789_012);
/// assert_eq!(dt.year(), 2015);
/// assert_eq!(dt.weekday(), Weekday::Wed);
/// assert_eq!(dt.second(), 56);
/// assert_eq!(dt.nanosecond(), 789_012_000);
- /// ~~~~
+ /// ```
+ #[deprecated(since = "0.4.23", note = "use `and_hms_micro_opt()` instead")]
#[inline]
pub fn and_hms_micro(&self, hour: u32, min: u32, sec: u32, micro: u32) -> NaiveDateTime {
self.and_hms_micro_opt(hour, min, sec, micro).expect("invalid time")
@@ -682,17 +825,17 @@ impl NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::NaiveDate;
///
- /// let d = NaiveDate::from_ymd(2015, 6, 3);
+ /// let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
/// assert!(d.and_hms_micro_opt(12, 34, 56, 789_012).is_some());
/// assert!(d.and_hms_micro_opt(12, 34, 59, 1_789_012).is_some()); // leap second
/// assert!(d.and_hms_micro_opt(12, 34, 59, 2_789_012).is_none());
/// assert!(d.and_hms_micro_opt(12, 34, 60, 789_012).is_none());
/// assert!(d.and_hms_micro_opt(12, 60, 56, 789_012).is_none());
/// assert!(d.and_hms_micro_opt(24, 34, 56, 789_012).is_none());
- /// ~~~~
+ /// ```
#[inline]
pub fn and_hms_micro_opt(
&self,
@@ -710,20 +853,7 @@ impl NaiveDate {
/// in order to represent the [leap second](./struct.NaiveTime.html#leap-second-handling).
///
/// Panics on invalid hour, minute, second and/or nanosecond.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Datelike, Timelike, Weekday};
- ///
- /// let d = NaiveDate::from_ymd(2015, 6, 3);
- ///
- /// let dt: NaiveDateTime = d.and_hms_nano(12, 34, 56, 789_012_345);
- /// assert_eq!(dt.year(), 2015);
- /// assert_eq!(dt.weekday(), Weekday::Wed);
- /// assert_eq!(dt.second(), 56);
- /// assert_eq!(dt.nanosecond(), 789_012_345);
- /// ~~~~
+ #[deprecated(since = "0.4.23", note = "use `and_hms_nano_opt()` instead")]
#[inline]
pub fn and_hms_nano(&self, hour: u32, min: u32, sec: u32, nano: u32) -> NaiveDateTime {
self.and_hms_nano_opt(hour, min, sec, nano).expect("invalid time")
@@ -738,17 +868,17 @@ impl NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::NaiveDate;
///
- /// let d = NaiveDate::from_ymd(2015, 6, 3);
+ /// let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
/// assert!(d.and_hms_nano_opt(12, 34, 56, 789_012_345).is_some());
/// assert!(d.and_hms_nano_opt(12, 34, 59, 1_789_012_345).is_some()); // leap second
/// assert!(d.and_hms_nano_opt(12, 34, 59, 2_789_012_345).is_none());
/// assert!(d.and_hms_nano_opt(12, 34, 60, 789_012_345).is_none());
/// assert!(d.and_hms_nano_opt(12, 60, 56, 789_012_345).is_none());
/// assert!(d.and_hms_nano_opt(24, 34, 56, 789_012_345).is_none());
- /// ~~~~
+ /// ```
#[inline]
pub fn and_hms_nano_opt(
&self,
@@ -768,7 +898,7 @@ impl NaiveDate {
/// Returns the packed ordinal-flags.
#[inline]
- fn of(&self) -> Of {
+ const fn of(&self) -> Of {
Of((self.ymdf & 0b1_1111_1111_1111) as u32)
}
@@ -796,16 +926,7 @@ impl NaiveDate {
/// Makes a new `NaiveDate` for the next calendar date.
///
/// Panics when `self` is the last representable date.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::NaiveDate;
- ///
- /// assert_eq!(NaiveDate::from_ymd(2015, 6, 3).succ(), NaiveDate::from_ymd(2015, 6, 4));
- /// assert_eq!(NaiveDate::from_ymd(2015, 6, 30).succ(), NaiveDate::from_ymd(2015, 7, 1));
- /// assert_eq!(NaiveDate::from_ymd(2015, 12, 31).succ(), NaiveDate::from_ymd(2016, 1, 1));
- /// ~~~~
+ #[deprecated(since = "0.4.23", note = "use `succ_opt()` instead")]
#[inline]
pub fn succ(&self) -> NaiveDate {
self.succ_opt().expect("out of bound")
@@ -817,14 +938,13 @@ impl NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::NaiveDate;
- /// use chrono::naive::MAX_DATE;
///
- /// assert_eq!(NaiveDate::from_ymd(2015, 6, 3).succ_opt(),
- /// Some(NaiveDate::from_ymd(2015, 6, 4)));
- /// assert_eq!(MAX_DATE.succ_opt(), None);
- /// ~~~~
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 6, 3).unwrap().succ_opt(),
+ /// Some(NaiveDate::from_ymd_opt(2015, 6, 4).unwrap()));
+ /// assert_eq!(NaiveDate::MAX.succ_opt(), None);
+ /// ```
#[inline]
pub fn succ_opt(&self) -> Option<NaiveDate> {
self.with_of(self.of().succ()).or_else(|| NaiveDate::from_ymd_opt(self.year() + 1, 1, 1))
@@ -833,16 +953,7 @@ impl NaiveDate {
/// Makes a new `NaiveDate` for the previous calendar date.
///
/// Panics when `self` is the first representable date.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::NaiveDate;
- ///
- /// assert_eq!(NaiveDate::from_ymd(2015, 6, 3).pred(), NaiveDate::from_ymd(2015, 6, 2));
- /// assert_eq!(NaiveDate::from_ymd(2015, 6, 1).pred(), NaiveDate::from_ymd(2015, 5, 31));
- /// assert_eq!(NaiveDate::from_ymd(2015, 1, 1).pred(), NaiveDate::from_ymd(2014, 12, 31));
- /// ~~~~
+ #[deprecated(since = "0.4.23", note = "use `pred_opt()` instead")]
#[inline]
pub fn pred(&self) -> NaiveDate {
self.pred_opt().expect("out of bound")
@@ -854,14 +965,13 @@ impl NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::NaiveDate;
- /// use chrono::naive::MIN_DATE;
///
- /// assert_eq!(NaiveDate::from_ymd(2015, 6, 3).pred_opt(),
- /// Some(NaiveDate::from_ymd(2015, 6, 2)));
- /// assert_eq!(MIN_DATE.pred_opt(), None);
- /// ~~~~
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 6, 3).unwrap().pred_opt(),
+ /// Some(NaiveDate::from_ymd_opt(2015, 6, 2).unwrap()));
+ /// assert_eq!(NaiveDate::MIN.pred_opt(), None);
+ /// ```
#[inline]
pub fn pred_opt(&self) -> Option<NaiveDate> {
self.with_of(self.of().pred()).or_else(|| NaiveDate::from_ymd_opt(self.year() - 1, 12, 31))
@@ -873,32 +983,29 @@ impl NaiveDate {
///
/// # Example
///
- /// ~~~~
- /// # extern crate chrono; fn main() {
+ /// ```
/// use chrono::{Duration, NaiveDate};
- /// use chrono::naive::MAX_DATE;
///
- /// let d = NaiveDate::from_ymd(2015, 9, 5);
+ /// let d = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap();
/// assert_eq!(d.checked_add_signed(Duration::days(40)),
- /// Some(NaiveDate::from_ymd(2015, 10, 15)));
+ /// Some(NaiveDate::from_ymd_opt(2015, 10, 15).unwrap()));
/// assert_eq!(d.checked_add_signed(Duration::days(-40)),
- /// Some(NaiveDate::from_ymd(2015, 7, 27)));
+ /// Some(NaiveDate::from_ymd_opt(2015, 7, 27).unwrap()));
/// assert_eq!(d.checked_add_signed(Duration::days(1_000_000_000)), None);
/// assert_eq!(d.checked_add_signed(Duration::days(-1_000_000_000)), None);
- /// assert_eq!(MAX_DATE.checked_add_signed(Duration::days(1)), None);
- /// # }
- /// ~~~~
+ /// assert_eq!(NaiveDate::MAX.checked_add_signed(Duration::days(1)), None);
+ /// ```
pub fn checked_add_signed(self, rhs: OldDuration) -> Option<NaiveDate> {
let year = self.year();
let (mut year_div_400, year_mod_400) = div_mod_floor(year, 400);
let cycle = internals::yo_to_cycle(year_mod_400 as u32, self.of().ordinal());
- let cycle = try_opt!((cycle as i32).checked_add(try_opt!(rhs.num_days().to_i32())));
+ let cycle = (cycle as i32).checked_add(rhs.num_days().to_i32()?)?;
let (cycle_div_400y, cycle) = div_mod_floor(cycle, 146_097);
year_div_400 += cycle_div_400y;
let (year_mod_400, ordinal) = internals::cycle_to_yo(cycle as u32);
let flags = YearFlags::from_year_mod_400(year_mod_400 as i32);
- NaiveDate::from_of(year_div_400 * 400 + year_mod_400 as i32, Of::new(ordinal, flags))
+ NaiveDate::from_of(year_div_400 * 400 + year_mod_400 as i32, Of::new(ordinal, flags)?)
}
/// Subtracts the `days` part of given `Duration` from the current date.
@@ -907,32 +1014,29 @@ impl NaiveDate {
///
/// # Example
///
- /// ~~~~
- /// # extern crate chrono; fn main() {
+ /// ```
/// use chrono::{Duration, NaiveDate};
- /// use chrono::naive::MIN_DATE;
///
- /// let d = NaiveDate::from_ymd(2015, 9, 5);
+ /// let d = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap();
/// assert_eq!(d.checked_sub_signed(Duration::days(40)),
- /// Some(NaiveDate::from_ymd(2015, 7, 27)));
+ /// Some(NaiveDate::from_ymd_opt(2015, 7, 27).unwrap()));
/// assert_eq!(d.checked_sub_signed(Duration::days(-40)),
- /// Some(NaiveDate::from_ymd(2015, 10, 15)));
+ /// Some(NaiveDate::from_ymd_opt(2015, 10, 15).unwrap()));
/// assert_eq!(d.checked_sub_signed(Duration::days(1_000_000_000)), None);
/// assert_eq!(d.checked_sub_signed(Duration::days(-1_000_000_000)), None);
- /// assert_eq!(MIN_DATE.checked_sub_signed(Duration::days(1)), None);
- /// # }
- /// ~~~~
+ /// assert_eq!(NaiveDate::MIN.checked_sub_signed(Duration::days(1)), None);
+ /// ```
pub fn checked_sub_signed(self, rhs: OldDuration) -> Option<NaiveDate> {
let year = self.year();
let (mut year_div_400, year_mod_400) = div_mod_floor(year, 400);
let cycle = internals::yo_to_cycle(year_mod_400 as u32, self.of().ordinal());
- let cycle = try_opt!((cycle as i32).checked_sub(try_opt!(rhs.num_days().to_i32())));
+ let cycle = (cycle as i32).checked_sub(rhs.num_days().to_i32()?)?;
let (cycle_div_400y, cycle) = div_mod_floor(cycle, 146_097);
year_div_400 += cycle_div_400y;
let (year_mod_400, ordinal) = internals::cycle_to_yo(cycle as u32);
let flags = YearFlags::from_year_mod_400(year_mod_400 as i32);
- NaiveDate::from_of(year_div_400 * 400 + year_mod_400 as i32, Of::new(ordinal, flags))
+ NaiveDate::from_of(year_div_400 * 400 + year_mod_400 as i32, Of::new(ordinal, flags)?)
}
/// Subtracts another `NaiveDate` from the current date.
@@ -943,8 +1047,7 @@ impl NaiveDate {
///
/// # Example
///
- /// ~~~~
- /// # extern crate chrono; fn main() {
+ /// ```
/// use chrono::{Duration, NaiveDate};
///
/// let from_ymd = NaiveDate::from_ymd;
@@ -957,8 +1060,7 @@ impl NaiveDate {
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2013, 1, 1)), Duration::days(365));
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(2010, 1, 1)), Duration::days(365*4 + 1));
/// assert_eq!(since(from_ymd(2014, 1, 1), from_ymd(1614, 1, 1)), Duration::days(365*400 + 97));
- /// # }
- /// ~~~~
+ /// ```
pub fn signed_duration_since(self, rhs: NaiveDate) -> OldDuration {
let year1 = self.year();
let year2 = rhs.year();
@@ -971,6 +1073,19 @@ impl NaiveDate {
)
}
+ /// Returns the number of whole years from the given `base` until `self`.
+ pub fn years_since(&self, base: Self) -> Option<u32> {
+ let mut years = self.year() - base.year();
+ if (self.month(), self.day()) < (base.month(), base.day()) {
+ years -= 1;
+ }
+
+ match years >= 0 {
+ true => Some(years as u32),
+ false => None,
+ }
+ }
+
/// Formats the date with the specified formatting items.
/// Otherwise it is the same as the ordinary `format` method.
///
@@ -979,26 +1094,27 @@ impl NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::NaiveDate;
/// use chrono::format::strftime::StrftimeItems;
///
/// let fmt = StrftimeItems::new("%Y-%m-%d");
- /// let d = NaiveDate::from_ymd(2015, 9, 5);
+ /// let d = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap();
/// assert_eq!(d.format_with_items(fmt.clone()).to_string(), "2015-09-05");
/// assert_eq!(d.format("%Y-%m-%d").to_string(), "2015-09-05");
- /// ~~~~
+ /// ```
///
/// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
///
- /// ~~~~
+ /// ```
/// # use chrono::NaiveDate;
/// # use chrono::format::strftime::StrftimeItems;
/// # let fmt = StrftimeItems::new("%Y-%m-%d").clone();
- /// # let d = NaiveDate::from_ymd(2015, 9, 5);
+ /// # let d = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap();
/// assert_eq!(format!("{}", d.format_with_items(fmt)), "2015-09-05");
- /// ~~~~
+ /// ```
#[cfg(any(feature = "alloc", feature = "std", test))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
#[inline]
pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat<I>
where
@@ -1024,29 +1140,61 @@ impl NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::NaiveDate;
///
- /// let d = NaiveDate::from_ymd(2015, 9, 5);
+ /// let d = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap();
/// assert_eq!(d.format("%Y-%m-%d").to_string(), "2015-09-05");
/// assert_eq!(d.format("%A, %-d %B, %C%y").to_string(), "Saturday, 5 September, 2015");
- /// ~~~~
+ /// ```
///
/// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
///
- /// ~~~~
+ /// ```
/// # use chrono::NaiveDate;
- /// # let d = NaiveDate::from_ymd(2015, 9, 5);
+ /// # let d = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap();
/// assert_eq!(format!("{}", d.format("%Y-%m-%d")), "2015-09-05");
/// assert_eq!(format!("{}", d.format("%A, %-d %B, %C%y")), "Saturday, 5 September, 2015");
- /// ~~~~
+ /// ```
#[cfg(any(feature = "alloc", feature = "std", test))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
#[inline]
pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>> {
self.format_with_items(StrftimeItems::new(fmt))
}
- /// Returns an iterator that steps by days until the last representable date.
+ /// Formats the date with the specified formatting items and locale.
+ #[cfg(feature = "unstable-locales")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "unstable-locales")))]
+ #[inline]
+ pub fn format_localized_with_items<'a, I, B>(
+ &self,
+ items: I,
+ locale: Locale,
+ ) -> DelayedFormat<I>
+ where
+ I: Iterator<Item = B> + Clone,
+ B: Borrow<Item<'a>>,
+ {
+ DelayedFormat::new_with_locale(Some(*self), None, items, locale)
+ }
+
+ /// Formats the date with the specified format string and locale.
+ ///
+ /// See the [`crate::format::strftime`] module on the supported escape
+ /// sequences.
+ #[cfg(feature = "unstable-locales")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "unstable-locales")))]
+ #[inline]
+ pub fn format_localized<'a>(
+ &self,
+ fmt: &'a str,
+ locale: Locale,
+ ) -> DelayedFormat<StrftimeItems<'a>> {
+ self.format_localized_with_items(StrftimeItems::new_with_locale(fmt, locale), locale)
+ }
+
+ /// Returns an iterator that steps by days across all representable dates.
///
/// # Example
///
@@ -1054,25 +1202,30 @@ impl NaiveDate {
/// # use chrono::NaiveDate;
///
/// let expected = [
- /// NaiveDate::from_ymd(2016, 2, 27),
- /// NaiveDate::from_ymd(2016, 2, 28),
- /// NaiveDate::from_ymd(2016, 2, 29),
- /// NaiveDate::from_ymd(2016, 3, 1),
+ /// NaiveDate::from_ymd_opt(2016, 2, 27).unwrap(),
+ /// NaiveDate::from_ymd_opt(2016, 2, 28).unwrap(),
+ /// NaiveDate::from_ymd_opt(2016, 2, 29).unwrap(),
+ /// NaiveDate::from_ymd_opt(2016, 3, 1).unwrap(),
/// ];
///
/// let mut count = 0;
- /// for (idx, d) in NaiveDate::from_ymd(2016, 2, 27).iter_days().take(4).enumerate() {
+ /// for (idx, d) in NaiveDate::from_ymd_opt(2016, 2, 27).unwrap().iter_days().take(4).enumerate() {
/// assert_eq!(d, expected[idx]);
/// count += 1;
/// }
/// assert_eq!(count, 4);
+ ///
+ /// for d in NaiveDate::from_ymd_opt(2016, 3, 1).unwrap().iter_days().rev().take(4) {
+ /// count -= 1;
+ /// assert_eq!(d, expected[count]);
+ /// }
/// ```
#[inline]
- pub fn iter_days(&self) -> NaiveDateDaysIterator {
+ pub const fn iter_days(&self) -> NaiveDateDaysIterator {
NaiveDateDaysIterator { value: *self }
}
- /// Returns an iterator that steps by weeks until the last representable date.
+ /// Returns an iterator that steps by weeks across all representable dates.
///
/// # Example
///
@@ -1080,23 +1233,40 @@ impl NaiveDate {
/// # use chrono::NaiveDate;
///
/// let expected = [
- /// NaiveDate::from_ymd(2016, 2, 27),
- /// NaiveDate::from_ymd(2016, 3, 5),
- /// NaiveDate::from_ymd(2016, 3, 12),
- /// NaiveDate::from_ymd(2016, 3, 19),
+ /// NaiveDate::from_ymd_opt(2016, 2, 27).unwrap(),
+ /// NaiveDate::from_ymd_opt(2016, 3, 5).unwrap(),
+ /// NaiveDate::from_ymd_opt(2016, 3, 12).unwrap(),
+ /// NaiveDate::from_ymd_opt(2016, 3, 19).unwrap(),
/// ];
///
/// let mut count = 0;
- /// for (idx, d) in NaiveDate::from_ymd(2016, 2, 27).iter_weeks().take(4).enumerate() {
+ /// for (idx, d) in NaiveDate::from_ymd_opt(2016, 2, 27).unwrap().iter_weeks().take(4).enumerate() {
/// assert_eq!(d, expected[idx]);
/// count += 1;
/// }
/// assert_eq!(count, 4);
+ ///
+ /// for d in NaiveDate::from_ymd_opt(2016, 3, 19).unwrap().iter_weeks().rev().take(4) {
+ /// count -= 1;
+ /// assert_eq!(d, expected[count]);
+ /// }
/// ```
#[inline]
- pub fn iter_weeks(&self) -> NaiveDateWeeksIterator {
+ pub const fn iter_weeks(&self) -> NaiveDateWeeksIterator {
NaiveDateWeeksIterator { value: *self }
}
+
+ /// Returns the [`NaiveWeek`] that the date belongs to, starting with the [`Weekday`]
+ /// specified.
+ #[inline]
+ pub const fn week(&self, start: Weekday) -> NaiveWeek {
+ NaiveWeek { date: *self, start }
+ }
+
+ /// The minimum possible `NaiveDate` (January 1, 262145 BCE).
+ pub const MIN: NaiveDate = NaiveDate { ymdf: (MIN_YEAR << 13) | (1 << 4) | 0o07 /*FE*/ };
+ /// The maximum possible `NaiveDate` (December 31, 262143 CE).
+ pub const MAX: NaiveDate = NaiveDate { ymdf: (MAX_YEAR << 13) | (365 << 4) | 0o17 /*F*/ };
}
impl Datelike for NaiveDate {
@@ -1104,12 +1274,12 @@ impl Datelike for NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Datelike};
///
- /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).year(), 2015);
- /// assert_eq!(NaiveDate::from_ymd(-308, 3, 14).year(), -308); // 309 BCE
- /// ~~~~
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().year(), 2015);
+ /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().year(), -308); // 309 BCE
+ /// ```
#[inline]
fn year(&self) -> i32 {
self.ymdf >> 13
@@ -1121,12 +1291,12 @@ impl Datelike for NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Datelike};
///
- /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).month(), 9);
- /// assert_eq!(NaiveDate::from_ymd(-308, 3, 14).month(), 3);
- /// ~~~~
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().month(), 9);
+ /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().month(), 3);
+ /// ```
#[inline]
fn month(&self) -> u32 {
self.mdf().month()
@@ -1138,12 +1308,12 @@ impl Datelike for NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Datelike};
///
- /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).month0(), 8);
- /// assert_eq!(NaiveDate::from_ymd(-308, 3, 14).month0(), 2);
- /// ~~~~
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().month0(), 8);
+ /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().month0(), 2);
+ /// ```
#[inline]
fn month0(&self) -> u32 {
self.mdf().month() - 1
@@ -1155,24 +1325,24 @@ impl Datelike for NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Datelike};
///
- /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).day(), 8);
- /// assert_eq!(NaiveDate::from_ymd(-308, 3, 14).day(), 14);
- /// ~~~~
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().day(), 8);
+ /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().day(), 14);
+ /// ```
///
/// Combined with [`NaiveDate::pred`](#method.pred),
/// one can determine the number of days in a particular month.
/// (Note that this panics when `year` is out of range.)
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Datelike};
///
/// fn ndays_in_month(year: i32, month: u32) -> u32 {
/// // the first day of the next month...
/// let (y, m) = if month == 12 { (year + 1, 1) } else { (year, month + 1) };
- /// let d = NaiveDate::from_ymd(y, m, 1);
+ /// let d = NaiveDate::from_ymd_opt(y, m, 1).unwrap();
///
/// // ...is preceded by the last day of the original month
/// d.pred().day()
@@ -1183,7 +1353,7 @@ impl Datelike for NaiveDate {
/// assert_eq!(ndays_in_month(2015, 12), 31);
/// assert_eq!(ndays_in_month(2016, 2), 29);
/// assert_eq!(ndays_in_month(2017, 2), 28);
- /// ~~~~
+ /// ```
#[inline]
fn day(&self) -> u32 {
self.mdf().day()
@@ -1195,12 +1365,12 @@ impl Datelike for NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Datelike};
///
- /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).day0(), 7);
- /// assert_eq!(NaiveDate::from_ymd(-308, 3, 14).day0(), 13);
- /// ~~~~
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().day0(), 7);
+ /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().day0(), 13);
+ /// ```
#[inline]
fn day0(&self) -> u32 {
self.mdf().day() - 1
@@ -1212,23 +1382,23 @@ impl Datelike for NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Datelike};
///
- /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).ordinal(), 251);
- /// assert_eq!(NaiveDate::from_ymd(-308, 3, 14).ordinal(), 74);
- /// ~~~~
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().ordinal(), 251);
+ /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().ordinal(), 74);
+ /// ```
///
/// Combined with [`NaiveDate::pred`](#method.pred),
/// one can determine the number of days in a particular year.
/// (Note that this panics when `year` is out of range.)
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Datelike};
///
/// fn ndays_in_year(year: i32) -> u32 {
/// // the first day of the next year...
- /// let d = NaiveDate::from_ymd(year + 1, 1, 1);
+ /// let d = NaiveDate::from_ymd_opt(year + 1, 1, 1).unwrap();
///
/// // ...is preceded by the last day of the original year
/// d.pred().ordinal()
@@ -1239,7 +1409,7 @@ impl Datelike for NaiveDate {
/// assert_eq!(ndays_in_year(2017), 365);
/// assert_eq!(ndays_in_year(2000), 366);
/// assert_eq!(ndays_in_year(2100), 365);
- /// ~~~~
+ /// ```
#[inline]
fn ordinal(&self) -> u32 {
self.of().ordinal()
@@ -1251,12 +1421,12 @@ impl Datelike for NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Datelike};
///
- /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).ordinal0(), 250);
- /// assert_eq!(NaiveDate::from_ymd(-308, 3, 14).ordinal0(), 73);
- /// ~~~~
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().ordinal0(), 250);
+ /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().ordinal0(), 73);
+ /// ```
#[inline]
fn ordinal0(&self) -> u32 {
self.of().ordinal() - 1
@@ -1266,12 +1436,12 @@ impl Datelike for NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Datelike, Weekday};
///
- /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).weekday(), Weekday::Tue);
- /// assert_eq!(NaiveDate::from_ymd(-308, 3, 14).weekday(), Weekday::Fri);
- /// ~~~~
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().weekday(), Weekday::Tue);
+ /// assert_eq!(NaiveDate::from_ymd_opt(-308, 3, 14).unwrap().weekday(), Weekday::Fri);
+ /// ```
#[inline]
fn weekday(&self) -> Weekday {
self.of().weekday()
@@ -1288,22 +1458,22 @@ impl Datelike for NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Datelike};
///
- /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).with_year(2016),
- /// Some(NaiveDate::from_ymd(2016, 9, 8)));
- /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).with_year(-308),
- /// Some(NaiveDate::from_ymd(-308, 9, 8)));
- /// ~~~~
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_year(2016),
+ /// Some(NaiveDate::from_ymd_opt(2016, 9, 8).unwrap()));
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_year(-308),
+ /// Some(NaiveDate::from_ymd_opt(-308, 9, 8).unwrap()));
+ /// ```
///
/// A leap day (February 29) is a good example that this method can return `None`.
///
- /// ~~~~
+ /// ```
/// # use chrono::{NaiveDate, Datelike};
- /// assert!(NaiveDate::from_ymd(2016, 2, 29).with_year(2015).is_none());
- /// assert!(NaiveDate::from_ymd(2016, 2, 29).with_year(2020).is_some());
- /// ~~~~
+ /// assert!(NaiveDate::from_ymd_opt(2016, 2, 29).unwrap().with_year(2015).is_none());
+ /// assert!(NaiveDate::from_ymd_opt(2016, 2, 29).unwrap().with_year(2020).is_some());
+ /// ```
#[inline]
fn with_year(&self, year: i32) -> Option<NaiveDate> {
// we need to operate with `mdf` since we should keep the month and day number as is
@@ -1322,17 +1492,17 @@ impl Datelike for NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Datelike};
///
- /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).with_month(10),
- /// Some(NaiveDate::from_ymd(2015, 10, 8)));
- /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).with_month(13), None); // no month 13
- /// assert_eq!(NaiveDate::from_ymd(2015, 9, 30).with_month(2), None); // no February 30
- /// ~~~~
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_month(10),
+ /// Some(NaiveDate::from_ymd_opt(2015, 10, 8).unwrap()));
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_month(13), None); // no month 13
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 30).unwrap().with_month(2), None); // no February 30
+ /// ```
#[inline]
fn with_month(&self, month: u32) -> Option<NaiveDate> {
- self.with_mdf(self.mdf().with_month(month))
+ self.with_mdf(self.mdf().with_month(month)?)
}
/// Makes a new `NaiveDate` with the month number (starting from 0) changed.
@@ -1341,17 +1511,17 @@ impl Datelike for NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Datelike};
///
- /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).with_month0(9),
- /// Some(NaiveDate::from_ymd(2015, 10, 8)));
- /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).with_month0(12), None); // no month 13
- /// assert_eq!(NaiveDate::from_ymd(2015, 9, 30).with_month0(1), None); // no February 30
- /// ~~~~
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_month0(9),
+ /// Some(NaiveDate::from_ymd_opt(2015, 10, 8).unwrap()));
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_month0(12), None); // no month 13
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 30).unwrap().with_month0(1), None); // no February 30
+ /// ```
#[inline]
fn with_month0(&self, month0: u32) -> Option<NaiveDate> {
- self.with_mdf(self.mdf().with_month(month0 + 1))
+ self.with_mdf(self.mdf().with_month(month0 + 1)?)
}
/// Makes a new `NaiveDate` with the day of month (starting from 1) changed.
@@ -1360,17 +1530,17 @@ impl Datelike for NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Datelike};
///
- /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).with_day(30),
- /// Some(NaiveDate::from_ymd(2015, 9, 30)));
- /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).with_day(31),
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_day(30),
+ /// Some(NaiveDate::from_ymd_opt(2015, 9, 30).unwrap()));
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_day(31),
/// None); // no September 31
- /// ~~~~
+ /// ```
#[inline]
fn with_day(&self, day: u32) -> Option<NaiveDate> {
- self.with_mdf(self.mdf().with_day(day))
+ self.with_mdf(self.mdf().with_day(day)?)
}
/// Makes a new `NaiveDate` with the day of month (starting from 0) changed.
@@ -1379,17 +1549,17 @@ impl Datelike for NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Datelike};
///
- /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).with_day0(29),
- /// Some(NaiveDate::from_ymd(2015, 9, 30)));
- /// assert_eq!(NaiveDate::from_ymd(2015, 9, 8).with_day0(30),
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_day0(29),
+ /// Some(NaiveDate::from_ymd_opt(2015, 9, 30).unwrap()));
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().with_day0(30),
/// None); // no September 31
- /// ~~~~
+ /// ```
#[inline]
fn with_day0(&self, day0: u32) -> Option<NaiveDate> {
- self.with_mdf(self.mdf().with_day(day0 + 1))
+ self.with_mdf(self.mdf().with_day(day0 + 1)?)
}
/// Makes a new `NaiveDate` with the day of year (starting from 1) changed.
@@ -1398,22 +1568,22 @@ impl Datelike for NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Datelike};
///
- /// assert_eq!(NaiveDate::from_ymd(2015, 1, 1).with_ordinal(60),
- /// Some(NaiveDate::from_ymd(2015, 3, 1)));
- /// assert_eq!(NaiveDate::from_ymd(2015, 1, 1).with_ordinal(366),
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 1, 1).unwrap().with_ordinal(60),
+ /// Some(NaiveDate::from_ymd_opt(2015, 3, 1).unwrap()));
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 1, 1).unwrap().with_ordinal(366),
/// None); // 2015 had only 365 days
///
- /// assert_eq!(NaiveDate::from_ymd(2016, 1, 1).with_ordinal(60),
- /// Some(NaiveDate::from_ymd(2016, 2, 29)));
- /// assert_eq!(NaiveDate::from_ymd(2016, 1, 1).with_ordinal(366),
- /// Some(NaiveDate::from_ymd(2016, 12, 31)));
- /// ~~~~
+ /// assert_eq!(NaiveDate::from_ymd_opt(2016, 1, 1).unwrap().with_ordinal(60),
+ /// Some(NaiveDate::from_ymd_opt(2016, 2, 29).unwrap()));
+ /// assert_eq!(NaiveDate::from_ymd_opt(2016, 1, 1).unwrap().with_ordinal(366),
+ /// Some(NaiveDate::from_ymd_opt(2016, 12, 31).unwrap()));
+ /// ```
#[inline]
fn with_ordinal(&self, ordinal: u32) -> Option<NaiveDate> {
- self.with_of(self.of().with_ordinal(ordinal))
+ self.with_of(self.of().with_ordinal(ordinal)?)
}
/// Makes a new `NaiveDate` with the day of year (starting from 0) changed.
@@ -1422,22 +1592,22 @@ impl Datelike for NaiveDate {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Datelike};
///
- /// assert_eq!(NaiveDate::from_ymd(2015, 1, 1).with_ordinal0(59),
- /// Some(NaiveDate::from_ymd(2015, 3, 1)));
- /// assert_eq!(NaiveDate::from_ymd(2015, 1, 1).with_ordinal0(365),
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 1, 1).unwrap().with_ordinal0(59),
+ /// Some(NaiveDate::from_ymd_opt(2015, 3, 1).unwrap()));
+ /// assert_eq!(NaiveDate::from_ymd_opt(2015, 1, 1).unwrap().with_ordinal0(365),
/// None); // 2015 had only 365 days
///
- /// assert_eq!(NaiveDate::from_ymd(2016, 1, 1).with_ordinal0(59),
- /// Some(NaiveDate::from_ymd(2016, 2, 29)));
- /// assert_eq!(NaiveDate::from_ymd(2016, 1, 1).with_ordinal0(365),
- /// Some(NaiveDate::from_ymd(2016, 12, 31)));
- /// ~~~~
+ /// assert_eq!(NaiveDate::from_ymd_opt(2016, 1, 1).unwrap().with_ordinal0(59),
+ /// Some(NaiveDate::from_ymd_opt(2016, 2, 29).unwrap()));
+ /// assert_eq!(NaiveDate::from_ymd_opt(2016, 1, 1).unwrap().with_ordinal0(365),
+ /// Some(NaiveDate::from_ymd_opt(2016, 12, 31).unwrap()));
+ /// ```
#[inline]
fn with_ordinal0(&self, ordinal0: u32) -> Option<NaiveDate> {
- self.with_of(self.of().with_ordinal(ordinal0 + 1))
+ self.with_of(self.of().with_ordinal(ordinal0 + 1)?)
}
}
@@ -1449,8 +1619,7 @@ impl Datelike for NaiveDate {
///
/// # Example
///
-/// ~~~~
-/// # extern crate chrono; fn main() {
+/// ```
/// use chrono::{Duration, NaiveDate};
///
/// let from_ymd = NaiveDate::from_ymd;
@@ -1463,8 +1632,7 @@ impl Datelike for NaiveDate {
/// assert_eq!(from_ymd(2014, 1, 1) + Duration::days(364), from_ymd(2014, 12, 31));
/// assert_eq!(from_ymd(2014, 1, 1) + Duration::days(365*4 + 1), from_ymd(2018, 1, 1));
/// assert_eq!(from_ymd(2014, 1, 1) + Duration::days(365*400 + 97), from_ymd(2414, 1, 1));
-/// # }
-/// ~~~~
+/// ```
impl Add<OldDuration> for NaiveDate {
type Output = NaiveDate;
@@ -1481,6 +1649,75 @@ impl AddAssign<OldDuration> for NaiveDate {
}
}
+impl Add<Months> for NaiveDate {
+ type Output = NaiveDate;
+
+ /// An addition of months to `NaiveDate` clamped to valid days in resulting month.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the resulting date would be out of range.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{Duration, NaiveDate, Months};
+ ///
+ /// let from_ymd = NaiveDate::from_ymd;
+ ///
+ /// assert_eq!(from_ymd(2014, 1, 1) + Months::new(1), from_ymd(2014, 2, 1));
+ /// assert_eq!(from_ymd(2014, 1, 1) + Months::new(11), from_ymd(2014, 12, 1));
+ /// assert_eq!(from_ymd(2014, 1, 1) + Months::new(12), from_ymd(2015, 1, 1));
+ /// assert_eq!(from_ymd(2014, 1, 1) + Months::new(13), from_ymd(2015, 2, 1));
+ /// assert_eq!(from_ymd(2014, 1, 31) + Months::new(1), from_ymd(2014, 2, 28));
+ /// assert_eq!(from_ymd(2020, 1, 31) + Months::new(1), from_ymd(2020, 2, 29));
+ /// ```
+ fn add(self, months: Months) -> Self::Output {
+ self.checked_add_months(months).unwrap()
+ }
+}
+
+impl Sub<Months> for NaiveDate {
+ type Output = NaiveDate;
+
+ /// A subtraction of Months from `NaiveDate` clamped to valid days in resulting month.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the resulting date would be out of range.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{Duration, NaiveDate, Months};
+ ///
+ /// let from_ymd = NaiveDate::from_ymd;
+ ///
+ /// assert_eq!(from_ymd(2014, 1, 1) - Months::new(11), from_ymd(2013, 2, 1));
+ /// assert_eq!(from_ymd(2014, 1, 1) - Months::new(12), from_ymd(2013, 1, 1));
+ /// assert_eq!(from_ymd(2014, 1, 1) - Months::new(13), from_ymd(2012, 12, 1));
+ /// ```
+ fn sub(self, months: Months) -> Self::Output {
+ self.checked_sub_months(months).unwrap()
+ }
+}
+
+impl Add<Days> for NaiveDate {
+ type Output = NaiveDate;
+
+ fn add(self, days: Days) -> Self::Output {
+ self.checked_add_days(days).unwrap()
+ }
+}
+
+impl Sub<Days> for NaiveDate {
+ type Output = NaiveDate;
+
+ fn sub(self, days: Days) -> Self::Output {
+ self.checked_sub_days(days).unwrap()
+ }
+}
+
/// A subtraction of `Duration` from `NaiveDate` discards the fractional days,
/// rounding to the closest integral number of days towards `Duration::zero()`.
/// It is the same as the addition with a negated `Duration`.
@@ -1490,8 +1727,7 @@ impl AddAssign<OldDuration> for NaiveDate {
///
/// # Example
///
-/// ~~~~
-/// # extern crate chrono; fn main() {
+/// ```
/// use chrono::{Duration, NaiveDate};
///
/// let from_ymd = NaiveDate::from_ymd;
@@ -1504,8 +1740,7 @@ impl AddAssign<OldDuration> for NaiveDate {
/// assert_eq!(from_ymd(2014, 1, 1) - Duration::days(364), from_ymd(2013, 1, 2));
/// assert_eq!(from_ymd(2014, 1, 1) - Duration::days(365*4 + 1), from_ymd(2010, 1, 1));
/// assert_eq!(from_ymd(2014, 1, 1) - Duration::days(365*400 + 97), from_ymd(1614, 1, 1));
-/// # }
-/// ~~~~
+/// ```
impl Sub<OldDuration> for NaiveDate {
type Output = NaiveDate;
@@ -1533,8 +1768,7 @@ impl SubAssign<OldDuration> for NaiveDate {
///
/// # Example
///
-/// ~~~~
-/// # extern crate chrono; fn main() {
+/// ```
/// use chrono::{Duration, NaiveDate};
///
/// let from_ymd = NaiveDate::from_ymd;
@@ -1546,8 +1780,7 @@ impl SubAssign<OldDuration> for NaiveDate {
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2013, 1, 1), Duration::days(365));
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(2010, 1, 1), Duration::days(365*4 + 1));
/// assert_eq!(from_ymd(2014, 1, 1) - from_ymd(1614, 1, 1), Duration::days(365*400 + 97));
-/// # }
-/// ~~~~
+/// ```
impl Sub<NaiveDate> for NaiveDate {
type Output = OldDuration;
@@ -1567,24 +1800,35 @@ impl Iterator for NaiveDateDaysIterator {
type Item = NaiveDate;
fn next(&mut self) -> Option<Self::Item> {
- if self.value == MAX_DATE {
+ if self.value == NaiveDate::MAX {
return None;
}
- // current < MAX_DATE from here on:
+ // current < NaiveDate::MAX from here on:
let current = self.value;
- // This can't panic because current is < MAX_DATE:
- self.value = current.succ();
+ // This can't panic because current is < NaiveDate::MAX:
+ self.value = current.succ_opt().unwrap();
Some(current)
}
fn size_hint(&self) -> (usize, Option<usize>) {
- let exact_size = MAX_DATE.signed_duration_since(self.value).num_days();
+ let exact_size = NaiveDate::MAX.signed_duration_since(self.value).num_days();
(exact_size as usize, Some(exact_size as usize))
}
}
impl ExactSizeIterator for NaiveDateDaysIterator {}
+impl DoubleEndedIterator for NaiveDateDaysIterator {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ if self.value == NaiveDate::MIN {
+ return None;
+ }
+ let current = self.value;
+ self.value = current.pred_opt().unwrap();
+ Some(current)
+ }
+}
+
#[derive(Debug, Copy, Clone, Hash, PartialEq, PartialOrd, Eq, Ord)]
pub struct NaiveDateWeeksIterator {
value: NaiveDate,
@@ -1594,7 +1838,7 @@ impl Iterator for NaiveDateWeeksIterator {
type Item = NaiveDate;
fn next(&mut self) -> Option<Self::Item> {
- if MAX_DATE - self.value < OldDuration::weeks(1) {
+ if NaiveDate::MAX - self.value < OldDuration::weeks(1) {
return None;
}
let current = self.value;
@@ -1603,13 +1847,24 @@ impl Iterator for NaiveDateWeeksIterator {
}
fn size_hint(&self) -> (usize, Option<usize>) {
- let exact_size = MAX_DATE.signed_duration_since(self.value).num_weeks();
+ let exact_size = NaiveDate::MAX.signed_duration_since(self.value).num_weeks();
(exact_size as usize, Some(exact_size as usize))
}
}
impl ExactSizeIterator for NaiveDateWeeksIterator {}
+impl DoubleEndedIterator for NaiveDateWeeksIterator {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ if self.value - NaiveDate::MIN < OldDuration::weeks(1) {
+ return None;
+ }
+ let current = self.value;
+ self.value = current - OldDuration::weeks(1);
+ Some(current)
+ }
+}
+
// TODO: NaiveDateDaysIterator and NaiveDateWeeksIterator should implement FusedIterator,
// TrustedLen, and Step once they becomes stable.
// See: https://github.com/chronotope/chrono/issues/208
@@ -1621,31 +1876,39 @@ impl ExactSizeIterator for NaiveDateWeeksIterator {}
///
/// # Example
///
-/// ~~~~
+/// ```
/// use chrono::NaiveDate;
///
-/// assert_eq!(format!("{:?}", NaiveDate::from_ymd(2015, 9, 5)), "2015-09-05");
-/// assert_eq!(format!("{:?}", NaiveDate::from_ymd( 0, 1, 1)), "0000-01-01");
-/// assert_eq!(format!("{:?}", NaiveDate::from_ymd(9999, 12, 31)), "9999-12-31");
-/// ~~~~
+/// assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(2015, 9, 5).unwrap()), "2015-09-05");
+/// assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt( 0, 1, 1).unwrap()), "0000-01-01");
+/// assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(9999, 12, 31).unwrap()), "9999-12-31");
+/// ```
///
/// ISO 8601 requires an explicit sign for years before 1 BCE or after 9999 CE.
///
-/// ~~~~
+/// ```
/// # use chrono::NaiveDate;
-/// assert_eq!(format!("{:?}", NaiveDate::from_ymd( -1, 1, 1)), "-0001-01-01");
-/// assert_eq!(format!("{:?}", NaiveDate::from_ymd(10000, 12, 31)), "+10000-12-31");
-/// ~~~~
+/// assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt( -1, 1, 1).unwrap()), "-0001-01-01");
+/// assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(10000, 12, 31).unwrap()), "+10000-12-31");
+/// ```
impl fmt::Debug for NaiveDate {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ use core::fmt::Write;
+
let year = self.year();
let mdf = self.mdf();
- if 0 <= year && year <= 9999 {
- write!(f, "{:04}-{:02}-{:02}", year, mdf.month(), mdf.day())
+ if (0..=9999).contains(&year) {
+ write_hundreds(f, (year / 100) as u8)?;
+ write_hundreds(f, (year % 100) as u8)?;
} else {
// ISO 8601 requires the explicit sign for out-of-range years
- write!(f, "{:+05}-{:02}-{:02}", year, mdf.month(), mdf.day())
+ write!(f, "{:+05}", year)?;
}
+
+ f.write_char('-')?;
+ write_hundreds(f, mdf.month() as u8)?;
+ f.write_char('-')?;
+ write_hundreds(f, mdf.day() as u8)
}
}
@@ -1656,21 +1919,21 @@ impl fmt::Debug for NaiveDate {
///
/// # Example
///
-/// ~~~~
+/// ```
/// use chrono::NaiveDate;
///
-/// assert_eq!(format!("{}", NaiveDate::from_ymd(2015, 9, 5)), "2015-09-05");
-/// assert_eq!(format!("{}", NaiveDate::from_ymd( 0, 1, 1)), "0000-01-01");
-/// assert_eq!(format!("{}", NaiveDate::from_ymd(9999, 12, 31)), "9999-12-31");
-/// ~~~~
+/// assert_eq!(format!("{}", NaiveDate::from_ymd_opt(2015, 9, 5).unwrap()), "2015-09-05");
+/// assert_eq!(format!("{}", NaiveDate::from_ymd_opt( 0, 1, 1).unwrap()), "0000-01-01");
+/// assert_eq!(format!("{}", NaiveDate::from_ymd_opt(9999, 12, 31).unwrap()), "9999-12-31");
+/// ```
///
/// ISO 8601 requires an explicit sign for years before 1 BCE or after 9999 CE.
///
-/// ~~~~
+/// ```
/// # use chrono::NaiveDate;
-/// assert_eq!(format!("{}", NaiveDate::from_ymd( -1, 1, 1)), "-0001-01-01");
-/// assert_eq!(format!("{}", NaiveDate::from_ymd(10000, 12, 31)), "+10000-12-31");
-/// ~~~~
+/// assert_eq!(format!("{}", NaiveDate::from_ymd_opt( -1, 1, 1).unwrap()), "-0001-01-01");
+/// assert_eq!(format!("{}", NaiveDate::from_ymd_opt(10000, 12, 31).unwrap()), "+10000-12-31");
+/// ```
impl fmt::Display for NaiveDate {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(self, f)
@@ -1682,22 +1945,22 @@ impl fmt::Display for NaiveDate {
///
/// # Example
///
-/// ~~~~
+/// ```
/// use chrono::NaiveDate;
///
-/// let d = NaiveDate::from_ymd(2015, 9, 18);
+/// let d = NaiveDate::from_ymd_opt(2015, 9, 18).unwrap();
/// assert_eq!("2015-09-18".parse::<NaiveDate>(), Ok(d));
///
-/// let d = NaiveDate::from_ymd(12345, 6, 7);
+/// let d = NaiveDate::from_ymd_opt(12345, 6, 7).unwrap();
/// assert_eq!("+12345-6-7".parse::<NaiveDate>(), Ok(d));
///
/// assert!("foo".parse::<NaiveDate>().is_err());
-/// ~~~~
+/// ```
impl str::FromStr for NaiveDate {
type Err = ParseError;
fn from_str(s: &str) -> ParseResult<NaiveDate> {
- const ITEMS: &'static [Item<'static>] = &[
+ const ITEMS: &[Item<'static>] = &[
Item::Numeric(Numeric::Year, Pad::Zero),
Item::Space(""),
Item::Literal("-"),
@@ -1714,17 +1977,42 @@ impl str::FromStr for NaiveDate {
}
}
+/// The default value for a NaiveDate is 1st of January 1970.
+///
+/// # Example
+///
+/// ```rust
+/// use chrono::NaiveDate;
+///
+/// let default_date = NaiveDate::default();
+/// assert_eq!(default_date, NaiveDate::from_ymd_opt(1970, 1, 1).unwrap());
+/// ```
+impl Default for NaiveDate {
+ fn default() -> Self {
+ NaiveDate::from_ymd_opt(1970, 1, 1).unwrap()
+ }
+}
+
#[cfg(all(test, any(feature = "rustc-serialize", feature = "serde")))]
fn test_encodable_json<F, E>(to_string: F)
where
F: Fn(&NaiveDate) -> Result<String, E>,
E: ::std::fmt::Debug,
{
- assert_eq!(to_string(&NaiveDate::from_ymd(2014, 7, 24)).ok(), Some(r#""2014-07-24""#.into()));
- assert_eq!(to_string(&NaiveDate::from_ymd(0, 1, 1)).ok(), Some(r#""0000-01-01""#.into()));
- assert_eq!(to_string(&NaiveDate::from_ymd(-1, 12, 31)).ok(), Some(r#""-0001-12-31""#.into()));
- assert_eq!(to_string(&MIN_DATE).ok(), Some(r#""-262144-01-01""#.into()));
- assert_eq!(to_string(&MAX_DATE).ok(), Some(r#""+262143-12-31""#.into()));
+ assert_eq!(
+ to_string(&NaiveDate::from_ymd_opt(2014, 7, 24).unwrap()).ok(),
+ Some(r#""2014-07-24""#.into())
+ );
+ assert_eq!(
+ to_string(&NaiveDate::from_ymd_opt(0, 1, 1).unwrap()).ok(),
+ Some(r#""0000-01-01""#.into())
+ );
+ assert_eq!(
+ to_string(&NaiveDate::from_ymd_opt(-1, 12, 31).unwrap()).ok(),
+ Some(r#""-0001-12-31""#.into())
+ );
+ assert_eq!(to_string(&NaiveDate::MIN).ok(), Some(r#""-262144-01-01""#.into()));
+ assert_eq!(to_string(&NaiveDate::MAX).ok(), Some(r#""+262143-12-31""#.into()));
}
#[cfg(all(test, any(feature = "rustc-serialize", feature = "serde")))]
@@ -1735,14 +2023,20 @@ where
{
use std::{i32, i64};
- assert_eq!(from_str(r#""2016-07-08""#).ok(), Some(NaiveDate::from_ymd(2016, 7, 8)));
- assert_eq!(from_str(r#""2016-7-8""#).ok(), Some(NaiveDate::from_ymd(2016, 7, 8)));
- assert_eq!(from_str(r#""+002016-07-08""#).ok(), Some(NaiveDate::from_ymd(2016, 7, 8)));
- assert_eq!(from_str(r#""0000-01-01""#).ok(), Some(NaiveDate::from_ymd(0, 1, 1)));
- assert_eq!(from_str(r#""0-1-1""#).ok(), Some(NaiveDate::from_ymd(0, 1, 1)));
- assert_eq!(from_str(r#""-0001-12-31""#).ok(), Some(NaiveDate::from_ymd(-1, 12, 31)));
- assert_eq!(from_str(r#""-262144-01-01""#).ok(), Some(MIN_DATE));
- assert_eq!(from_str(r#""+262143-12-31""#).ok(), Some(MAX_DATE));
+ assert_eq!(
+ from_str(r#""2016-07-08""#).ok(),
+ Some(NaiveDate::from_ymd_opt(2016, 7, 8).unwrap())
+ );
+ assert_eq!(from_str(r#""2016-7-8""#).ok(), Some(NaiveDate::from_ymd_opt(2016, 7, 8).unwrap()));
+ assert_eq!(from_str(r#""+002016-07-08""#).ok(), NaiveDate::from_ymd_opt(2016, 7, 8));
+ assert_eq!(from_str(r#""0000-01-01""#).ok(), Some(NaiveDate::from_ymd_opt(0, 1, 1).unwrap()));
+ assert_eq!(from_str(r#""0-1-1""#).ok(), Some(NaiveDate::from_ymd_opt(0, 1, 1).unwrap()));
+ assert_eq!(
+ from_str(r#""-0001-12-31""#).ok(),
+ Some(NaiveDate::from_ymd_opt(-1, 12, 31).unwrap())
+ );
+ assert_eq!(from_str(r#""-262144-01-01""#).ok(), Some(NaiveDate::MIN));
+ assert_eq!(from_str(r#""+262143-12-31""#).ok(), Some(NaiveDate::MAX));
// bad formats
assert!(from_str(r#""""#).is_err());
@@ -1765,6 +2059,7 @@ where
}
#[cfg(feature = "rustc-serialize")]
+#[cfg_attr(docsrs, doc(cfg(feature = "rustc-serialize")))]
mod rustc_serialize {
use super::NaiveDate;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
@@ -1796,10 +2091,11 @@ mod rustc_serialize {
}
#[cfg(feature = "serde")]
+#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
mod serde {
use super::NaiveDate;
use core::fmt;
- use serdelib::{de, ser};
+ use serde::{de, ser};
// TODO not very optimized for space (binary formats would want something better)
@@ -1828,11 +2124,11 @@ mod serde {
type Value = NaiveDate;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- write!(formatter, "a formatted date string")
+ formatter.write_str("a formatted date string")
}
#[cfg(any(feature = "std", test))]
- fn visit_str<E>(self, value: &str) -> Result<NaiveDate, E>
+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
@@ -1840,7 +2136,7 @@ mod serde {
}
#[cfg(not(any(feature = "std", test)))]
- fn visit_str<E>(self, value: &str) -> Result<NaiveDate, E>
+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
@@ -1857,29 +2153,24 @@ mod serde {
}
}
- #[cfg(test)]
- extern crate bincode;
- #[cfg(test)]
- extern crate serde_json;
-
#[test]
fn test_serde_serialize() {
- super::test_encodable_json(self::serde_json::to_string);
+ super::test_encodable_json(serde_json::to_string);
}
#[test]
fn test_serde_deserialize() {
- super::test_decodable_json(|input| self::serde_json::from_str(&input));
+ super::test_decodable_json(|input| serde_json::from_str(input));
}
#[test]
fn test_serde_bincode() {
// Bincode is relevant to test separately from JSON because
// it is not self-describing.
- use self::bincode::{deserialize, serialize, Infinite};
+ use bincode::{deserialize, serialize};
- let d = NaiveDate::from_ymd(2014, 7, 24);
- let encoded = serialize(&d, Infinite).unwrap();
+ let d = NaiveDate::from_ymd_opt(2014, 7, 24).unwrap();
+ let encoded = serialize(&d).unwrap();
let decoded: NaiveDate = deserialize(&encoded).unwrap();
assert_eq!(d, decoded);
}
@@ -1887,16 +2178,131 @@ mod serde {
#[cfg(test)]
mod tests {
- use super::NaiveDate;
- use super::{MAX_DATE, MAX_DAYS_FROM_YEAR_0, MAX_YEAR};
- use super::{MIN_DATE, MIN_DAYS_FROM_YEAR_0, MIN_YEAR};
- use oldtime::Duration;
- use std::{i32, u32};
- use {Datelike, Weekday};
+ use super::{
+ Days, Months, NaiveDate, MAX_DAYS_FROM_YEAR_0, MAX_YEAR, MIN_DAYS_FROM_YEAR_0, MIN_YEAR,
+ };
+ use crate::oldtime::Duration;
+ use crate::{Datelike, Weekday};
+ use std::{
+ convert::{TryFrom, TryInto},
+ i32, u32,
+ };
+
+ #[test]
+ fn diff_months() {
+ // identity
+ assert_eq!(
+ NaiveDate::from_ymd_opt(2022, 8, 3).unwrap().checked_add_months(Months::new(0)),
+ Some(NaiveDate::from_ymd_opt(2022, 8, 3).unwrap())
+ );
+
+ // add with months exceeding `i32::MAX`
+ assert_eq!(
+ NaiveDate::from_ymd_opt(2022, 8, 3)
+ .unwrap()
+ .checked_add_months(Months::new(i32::MAX as u32 + 1)),
+ None
+ );
+
+ // sub with months exceeding `i32::MIN`
+ assert_eq!(
+ NaiveDate::from_ymd_opt(2022, 8, 3)
+ .unwrap()
+ .checked_sub_months(Months::new((i32::MIN as i64).abs() as u32 + 1)),
+ None
+ );
+
+ // add overflowing year
+ assert_eq!(NaiveDate::MAX.checked_add_months(Months::new(1)), None);
+
+ // add underflowing year
+ assert_eq!(NaiveDate::MIN.checked_sub_months(Months::new(1)), None);
+
+ // sub crossing year 0 boundary
+ assert_eq!(
+ NaiveDate::from_ymd_opt(2022, 8, 3).unwrap().checked_sub_months(Months::new(2050 * 12)),
+ Some(NaiveDate::from_ymd_opt(-28, 8, 3).unwrap())
+ );
+
+ // add crossing year boundary
+ assert_eq!(
+ NaiveDate::from_ymd_opt(2022, 8, 3).unwrap().checked_add_months(Months::new(6)),
+ Some(NaiveDate::from_ymd_opt(2023, 2, 3).unwrap())
+ );
+
+ // sub crossing year boundary
+ assert_eq!(
+ NaiveDate::from_ymd_opt(2022, 8, 3).unwrap().checked_sub_months(Months::new(10)),
+ Some(NaiveDate::from_ymd_opt(2021, 10, 3).unwrap())
+ );
+
+ // add clamping day, non-leap year
+ assert_eq!(
+ NaiveDate::from_ymd_opt(2022, 1, 29).unwrap().checked_add_months(Months::new(1)),
+ Some(NaiveDate::from_ymd_opt(2022, 2, 28).unwrap())
+ );
+
+ // add to leap day
+ assert_eq!(
+ NaiveDate::from_ymd_opt(2022, 10, 29).unwrap().checked_add_months(Months::new(16)),
+ Some(NaiveDate::from_ymd_opt(2024, 2, 29).unwrap())
+ );
+
+ // add into december
+ assert_eq!(
+ NaiveDate::from_ymd_opt(2022, 10, 31).unwrap().checked_add_months(Months::new(2)),
+ Some(NaiveDate::from_ymd_opt(2022, 12, 31).unwrap())
+ );
+
+ // sub into december
+ assert_eq!(
+ NaiveDate::from_ymd_opt(2022, 10, 31).unwrap().checked_sub_months(Months::new(10)),
+ Some(NaiveDate::from_ymd_opt(2021, 12, 31).unwrap())
+ );
+
+ // add into january
+ assert_eq!(
+ NaiveDate::from_ymd_opt(2022, 8, 3).unwrap().checked_add_months(Months::new(5)),
+ Some(NaiveDate::from_ymd_opt(2023, 1, 3).unwrap())
+ );
+
+ // sub into january
+ assert_eq!(
+ NaiveDate::from_ymd_opt(2022, 8, 3).unwrap().checked_sub_months(Months::new(7)),
+ Some(NaiveDate::from_ymd_opt(2022, 1, 3).unwrap())
+ );
+ }
+
+ #[test]
+ fn test_readme_doomsday() {
+ use num_iter::range_inclusive;
+
+ for y in range_inclusive(NaiveDate::MIN.year(), NaiveDate::MAX.year()) {
+ // even months
+ let d4 = NaiveDate::from_ymd_opt(y, 4, 4).unwrap();
+ let d6 = NaiveDate::from_ymd_opt(y, 6, 6).unwrap();
+ let d8 = NaiveDate::from_ymd_opt(y, 8, 8).unwrap();
+ let d10 = NaiveDate::from_ymd_opt(y, 10, 10).unwrap();
+ let d12 = NaiveDate::from_ymd_opt(y, 12, 12).unwrap();
+
+ // nine to five, seven-eleven
+ let d59 = NaiveDate::from_ymd_opt(y, 5, 9).unwrap();
+ let d95 = NaiveDate::from_ymd_opt(y, 9, 5).unwrap();
+ let d711 = NaiveDate::from_ymd_opt(y, 7, 11).unwrap();
+ let d117 = NaiveDate::from_ymd_opt(y, 11, 7).unwrap();
+
+ // "March 0"
+ let d30 = NaiveDate::from_ymd_opt(y, 3, 1).unwrap().pred_opt().unwrap();
+
+ let weekday = d30.weekday();
+ let other_dates = [d4, d6, d8, d10, d12, d59, d95, d711, d117];
+ assert!(other_dates.iter().all(|d| d.weekday() == weekday));
+ }
+ }
#[test]
fn test_date_from_ymd() {
- let ymd_opt = |y, m, d| NaiveDate::from_ymd_opt(y, m, d);
+ let ymd_opt = NaiveDate::from_ymd_opt;
assert!(ymd_opt(2012, 0, 1).is_none());
assert!(ymd_opt(2012, 1, 1).is_some());
@@ -1912,8 +2318,8 @@ mod tests {
#[test]
fn test_date_from_yo() {
- let yo_opt = |y, o| NaiveDate::from_yo_opt(y, o);
- let ymd = |y, m, d| NaiveDate::from_ymd(y, m, d);
+ let yo_opt = NaiveDate::from_yo_opt;
+ let ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
assert_eq!(yo_opt(2012, 0), None);
assert_eq!(yo_opt(2012, 1), Some(ymd(2012, 1, 1)));
@@ -1942,8 +2348,8 @@ mod tests {
#[test]
fn test_date_from_isoywd() {
- let isoywd_opt = |y, w, d| NaiveDate::from_isoywd_opt(y, w, d);
- let ymd = |y, m, d| NaiveDate::from_ymd(y, m, d);
+ let isoywd_opt = NaiveDate::from_isoywd_opt;
+ let ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
assert_eq!(isoywd_opt(2004, 0, Weekday::Sun), None);
assert_eq!(isoywd_opt(2004, 1, Weekday::Mon), Some(ymd(2003, 12, 29)));
@@ -1985,8 +2391,7 @@ mod tests {
.iter()
{
let d = NaiveDate::from_isoywd_opt(year, week, weekday);
- if d.is_some() {
- let d = d.unwrap();
+ if let Some(d) = d {
assert_eq!(d.weekday(), weekday);
let w = d.iso_week();
assert_eq!(w.year(), year);
@@ -2000,11 +2405,10 @@ mod tests {
for month in 1..13 {
for day in 1..32 {
let d = NaiveDate::from_ymd_opt(year, month, day);
- if d.is_some() {
- let d = d.unwrap();
+ if let Some(d) = d {
let w = d.iso_week();
- let d_ = NaiveDate::from_isoywd(w.year(), w.week(), d.weekday());
- assert_eq!(d, d_);
+ let d_ = NaiveDate::from_isoywd_opt(w.year(), w.week(), d.weekday());
+ assert_eq!(d, d_.unwrap());
}
}
}
@@ -2013,63 +2417,111 @@ mod tests {
#[test]
fn test_date_from_num_days_from_ce() {
- let from_ndays_from_ce = |days| NaiveDate::from_num_days_from_ce_opt(days);
- assert_eq!(from_ndays_from_ce(1), Some(NaiveDate::from_ymd(1, 1, 1)));
- assert_eq!(from_ndays_from_ce(2), Some(NaiveDate::from_ymd(1, 1, 2)));
- assert_eq!(from_ndays_from_ce(31), Some(NaiveDate::from_ymd(1, 1, 31)));
- assert_eq!(from_ndays_from_ce(32), Some(NaiveDate::from_ymd(1, 2, 1)));
- assert_eq!(from_ndays_from_ce(59), Some(NaiveDate::from_ymd(1, 2, 28)));
- assert_eq!(from_ndays_from_ce(60), Some(NaiveDate::from_ymd(1, 3, 1)));
- assert_eq!(from_ndays_from_ce(365), Some(NaiveDate::from_ymd(1, 12, 31)));
- assert_eq!(from_ndays_from_ce(365 * 1 + 1), Some(NaiveDate::from_ymd(2, 1, 1)));
- assert_eq!(from_ndays_from_ce(365 * 2 + 1), Some(NaiveDate::from_ymd(3, 1, 1)));
- assert_eq!(from_ndays_from_ce(365 * 3 + 1), Some(NaiveDate::from_ymd(4, 1, 1)));
- assert_eq!(from_ndays_from_ce(365 * 4 + 2), Some(NaiveDate::from_ymd(5, 1, 1)));
- assert_eq!(from_ndays_from_ce(146097 + 1), Some(NaiveDate::from_ymd(401, 1, 1)));
- assert_eq!(from_ndays_from_ce(146097 * 5 + 1), Some(NaiveDate::from_ymd(2001, 1, 1)));
- assert_eq!(from_ndays_from_ce(719163), Some(NaiveDate::from_ymd(1970, 1, 1)));
- assert_eq!(from_ndays_from_ce(0), Some(NaiveDate::from_ymd(0, 12, 31))); // 1 BCE
- assert_eq!(from_ndays_from_ce(-365), Some(NaiveDate::from_ymd(0, 1, 1)));
- assert_eq!(from_ndays_from_ce(-366), Some(NaiveDate::from_ymd(-1, 12, 31))); // 2 BCE
+ let from_ndays_from_ce = NaiveDate::from_num_days_from_ce_opt;
+ assert_eq!(from_ndays_from_ce(1), Some(NaiveDate::from_ymd_opt(1, 1, 1).unwrap()));
+ assert_eq!(from_ndays_from_ce(2), Some(NaiveDate::from_ymd_opt(1, 1, 2).unwrap()));
+ assert_eq!(from_ndays_from_ce(31), Some(NaiveDate::from_ymd_opt(1, 1, 31).unwrap()));
+ assert_eq!(from_ndays_from_ce(32), Some(NaiveDate::from_ymd_opt(1, 2, 1).unwrap()));
+ assert_eq!(from_ndays_from_ce(59), Some(NaiveDate::from_ymd_opt(1, 2, 28).unwrap()));
+ assert_eq!(from_ndays_from_ce(60), Some(NaiveDate::from_ymd_opt(1, 3, 1).unwrap()));
+ assert_eq!(from_ndays_from_ce(365), Some(NaiveDate::from_ymd_opt(1, 12, 31).unwrap()));
+ assert_eq!(from_ndays_from_ce(365 + 1), Some(NaiveDate::from_ymd_opt(2, 1, 1).unwrap()));
+ assert_eq!(
+ from_ndays_from_ce(365 * 2 + 1),
+ Some(NaiveDate::from_ymd_opt(3, 1, 1).unwrap())
+ );
+ assert_eq!(
+ from_ndays_from_ce(365 * 3 + 1),
+ Some(NaiveDate::from_ymd_opt(4, 1, 1).unwrap())
+ );
+ assert_eq!(
+ from_ndays_from_ce(365 * 4 + 2),
+ Some(NaiveDate::from_ymd_opt(5, 1, 1).unwrap())
+ );
+ assert_eq!(
+ from_ndays_from_ce(146097 + 1),
+ Some(NaiveDate::from_ymd_opt(401, 1, 1).unwrap())
+ );
+ assert_eq!(
+ from_ndays_from_ce(146097 * 5 + 1),
+ Some(NaiveDate::from_ymd_opt(2001, 1, 1).unwrap())
+ );
+ assert_eq!(from_ndays_from_ce(719163), Some(NaiveDate::from_ymd_opt(1970, 1, 1).unwrap()));
+ assert_eq!(from_ndays_from_ce(0), Some(NaiveDate::from_ymd_opt(0, 12, 31).unwrap())); // 1 BCE
+ assert_eq!(from_ndays_from_ce(-365), Some(NaiveDate::from_ymd_opt(0, 1, 1).unwrap()));
+ assert_eq!(from_ndays_from_ce(-366), Some(NaiveDate::from_ymd_opt(-1, 12, 31).unwrap())); // 2 BCE
for days in (-9999..10001).map(|x| x * 100) {
assert_eq!(from_ndays_from_ce(days).map(|d| d.num_days_from_ce()), Some(days));
}
- assert_eq!(from_ndays_from_ce(MIN_DATE.num_days_from_ce()), Some(MIN_DATE));
- assert_eq!(from_ndays_from_ce(MIN_DATE.num_days_from_ce() - 1), None);
- assert_eq!(from_ndays_from_ce(MAX_DATE.num_days_from_ce()), Some(MAX_DATE));
- assert_eq!(from_ndays_from_ce(MAX_DATE.num_days_from_ce() + 1), None);
+ assert_eq!(from_ndays_from_ce(NaiveDate::MIN.num_days_from_ce()), Some(NaiveDate::MIN));
+ assert_eq!(from_ndays_from_ce(NaiveDate::MIN.num_days_from_ce() - 1), None);
+ assert_eq!(from_ndays_from_ce(NaiveDate::MAX.num_days_from_ce()), Some(NaiveDate::MAX));
+ assert_eq!(from_ndays_from_ce(NaiveDate::MAX.num_days_from_ce() + 1), None);
}
#[test]
fn test_date_from_weekday_of_month_opt() {
- let ymwd = |y, m, w, n| NaiveDate::from_weekday_of_month_opt(y, m, w, n);
+ let ymwd = NaiveDate::from_weekday_of_month_opt;
assert_eq!(ymwd(2018, 8, Weekday::Tue, 0), None);
- assert_eq!(ymwd(2018, 8, Weekday::Wed, 1), Some(NaiveDate::from_ymd(2018, 8, 1)));
- assert_eq!(ymwd(2018, 8, Weekday::Thu, 1), Some(NaiveDate::from_ymd(2018, 8, 2)));
- assert_eq!(ymwd(2018, 8, Weekday::Sun, 1), Some(NaiveDate::from_ymd(2018, 8, 5)));
- assert_eq!(ymwd(2018, 8, Weekday::Mon, 1), Some(NaiveDate::from_ymd(2018, 8, 6)));
- assert_eq!(ymwd(2018, 8, Weekday::Tue, 1), Some(NaiveDate::from_ymd(2018, 8, 7)));
- assert_eq!(ymwd(2018, 8, Weekday::Wed, 2), Some(NaiveDate::from_ymd(2018, 8, 8)));
- assert_eq!(ymwd(2018, 8, Weekday::Sun, 2), Some(NaiveDate::from_ymd(2018, 8, 12)));
- assert_eq!(ymwd(2018, 8, Weekday::Thu, 3), Some(NaiveDate::from_ymd(2018, 8, 16)));
- assert_eq!(ymwd(2018, 8, Weekday::Thu, 4), Some(NaiveDate::from_ymd(2018, 8, 23)));
- assert_eq!(ymwd(2018, 8, Weekday::Thu, 5), Some(NaiveDate::from_ymd(2018, 8, 30)));
- assert_eq!(ymwd(2018, 8, Weekday::Fri, 5), Some(NaiveDate::from_ymd(2018, 8, 31)));
+ assert_eq!(
+ ymwd(2018, 8, Weekday::Wed, 1),
+ Some(NaiveDate::from_ymd_opt(2018, 8, 1).unwrap())
+ );
+ assert_eq!(
+ ymwd(2018, 8, Weekday::Thu, 1),
+ Some(NaiveDate::from_ymd_opt(2018, 8, 2).unwrap())
+ );
+ assert_eq!(
+ ymwd(2018, 8, Weekday::Sun, 1),
+ Some(NaiveDate::from_ymd_opt(2018, 8, 5).unwrap())
+ );
+ assert_eq!(
+ ymwd(2018, 8, Weekday::Mon, 1),
+ Some(NaiveDate::from_ymd_opt(2018, 8, 6).unwrap())
+ );
+ assert_eq!(
+ ymwd(2018, 8, Weekday::Tue, 1),
+ Some(NaiveDate::from_ymd_opt(2018, 8, 7).unwrap())
+ );
+ assert_eq!(
+ ymwd(2018, 8, Weekday::Wed, 2),
+ Some(NaiveDate::from_ymd_opt(2018, 8, 8).unwrap())
+ );
+ assert_eq!(
+ ymwd(2018, 8, Weekday::Sun, 2),
+ Some(NaiveDate::from_ymd_opt(2018, 8, 12).unwrap())
+ );
+ assert_eq!(
+ ymwd(2018, 8, Weekday::Thu, 3),
+ Some(NaiveDate::from_ymd_opt(2018, 8, 16).unwrap())
+ );
+ assert_eq!(
+ ymwd(2018, 8, Weekday::Thu, 4),
+ Some(NaiveDate::from_ymd_opt(2018, 8, 23).unwrap())
+ );
+ assert_eq!(
+ ymwd(2018, 8, Weekday::Thu, 5),
+ Some(NaiveDate::from_ymd_opt(2018, 8, 30).unwrap())
+ );
+ assert_eq!(
+ ymwd(2018, 8, Weekday::Fri, 5),
+ Some(NaiveDate::from_ymd_opt(2018, 8, 31).unwrap())
+ );
assert_eq!(ymwd(2018, 8, Weekday::Sat, 5), None);
}
#[test]
fn test_date_fields() {
fn check(year: i32, month: u32, day: u32, ordinal: u32) {
- let d1 = NaiveDate::from_ymd(year, month, day);
+ let d1 = NaiveDate::from_ymd_opt(year, month, day).unwrap();
assert_eq!(d1.year(), year);
assert_eq!(d1.month(), month);
assert_eq!(d1.day(), day);
assert_eq!(d1.ordinal(), ordinal);
- let d2 = NaiveDate::from_yo(year, ordinal);
+ let d2 = NaiveDate::from_yo_opt(year, ordinal).unwrap();
assert_eq!(d2.year(), year);
assert_eq!(d2.month(), month);
assert_eq!(d2.day(), day);
@@ -2101,88 +2553,88 @@ mod tests {
#[test]
fn test_date_weekday() {
- assert_eq!(NaiveDate::from_ymd(1582, 10, 15).weekday(), Weekday::Fri);
+ assert_eq!(NaiveDate::from_ymd_opt(1582, 10, 15).unwrap().weekday(), Weekday::Fri);
// May 20, 1875 = ISO 8601 reference date
- assert_eq!(NaiveDate::from_ymd(1875, 5, 20).weekday(), Weekday::Thu);
- assert_eq!(NaiveDate::from_ymd(2000, 1, 1).weekday(), Weekday::Sat);
+ assert_eq!(NaiveDate::from_ymd_opt(1875, 5, 20).unwrap().weekday(), Weekday::Thu);
+ assert_eq!(NaiveDate::from_ymd_opt(2000, 1, 1).unwrap().weekday(), Weekday::Sat);
}
#[test]
fn test_date_with_fields() {
- let d = NaiveDate::from_ymd(2000, 2, 29);
- assert_eq!(d.with_year(-400), Some(NaiveDate::from_ymd(-400, 2, 29)));
+ let d = NaiveDate::from_ymd_opt(2000, 2, 29).unwrap();
+ assert_eq!(d.with_year(-400), Some(NaiveDate::from_ymd_opt(-400, 2, 29).unwrap()));
assert_eq!(d.with_year(-100), None);
- assert_eq!(d.with_year(1600), Some(NaiveDate::from_ymd(1600, 2, 29)));
+ assert_eq!(d.with_year(1600), Some(NaiveDate::from_ymd_opt(1600, 2, 29).unwrap()));
assert_eq!(d.with_year(1900), None);
- assert_eq!(d.with_year(2000), Some(NaiveDate::from_ymd(2000, 2, 29)));
+ assert_eq!(d.with_year(2000), Some(NaiveDate::from_ymd_opt(2000, 2, 29).unwrap()));
assert_eq!(d.with_year(2001), None);
- assert_eq!(d.with_year(2004), Some(NaiveDate::from_ymd(2004, 2, 29)));
+ assert_eq!(d.with_year(2004), Some(NaiveDate::from_ymd_opt(2004, 2, 29).unwrap()));
assert_eq!(d.with_year(i32::MAX), None);
- let d = NaiveDate::from_ymd(2000, 4, 30);
+ let d = NaiveDate::from_ymd_opt(2000, 4, 30).unwrap();
assert_eq!(d.with_month(0), None);
- assert_eq!(d.with_month(1), Some(NaiveDate::from_ymd(2000, 1, 30)));
+ assert_eq!(d.with_month(1), Some(NaiveDate::from_ymd_opt(2000, 1, 30).unwrap()));
assert_eq!(d.with_month(2), None);
- assert_eq!(d.with_month(3), Some(NaiveDate::from_ymd(2000, 3, 30)));
- assert_eq!(d.with_month(4), Some(NaiveDate::from_ymd(2000, 4, 30)));
- assert_eq!(d.with_month(12), Some(NaiveDate::from_ymd(2000, 12, 30)));
+ assert_eq!(d.with_month(3), Some(NaiveDate::from_ymd_opt(2000, 3, 30).unwrap()));
+ assert_eq!(d.with_month(4), Some(NaiveDate::from_ymd_opt(2000, 4, 30).unwrap()));
+ assert_eq!(d.with_month(12), Some(NaiveDate::from_ymd_opt(2000, 12, 30).unwrap()));
assert_eq!(d.with_month(13), None);
assert_eq!(d.with_month(u32::MAX), None);
- let d = NaiveDate::from_ymd(2000, 2, 8);
+ let d = NaiveDate::from_ymd_opt(2000, 2, 8).unwrap();
assert_eq!(d.with_day(0), None);
- assert_eq!(d.with_day(1), Some(NaiveDate::from_ymd(2000, 2, 1)));
- assert_eq!(d.with_day(29), Some(NaiveDate::from_ymd(2000, 2, 29)));
+ assert_eq!(d.with_day(1), Some(NaiveDate::from_ymd_opt(2000, 2, 1).unwrap()));
+ assert_eq!(d.with_day(29), Some(NaiveDate::from_ymd_opt(2000, 2, 29).unwrap()));
assert_eq!(d.with_day(30), None);
assert_eq!(d.with_day(u32::MAX), None);
- let d = NaiveDate::from_ymd(2000, 5, 5);
+ let d = NaiveDate::from_ymd_opt(2000, 5, 5).unwrap();
assert_eq!(d.with_ordinal(0), None);
- assert_eq!(d.with_ordinal(1), Some(NaiveDate::from_ymd(2000, 1, 1)));
- assert_eq!(d.with_ordinal(60), Some(NaiveDate::from_ymd(2000, 2, 29)));
- assert_eq!(d.with_ordinal(61), Some(NaiveDate::from_ymd(2000, 3, 1)));
- assert_eq!(d.with_ordinal(366), Some(NaiveDate::from_ymd(2000, 12, 31)));
+ assert_eq!(d.with_ordinal(1), Some(NaiveDate::from_ymd_opt(2000, 1, 1).unwrap()));
+ assert_eq!(d.with_ordinal(60), Some(NaiveDate::from_ymd_opt(2000, 2, 29).unwrap()));
+ assert_eq!(d.with_ordinal(61), Some(NaiveDate::from_ymd_opt(2000, 3, 1).unwrap()));
+ assert_eq!(d.with_ordinal(366), Some(NaiveDate::from_ymd_opt(2000, 12, 31).unwrap()));
assert_eq!(d.with_ordinal(367), None);
assert_eq!(d.with_ordinal(u32::MAX), None);
}
#[test]
fn test_date_num_days_from_ce() {
- assert_eq!(NaiveDate::from_ymd(1, 1, 1).num_days_from_ce(), 1);
+ assert_eq!(NaiveDate::from_ymd_opt(1, 1, 1).unwrap().num_days_from_ce(), 1);
for year in -9999..10001 {
assert_eq!(
- NaiveDate::from_ymd(year, 1, 1).num_days_from_ce(),
- NaiveDate::from_ymd(year - 1, 12, 31).num_days_from_ce() + 1
+ NaiveDate::from_ymd_opt(year, 1, 1).unwrap().num_days_from_ce(),
+ NaiveDate::from_ymd_opt(year - 1, 12, 31).unwrap().num_days_from_ce() + 1
);
}
}
#[test]
fn test_date_succ() {
- let ymd = |y, m, d| NaiveDate::from_ymd(y, m, d);
+ let ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
assert_eq!(ymd(2014, 5, 6).succ_opt(), Some(ymd(2014, 5, 7)));
assert_eq!(ymd(2014, 5, 31).succ_opt(), Some(ymd(2014, 6, 1)));
assert_eq!(ymd(2014, 12, 31).succ_opt(), Some(ymd(2015, 1, 1)));
assert_eq!(ymd(2016, 2, 28).succ_opt(), Some(ymd(2016, 2, 29)));
- assert_eq!(ymd(MAX_DATE.year(), 12, 31).succ_opt(), None);
+ assert_eq!(ymd(NaiveDate::MAX.year(), 12, 31).succ_opt(), None);
}
#[test]
fn test_date_pred() {
- let ymd = |y, m, d| NaiveDate::from_ymd(y, m, d);
+ let ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
assert_eq!(ymd(2016, 3, 1).pred_opt(), Some(ymd(2016, 2, 29)));
assert_eq!(ymd(2015, 1, 1).pred_opt(), Some(ymd(2014, 12, 31)));
assert_eq!(ymd(2014, 6, 1).pred_opt(), Some(ymd(2014, 5, 31)));
assert_eq!(ymd(2014, 5, 7).pred_opt(), Some(ymd(2014, 5, 6)));
- assert_eq!(ymd(MIN_DATE.year(), 1, 1).pred_opt(), None);
+ assert_eq!(ymd(NaiveDate::MIN.year(), 1, 1).pred_opt(), None);
}
#[test]
fn test_date_add() {
fn check((y1, m1, d1): (i32, u32, u32), rhs: Duration, ymd: Option<(i32, u32, u32)>) {
- let lhs = NaiveDate::from_ymd(y1, m1, d1);
- let sum = ymd.map(|(y, m, d)| NaiveDate::from_ymd(y, m, d));
+ let lhs = NaiveDate::from_ymd_opt(y1, m1, d1).unwrap();
+ let sum = ymd.map(|(y, m, d)| NaiveDate::from_ymd_opt(y, m, d).unwrap());
assert_eq!(lhs.checked_add_signed(rhs), sum);
assert_eq!(lhs.checked_sub_signed(-rhs), sum);
}
@@ -2211,8 +2663,8 @@ mod tests {
#[test]
fn test_date_sub() {
fn check((y1, m1, d1): (i32, u32, u32), (y2, m2, d2): (i32, u32, u32), diff: Duration) {
- let lhs = NaiveDate::from_ymd(y1, m1, d1);
- let rhs = NaiveDate::from_ymd(y2, m2, d2);
+ let lhs = NaiveDate::from_ymd_opt(y1, m1, d1).unwrap();
+ let rhs = NaiveDate::from_ymd_opt(y2, m2, d2).unwrap();
assert_eq!(lhs.signed_duration_since(rhs), diff);
assert_eq!(rhs.signed_duration_since(lhs), -diff);
}
@@ -2229,8 +2681,53 @@ mod tests {
}
#[test]
+ fn test_date_add_days() {
+ fn check((y1, m1, d1): (i32, u32, u32), rhs: Days, ymd: Option<(i32, u32, u32)>) {
+ let lhs = NaiveDate::from_ymd_opt(y1, m1, d1).unwrap();
+ let sum = ymd.map(|(y, m, d)| NaiveDate::from_ymd_opt(y, m, d).unwrap());
+ assert_eq!(lhs.checked_add_days(rhs), sum);
+ }
+
+ check((2014, 1, 1), Days::new(0), Some((2014, 1, 1)));
+ // always round towards zero
+ check((2014, 1, 1), Days::new(1), Some((2014, 1, 2)));
+ check((2014, 1, 1), Days::new(364), Some((2014, 12, 31)));
+ check((2014, 1, 1), Days::new(365 * 4 + 1), Some((2018, 1, 1)));
+ check((2014, 1, 1), Days::new(365 * 400 + 97), Some((2414, 1, 1)));
+
+ check((-7, 1, 1), Days::new(365 * 12 + 3), Some((5, 1, 1)));
+
+ // overflow check
+ check(
+ (0, 1, 1),
+ Days::new(MAX_DAYS_FROM_YEAR_0.try_into().unwrap()),
+ Some((MAX_YEAR, 12, 31)),
+ );
+ check((0, 1, 1), Days::new(u64::try_from(MAX_DAYS_FROM_YEAR_0).unwrap() + 1), None);
+ }
+
+ #[test]
+ fn test_date_sub_days() {
+ fn check((y1, m1, d1): (i32, u32, u32), (y2, m2, d2): (i32, u32, u32), diff: Days) {
+ let lhs = NaiveDate::from_ymd_opt(y1, m1, d1).unwrap();
+ let rhs = NaiveDate::from_ymd_opt(y2, m2, d2).unwrap();
+ assert_eq!(lhs - diff, rhs);
+ }
+
+ check((2014, 1, 1), (2014, 1, 1), Days::new(0));
+ check((2014, 1, 2), (2014, 1, 1), Days::new(1));
+ check((2014, 12, 31), (2014, 1, 1), Days::new(364));
+ check((2015, 1, 3), (2014, 1, 1), Days::new(365 + 2));
+ check((2018, 1, 1), (2014, 1, 1), Days::new(365 * 4 + 1));
+ check((2414, 1, 1), (2014, 1, 1), Days::new(365 * 400 + 97));
+
+ check((MAX_YEAR, 12, 31), (0, 1, 1), Days::new(MAX_DAYS_FROM_YEAR_0.try_into().unwrap()));
+ check((0, 1, 1), (MIN_YEAR, 1, 1), Days::new((-MIN_DAYS_FROM_YEAR_0).try_into().unwrap()));
+ }
+
+ #[test]
fn test_date_addassignment() {
- let ymd = NaiveDate::from_ymd;
+ let ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
let mut date = ymd(2016, 10, 1);
date += Duration::days(10);
assert_eq!(date, ymd(2016, 10, 11));
@@ -2240,7 +2737,7 @@ mod tests {
#[test]
fn test_date_subassignment() {
- let ymd = NaiveDate::from_ymd;
+ let ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
let mut date = ymd(2016, 10, 11);
date -= Duration::days(10);
assert_eq!(date, ymd(2016, 10, 1));
@@ -2250,19 +2747,22 @@ mod tests {
#[test]
fn test_date_fmt() {
- assert_eq!(format!("{:?}", NaiveDate::from_ymd(2012, 3, 4)), "2012-03-04");
- assert_eq!(format!("{:?}", NaiveDate::from_ymd(0, 3, 4)), "0000-03-04");
- assert_eq!(format!("{:?}", NaiveDate::from_ymd(-307, 3, 4)), "-0307-03-04");
- assert_eq!(format!("{:?}", NaiveDate::from_ymd(12345, 3, 4)), "+12345-03-04");
+ assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(2012, 3, 4).unwrap()), "2012-03-04");
+ assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(0, 3, 4).unwrap()), "0000-03-04");
+ assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(-307, 3, 4).unwrap()), "-0307-03-04");
+ assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(12345, 3, 4).unwrap()), "+12345-03-04");
- assert_eq!(NaiveDate::from_ymd(2012, 3, 4).to_string(), "2012-03-04");
- assert_eq!(NaiveDate::from_ymd(0, 3, 4).to_string(), "0000-03-04");
- assert_eq!(NaiveDate::from_ymd(-307, 3, 4).to_string(), "-0307-03-04");
- assert_eq!(NaiveDate::from_ymd(12345, 3, 4).to_string(), "+12345-03-04");
+ assert_eq!(NaiveDate::from_ymd_opt(2012, 3, 4).unwrap().to_string(), "2012-03-04");
+ assert_eq!(NaiveDate::from_ymd_opt(0, 3, 4).unwrap().to_string(), "0000-03-04");
+ assert_eq!(NaiveDate::from_ymd_opt(-307, 3, 4).unwrap().to_string(), "-0307-03-04");
+ assert_eq!(NaiveDate::from_ymd_opt(12345, 3, 4).unwrap().to_string(), "+12345-03-04");
// the format specifier should have no effect on `NaiveTime`
- assert_eq!(format!("{:+30?}", NaiveDate::from_ymd(1234, 5, 6)), "1234-05-06");
- assert_eq!(format!("{:30?}", NaiveDate::from_ymd(12345, 6, 7)), "+12345-06-07");
+ assert_eq!(format!("{:+30?}", NaiveDate::from_ymd_opt(1234, 5, 6).unwrap()), "1234-05-06");
+ assert_eq!(
+ format!("{:30?}", NaiveDate::from_ymd_opt(12345, 6, 7).unwrap()),
+ "+12345-06-07"
+ );
}
#[test]
@@ -2318,7 +2818,7 @@ mod tests {
#[test]
fn test_date_parse_from_str() {
- let ymd = |y, m, d| NaiveDate::from_ymd(y, m, d);
+ let ymd = |y, m, d| NaiveDate::from_ymd_opt(y, m, d).unwrap();
assert_eq!(
NaiveDate::parse_from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
Ok(ymd(2014, 5, 7))
@@ -2334,11 +2834,21 @@ mod tests {
assert!(NaiveDate::parse_from_str("Sat, 09 Aug 2013", "%a, %d %b %Y").is_err());
assert!(NaiveDate::parse_from_str("2014-57", "%Y-%m-%d").is_err());
assert!(NaiveDate::parse_from_str("2014", "%Y").is_err()); // insufficient
+
+ assert_eq!(
+ NaiveDate::parse_from_str("2020-01-0", "%Y-%W-%w").ok(),
+ NaiveDate::from_ymd_opt(2020, 1, 12),
+ );
+
+ assert_eq!(
+ NaiveDate::parse_from_str("2019-01-0", "%Y-%W-%w").ok(),
+ NaiveDate::from_ymd_opt(2019, 1, 13),
+ );
}
#[test]
fn test_date_format() {
- let d = NaiveDate::from_ymd(2012, 3, 4);
+ let d = NaiveDate::from_ymd_opt(2012, 3, 4).unwrap();
assert_eq!(d.format("%Y,%C,%y,%G,%g").to_string(), "2012,20,12,2012,12");
assert_eq!(d.format("%m,%b,%h,%B").to_string(), "03,Mar,Mar,March");
assert_eq!(d.format("%d,%e").to_string(), "04, 4");
@@ -2351,33 +2861,40 @@ mod tests {
assert_eq!(d.format("%t%n%%%n%t").to_string(), "\t\n%\n\t");
// non-four-digit years
- assert_eq!(NaiveDate::from_ymd(12345, 1, 1).format("%Y").to_string(), "+12345");
- assert_eq!(NaiveDate::from_ymd(1234, 1, 1).format("%Y").to_string(), "1234");
- assert_eq!(NaiveDate::from_ymd(123, 1, 1).format("%Y").to_string(), "0123");
- assert_eq!(NaiveDate::from_ymd(12, 1, 1).format("%Y").to_string(), "0012");
- assert_eq!(NaiveDate::from_ymd(1, 1, 1).format("%Y").to_string(), "0001");
- assert_eq!(NaiveDate::from_ymd(0, 1, 1).format("%Y").to_string(), "0000");
- assert_eq!(NaiveDate::from_ymd(-1, 1, 1).format("%Y").to_string(), "-0001");
- assert_eq!(NaiveDate::from_ymd(-12, 1, 1).format("%Y").to_string(), "-0012");
- assert_eq!(NaiveDate::from_ymd(-123, 1, 1).format("%Y").to_string(), "-0123");
- assert_eq!(NaiveDate::from_ymd(-1234, 1, 1).format("%Y").to_string(), "-1234");
- assert_eq!(NaiveDate::from_ymd(-12345, 1, 1).format("%Y").to_string(), "-12345");
+ assert_eq!(
+ NaiveDate::from_ymd_opt(12345, 1, 1).unwrap().format("%Y").to_string(),
+ "+12345"
+ );
+ assert_eq!(NaiveDate::from_ymd_opt(1234, 1, 1).unwrap().format("%Y").to_string(), "1234");
+ assert_eq!(NaiveDate::from_ymd_opt(123, 1, 1).unwrap().format("%Y").to_string(), "0123");
+ assert_eq!(NaiveDate::from_ymd_opt(12, 1, 1).unwrap().format("%Y").to_string(), "0012");
+ assert_eq!(NaiveDate::from_ymd_opt(1, 1, 1).unwrap().format("%Y").to_string(), "0001");
+ assert_eq!(NaiveDate::from_ymd_opt(0, 1, 1).unwrap().format("%Y").to_string(), "0000");
+ assert_eq!(NaiveDate::from_ymd_opt(-1, 1, 1).unwrap().format("%Y").to_string(), "-0001");
+ assert_eq!(NaiveDate::from_ymd_opt(-12, 1, 1).unwrap().format("%Y").to_string(), "-0012");
+ assert_eq!(NaiveDate::from_ymd_opt(-123, 1, 1).unwrap().format("%Y").to_string(), "-0123");
+ assert_eq!(NaiveDate::from_ymd_opt(-1234, 1, 1).unwrap().format("%Y").to_string(), "-1234");
+ assert_eq!(
+ NaiveDate::from_ymd_opt(-12345, 1, 1).unwrap().format("%Y").to_string(),
+ "-12345"
+ );
// corner cases
assert_eq!(
- NaiveDate::from_ymd(2007, 12, 31).format("%G,%g,%U,%W,%V").to_string(),
- "2008,08,53,53,01"
+ NaiveDate::from_ymd_opt(2007, 12, 31).unwrap().format("%G,%g,%U,%W,%V").to_string(),
+ "2008,08,52,53,01"
);
assert_eq!(
- NaiveDate::from_ymd(2010, 1, 3).format("%G,%g,%U,%W,%V").to_string(),
+ NaiveDate::from_ymd_opt(2010, 1, 3).unwrap().format("%G,%g,%U,%W,%V").to_string(),
"2009,09,01,00,53"
);
}
#[test]
fn test_day_iterator_limit() {
+ assert_eq!(NaiveDate::from_ymd_opt(262143, 12, 29).unwrap().iter_days().take(4).count(), 2);
assert_eq!(
- NaiveDate::from_ymd(262143, 12, 29).iter_days().take(4).collect::<Vec<_>>().len(),
+ NaiveDate::from_ymd_opt(-262144, 1, 3).unwrap().iter_days().rev().take(4).count(),
2
);
}
@@ -2385,8 +2902,96 @@ mod tests {
#[test]
fn test_week_iterator_limit() {
assert_eq!(
- NaiveDate::from_ymd(262143, 12, 12).iter_weeks().take(4).collect::<Vec<_>>().len(),
+ NaiveDate::from_ymd_opt(262143, 12, 12).unwrap().iter_weeks().take(4).count(),
+ 2
+ );
+ assert_eq!(
+ NaiveDate::from_ymd_opt(-262144, 1, 15).unwrap().iter_weeks().rev().take(4).count(),
2
);
}
+
+ #[test]
+ fn test_naiveweek() {
+ let date = NaiveDate::from_ymd_opt(2022, 5, 18).unwrap();
+ let asserts = vec![
+ (Weekday::Mon, "2022-05-16", "2022-05-22"),
+ (Weekday::Tue, "2022-05-17", "2022-05-23"),
+ (Weekday::Wed, "2022-05-18", "2022-05-24"),
+ (Weekday::Thu, "2022-05-12", "2022-05-18"),
+ (Weekday::Fri, "2022-05-13", "2022-05-19"),
+ (Weekday::Sat, "2022-05-14", "2022-05-20"),
+ (Weekday::Sun, "2022-05-15", "2022-05-21"),
+ ];
+ for (start, first_day, last_day) in asserts {
+ let week = date.week(start);
+ let days = week.days();
+ assert_eq!(Ok(week.first_day()), NaiveDate::parse_from_str(first_day, "%Y-%m-%d"));
+ assert_eq!(Ok(week.last_day()), NaiveDate::parse_from_str(last_day, "%Y-%m-%d"));
+ assert!(days.contains(&date));
+ }
+ }
+
+ #[test]
+ fn test_weeks_from() {
+ // tests per: https://github.com/chronotope/chrono/issues/961
+ // these internally use `weeks_from` via the parsing infrastructure
+ assert_eq!(
+ NaiveDate::parse_from_str("2020-01-0", "%Y-%W-%w").ok(),
+ NaiveDate::from_ymd_opt(2020, 1, 12),
+ );
+ assert_eq!(
+ NaiveDate::parse_from_str("2019-01-0", "%Y-%W-%w").ok(),
+ NaiveDate::from_ymd_opt(2019, 1, 13),
+ );
+
+ // direct tests
+ for (y, starts_on) in &[
+ (2019, Weekday::Tue),
+ (2020, Weekday::Wed),
+ (2021, Weekday::Fri),
+ (2022, Weekday::Sat),
+ (2023, Weekday::Sun),
+ (2024, Weekday::Mon),
+ (2025, Weekday::Wed),
+ (2026, Weekday::Thu),
+ ] {
+ for day in &[
+ Weekday::Mon,
+ Weekday::Tue,
+ Weekday::Wed,
+ Weekday::Thu,
+ Weekday::Fri,
+ Weekday::Sat,
+ Weekday::Sun,
+ ] {
+ assert_eq!(
+ NaiveDate::from_ymd_opt(*y, 1, 1).map(|d| d.weeks_from(*day)),
+ Some(if day == starts_on { 1 } else { 0 })
+ );
+
+ // last day must always be in week 52 or 53
+ assert!([52, 53]
+ .contains(&NaiveDate::from_ymd_opt(*y, 12, 31).unwrap().weeks_from(*day)),);
+ }
+ }
+
+ let base = NaiveDate::from_ymd_opt(2019, 1, 1).unwrap();
+
+ // 400 years covers all year types
+ for day in &[
+ Weekday::Mon,
+ Weekday::Tue,
+ Weekday::Wed,
+ Weekday::Thu,
+ Weekday::Fri,
+ Weekday::Sat,
+ Weekday::Sun,
+ ] {
+ // must always be below 54
+ for dplus in 1..(400 * 366) {
+ assert!((base + Days::new(dplus)).weeks_from(*day) < 54)
+ }
+ }
+ }
}
diff --git a/vendor/chrono/src/naive/datetime.rs b/vendor/chrono/src/naive/datetime.rs
deleted file mode 100644
index 92d6c2855..000000000
--- a/vendor/chrono/src/naive/datetime.rs
+++ /dev/null
@@ -1,2507 +0,0 @@
-// This is a part of Chrono.
-// See README.md and LICENSE.txt for details.
-
-//! ISO 8601 date and time without timezone.
-
-#[cfg(any(feature = "alloc", feature = "std", test))]
-use core::borrow::Borrow;
-use core::ops::{Add, AddAssign, Sub, SubAssign};
-use core::{fmt, hash, str};
-use num_traits::ToPrimitive;
-use oldtime::Duration as OldDuration;
-
-use div::div_mod_floor;
-#[cfg(any(feature = "alloc", feature = "std", test))]
-use format::DelayedFormat;
-use format::{parse, ParseError, ParseResult, Parsed, StrftimeItems};
-use format::{Fixed, Item, Numeric, Pad};
-use naive::date::{MAX_DATE, MIN_DATE};
-use naive::time::{MAX_TIME, MIN_TIME};
-use naive::{IsoWeek, NaiveDate, NaiveTime};
-use {Datelike, Timelike, Weekday};
-
-/// The tight upper bound guarantees that a duration with `|Duration| >= 2^MAX_SECS_BITS`
-/// will always overflow the addition with any date and time type.
-///
-/// So why is this needed? `Duration::seconds(rhs)` may overflow, and we don't have
-/// an alternative returning `Option` or `Result`. Thus we need some early bound to avoid
-/// touching that call when we are already sure that it WILL overflow...
-const MAX_SECS_BITS: usize = 44;
-
-/// The minimum possible `NaiveDateTime`.
-pub const MIN_DATETIME: NaiveDateTime = NaiveDateTime { date: MIN_DATE, time: MIN_TIME };
-/// The maximum possible `NaiveDateTime`.
-pub const MAX_DATETIME: NaiveDateTime = NaiveDateTime { date: MAX_DATE, time: MAX_TIME };
-
-/// ISO 8601 combined date and time without timezone.
-///
-/// # Example
-///
-/// `NaiveDateTime` is commonly created from [`NaiveDate`](./struct.NaiveDate.html).
-///
-/// ~~~~
-/// use chrono::{NaiveDate, NaiveDateTime};
-///
-/// let dt: NaiveDateTime = NaiveDate::from_ymd(2016, 7, 8).and_hms(9, 10, 11);
-/// # let _ = dt;
-/// ~~~~
-///
-/// You can use typical [date-like](../trait.Datelike.html) and
-/// [time-like](../trait.Timelike.html) methods,
-/// provided that relevant traits are in the scope.
-///
-/// ~~~~
-/// # use chrono::{NaiveDate, NaiveDateTime};
-/// # let dt: NaiveDateTime = NaiveDate::from_ymd(2016, 7, 8).and_hms(9, 10, 11);
-/// use chrono::{Datelike, Timelike, Weekday};
-///
-/// assert_eq!(dt.weekday(), Weekday::Fri);
-/// assert_eq!(dt.num_seconds_from_midnight(), 33011);
-/// ~~~~
-#[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
-pub struct NaiveDateTime {
- date: NaiveDate,
- time: NaiveTime,
-}
-
-impl NaiveDateTime {
- /// Makes a new `NaiveDateTime` from date and time components.
- /// Equivalent to [`date.and_time(time)`](./struct.NaiveDate.html#method.and_time)
- /// and many other helper constructors on `NaiveDate`.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveTime, NaiveDateTime};
- ///
- /// let d = NaiveDate::from_ymd(2015, 6, 3);
- /// let t = NaiveTime::from_hms_milli(12, 34, 56, 789);
- ///
- /// let dt = NaiveDateTime::new(d, t);
- /// assert_eq!(dt.date(), d);
- /// assert_eq!(dt.time(), t);
- /// ~~~~
- #[inline]
- pub fn new(date: NaiveDate, time: NaiveTime) -> NaiveDateTime {
- NaiveDateTime { date: date, time: time }
- }
-
- /// Makes a new `NaiveDateTime` corresponding to a UTC date and time,
- /// from the number of non-leap seconds
- /// since the midnight UTC on January 1, 1970 (aka "UNIX timestamp")
- /// and the number of nanoseconds since the last whole non-leap second.
- ///
- /// For a non-naive version of this function see
- /// [`TimeZone::timestamp`](../offset/trait.TimeZone.html#method.timestamp).
- ///
- /// The nanosecond part can exceed 1,000,000,000 in order to represent the
- /// [leap second](./struct.NaiveTime.html#leap-second-handling). (The true "UNIX
- /// timestamp" cannot represent a leap second unambiguously.)
- ///
- /// Panics on the out-of-range number of seconds and/or invalid nanosecond.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDateTime, NaiveDate};
- ///
- /// let dt = NaiveDateTime::from_timestamp(0, 42_000_000);
- /// assert_eq!(dt, NaiveDate::from_ymd(1970, 1, 1).and_hms_milli(0, 0, 0, 42));
- ///
- /// let dt = NaiveDateTime::from_timestamp(1_000_000_000, 0);
- /// assert_eq!(dt, NaiveDate::from_ymd(2001, 9, 9).and_hms(1, 46, 40));
- /// ~~~~
- #[inline]
- pub fn from_timestamp(secs: i64, nsecs: u32) -> NaiveDateTime {
- let datetime = NaiveDateTime::from_timestamp_opt(secs, nsecs);
- datetime.expect("invalid or out-of-range datetime")
- }
-
- /// Makes a new `NaiveDateTime` corresponding to a UTC date and time,
- /// from the number of non-leap seconds
- /// since the midnight UTC on January 1, 1970 (aka "UNIX timestamp")
- /// and the number of nanoseconds since the last whole non-leap second.
- ///
- /// The nanosecond part can exceed 1,000,000,000
- /// in order to represent the [leap second](./struct.NaiveTime.html#leap-second-handling).
- /// (The true "UNIX timestamp" cannot represent a leap second unambiguously.)
- ///
- /// Returns `None` on the out-of-range number of seconds and/or invalid nanosecond.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDateTime, NaiveDate};
- /// use std::i64;
- ///
- /// let from_timestamp_opt = NaiveDateTime::from_timestamp_opt;
- ///
- /// assert!(from_timestamp_opt(0, 0).is_some());
- /// assert!(from_timestamp_opt(0, 999_999_999).is_some());
- /// assert!(from_timestamp_opt(0, 1_500_000_000).is_some()); // leap second
- /// assert!(from_timestamp_opt(0, 2_000_000_000).is_none());
- /// assert!(from_timestamp_opt(i64::MAX, 0).is_none());
- /// ~~~~
- #[inline]
- pub fn from_timestamp_opt(secs: i64, nsecs: u32) -> Option<NaiveDateTime> {
- let (days, secs) = div_mod_floor(secs, 86_400);
- let date = days
- .to_i32()
- .and_then(|days| days.checked_add(719_163))
- .and_then(NaiveDate::from_num_days_from_ce_opt);
- let time = NaiveTime::from_num_seconds_from_midnight_opt(secs as u32, nsecs);
- match (date, time) {
- (Some(date), Some(time)) => Some(NaiveDateTime { date: date, time: time }),
- (_, _) => None,
- }
- }
-
- /// Parses a string with the specified format string and returns a new `NaiveDateTime`.
- /// See the [`format::strftime` module](../format/strftime/index.html)
- /// on the supported escape sequences.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDateTime, NaiveDate};
- ///
- /// let parse_from_str = NaiveDateTime::parse_from_str;
- ///
- /// assert_eq!(parse_from_str("2015-09-05 23:56:04", "%Y-%m-%d %H:%M:%S"),
- /// Ok(NaiveDate::from_ymd(2015, 9, 5).and_hms(23, 56, 4)));
- /// assert_eq!(parse_from_str("5sep2015pm012345.6789", "%d%b%Y%p%I%M%S%.f"),
- /// Ok(NaiveDate::from_ymd(2015, 9, 5).and_hms_micro(13, 23, 45, 678_900)));
- /// ~~~~
- ///
- /// Offset is ignored for the purpose of parsing.
- ///
- /// ~~~~
- /// # use chrono::{NaiveDateTime, NaiveDate};
- /// # let parse_from_str = NaiveDateTime::parse_from_str;
- /// assert_eq!(parse_from_str("2014-5-17T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
- /// Ok(NaiveDate::from_ymd(2014, 5, 17).and_hms(12, 34, 56)));
- /// ~~~~
- ///
- /// [Leap seconds](./struct.NaiveTime.html#leap-second-handling) are correctly handled by
- /// treating any time of the form `hh:mm:60` as a leap second.
- /// (This equally applies to the formatting, so the round trip is possible.)
- ///
- /// ~~~~
- /// # use chrono::{NaiveDateTime, NaiveDate};
- /// # let parse_from_str = NaiveDateTime::parse_from_str;
- /// assert_eq!(parse_from_str("2015-07-01 08:59:60.123", "%Y-%m-%d %H:%M:%S%.f"),
- /// Ok(NaiveDate::from_ymd(2015, 7, 1).and_hms_milli(8, 59, 59, 1_123)));
- /// ~~~~
- ///
- /// Missing seconds are assumed to be zero,
- /// but out-of-bound times or insufficient fields are errors otherwise.
- ///
- /// ~~~~
- /// # use chrono::{NaiveDateTime, NaiveDate};
- /// # let parse_from_str = NaiveDateTime::parse_from_str;
- /// assert_eq!(parse_from_str("94/9/4 7:15", "%y/%m/%d %H:%M"),
- /// Ok(NaiveDate::from_ymd(1994, 9, 4).and_hms(7, 15, 0)));
- ///
- /// assert!(parse_from_str("04m33s", "%Mm%Ss").is_err());
- /// assert!(parse_from_str("94/9/4 12", "%y/%m/%d %H").is_err());
- /// assert!(parse_from_str("94/9/4 17:60", "%y/%m/%d %H:%M").is_err());
- /// assert!(parse_from_str("94/9/4 24:00:00", "%y/%m/%d %H:%M:%S").is_err());
- /// ~~~~
- ///
- /// All parsed fields should be consistent to each other, otherwise it's an error.
- ///
- /// ~~~~
- /// # use chrono::NaiveDateTime;
- /// # let parse_from_str = NaiveDateTime::parse_from_str;
- /// let fmt = "%Y-%m-%d %H:%M:%S = UNIX timestamp %s";
- /// assert!(parse_from_str("2001-09-09 01:46:39 = UNIX timestamp 999999999", fmt).is_ok());
- /// assert!(parse_from_str("1970-01-01 00:00:00 = UNIX timestamp 1", fmt).is_err());
- /// ~~~~
- pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveDateTime> {
- let mut parsed = Parsed::new();
- parse(&mut parsed, s, StrftimeItems::new(fmt))?;
- parsed.to_naive_datetime_with_offset(0) // no offset adjustment
- }
-
- /// Retrieves a date component.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::NaiveDate;
- ///
- /// let dt = NaiveDate::from_ymd(2016, 7, 8).and_hms(9, 10, 11);
- /// assert_eq!(dt.date(), NaiveDate::from_ymd(2016, 7, 8));
- /// ~~~~
- #[inline]
- pub fn date(&self) -> NaiveDate {
- self.date
- }
-
- /// Retrieves a time component.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveTime};
- ///
- /// let dt = NaiveDate::from_ymd(2016, 7, 8).and_hms(9, 10, 11);
- /// assert_eq!(dt.time(), NaiveTime::from_hms(9, 10, 11));
- /// ~~~~
- #[inline]
- pub fn time(&self) -> NaiveTime {
- self.time
- }
-
- /// Returns the number of non-leap seconds since the midnight on January 1, 1970.
- ///
- /// Note that this does *not* account for the timezone!
- /// The true "UNIX timestamp" would count seconds since the midnight *UTC* on the epoch.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::NaiveDate;
- ///
- /// let dt = NaiveDate::from_ymd(1970, 1, 1).and_hms_milli(0, 0, 1, 980);
- /// assert_eq!(dt.timestamp(), 1);
- ///
- /// let dt = NaiveDate::from_ymd(2001, 9, 9).and_hms(1, 46, 40);
- /// assert_eq!(dt.timestamp(), 1_000_000_000);
- ///
- /// let dt = NaiveDate::from_ymd(1969, 12, 31).and_hms(23, 59, 59);
- /// assert_eq!(dt.timestamp(), -1);
- ///
- /// let dt = NaiveDate::from_ymd(-1, 1, 1).and_hms(0, 0, 0);
- /// assert_eq!(dt.timestamp(), -62198755200);
- /// ~~~~
- #[inline]
- pub fn timestamp(&self) -> i64 {
- const UNIX_EPOCH_DAY: i64 = 719_163;
- let gregorian_day = i64::from(self.date.num_days_from_ce());
- let seconds_from_midnight = i64::from(self.time.num_seconds_from_midnight());
- (gregorian_day - UNIX_EPOCH_DAY) * 86_400 + seconds_from_midnight
- }
-
- /// Returns the number of non-leap *milliseconds* since midnight on January 1, 1970.
- ///
- /// Note that this does *not* account for the timezone!
- /// The true "UNIX timestamp" would count seconds since the midnight *UTC* on the epoch.
- ///
- /// Note also that this does reduce the number of years that can be
- /// represented from ~584 Billion to ~584 Million. (If this is a problem,
- /// please file an issue to let me know what domain needs millisecond
- /// precision over billions of years, I'm curious.)
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::NaiveDate;
- ///
- /// let dt = NaiveDate::from_ymd(1970, 1, 1).and_hms_milli(0, 0, 1, 444);
- /// assert_eq!(dt.timestamp_millis(), 1_444);
- ///
- /// let dt = NaiveDate::from_ymd(2001, 9, 9).and_hms_milli(1, 46, 40, 555);
- /// assert_eq!(dt.timestamp_millis(), 1_000_000_000_555);
- ///
- /// let dt = NaiveDate::from_ymd(1969, 12, 31).and_hms_milli(23, 59, 59, 100);
- /// assert_eq!(dt.timestamp_millis(), -900);
- /// ~~~~
- #[inline]
- pub fn timestamp_millis(&self) -> i64 {
- let as_ms = self.timestamp() * 1000;
- as_ms + i64::from(self.timestamp_subsec_millis())
- }
-
- /// Returns the number of non-leap *nanoseconds* since midnight on January 1, 1970.
- ///
- /// Note that this does *not* account for the timezone!
- /// The true "UNIX timestamp" would count seconds since the midnight *UTC* on the epoch.
- ///
- /// # Panics
- ///
- /// Note also that this does reduce the number of years that can be
- /// represented from ~584 Billion to ~584 years. The dates that can be
- /// represented as nanoseconds are between 1677-09-21T00:12:44.0 and
- /// 2262-04-11T23:47:16.854775804.
- ///
- /// (If this is a problem, please file an issue to let me know what domain
- /// needs nanosecond precision over millennia, I'm curious.)
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime};
- ///
- /// let dt = NaiveDate::from_ymd(1970, 1, 1).and_hms_nano(0, 0, 1, 444);
- /// assert_eq!(dt.timestamp_nanos(), 1_000_000_444);
- ///
- /// let dt = NaiveDate::from_ymd(2001, 9, 9).and_hms_nano(1, 46, 40, 555);
- ///
- /// const A_BILLION: i64 = 1_000_000_000;
- /// let nanos = dt.timestamp_nanos();
- /// assert_eq!(nanos, 1_000_000_000_000_000_555);
- /// assert_eq!(
- /// dt,
- /// NaiveDateTime::from_timestamp(nanos / A_BILLION, (nanos % A_BILLION) as u32)
- /// );
- /// ~~~~
- #[inline]
- pub fn timestamp_nanos(&self) -> i64 {
- let as_ns = self.timestamp() * 1_000_000_000;
- as_ns + i64::from(self.timestamp_subsec_nanos())
- }
-
- /// Returns the number of milliseconds since the last whole non-leap second.
- ///
- /// The return value ranges from 0 to 999,
- /// or for [leap seconds](./struct.NaiveTime.html#leap-second-handling), to 1,999.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::NaiveDate;
- ///
- /// let dt = NaiveDate::from_ymd(2016, 7, 8).and_hms_nano(9, 10, 11, 123_456_789);
- /// assert_eq!(dt.timestamp_subsec_millis(), 123);
- ///
- /// let dt = NaiveDate::from_ymd(2015, 7, 1).and_hms_nano(8, 59, 59, 1_234_567_890);
- /// assert_eq!(dt.timestamp_subsec_millis(), 1_234);
- /// ~~~~
- #[inline]
- pub fn timestamp_subsec_millis(&self) -> u32 {
- self.timestamp_subsec_nanos() / 1_000_000
- }
-
- /// Returns the number of microseconds since the last whole non-leap second.
- ///
- /// The return value ranges from 0 to 999,999,
- /// or for [leap seconds](./struct.NaiveTime.html#leap-second-handling), to 1,999,999.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::NaiveDate;
- ///
- /// let dt = NaiveDate::from_ymd(2016, 7, 8).and_hms_nano(9, 10, 11, 123_456_789);
- /// assert_eq!(dt.timestamp_subsec_micros(), 123_456);
- ///
- /// let dt = NaiveDate::from_ymd(2015, 7, 1).and_hms_nano(8, 59, 59, 1_234_567_890);
- /// assert_eq!(dt.timestamp_subsec_micros(), 1_234_567);
- /// ~~~~
- #[inline]
- pub fn timestamp_subsec_micros(&self) -> u32 {
- self.timestamp_subsec_nanos() / 1_000
- }
-
- /// Returns the number of nanoseconds since the last whole non-leap second.
- ///
- /// The return value ranges from 0 to 999,999,999,
- /// or for [leap seconds](./struct.NaiveTime.html#leap-second-handling), to 1,999,999,999.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::NaiveDate;
- ///
- /// let dt = NaiveDate::from_ymd(2016, 7, 8).and_hms_nano(9, 10, 11, 123_456_789);
- /// assert_eq!(dt.timestamp_subsec_nanos(), 123_456_789);
- ///
- /// let dt = NaiveDate::from_ymd(2015, 7, 1).and_hms_nano(8, 59, 59, 1_234_567_890);
- /// assert_eq!(dt.timestamp_subsec_nanos(), 1_234_567_890);
- /// ~~~~
- #[inline]
- pub fn timestamp_subsec_nanos(&self) -> u32 {
- self.time.nanosecond()
- }
-
- /// Adds given `Duration` to the current date and time.
- ///
- /// As a part of Chrono's [leap second handling](./struct.NaiveTime.html#leap-second-handling),
- /// the addition assumes that **there is no leap second ever**,
- /// except when the `NaiveDateTime` itself represents a leap second
- /// in which case the assumption becomes that **there is exactly a single leap second ever**.
- ///
- /// Returns `None` when it will result in overflow.
- ///
- /// # Example
- ///
- /// ~~~~
- /// # extern crate chrono; fn main() {
- /// use chrono::{Duration, NaiveDate};
- ///
- /// let from_ymd = NaiveDate::from_ymd;
- ///
- /// let d = from_ymd(2016, 7, 8);
- /// let hms = |h, m, s| d.and_hms(h, m, s);
- /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::zero()),
- /// Some(hms(3, 5, 7)));
- /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::seconds(1)),
- /// Some(hms(3, 5, 8)));
- /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::seconds(-1)),
- /// Some(hms(3, 5, 6)));
- /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::seconds(3600 + 60)),
- /// Some(hms(4, 6, 7)));
- /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::seconds(86_400)),
- /// Some(from_ymd(2016, 7, 9).and_hms(3, 5, 7)));
- ///
- /// let hmsm = |h, m, s, milli| d.and_hms_milli(h, m, s, milli);
- /// assert_eq!(hmsm(3, 5, 7, 980).checked_add_signed(Duration::milliseconds(450)),
- /// Some(hmsm(3, 5, 8, 430)));
- /// # }
- /// ~~~~
- ///
- /// Overflow returns `None`.
- ///
- /// ~~~~
- /// # extern crate chrono; fn main() {
- /// # use chrono::{Duration, NaiveDate};
- /// # let hms = |h, m, s| NaiveDate::from_ymd(2016, 7, 8).and_hms(h, m, s);
- /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::days(1_000_000_000)), None);
- /// # }
- /// ~~~~
- ///
- /// Leap seconds are handled,
- /// but the addition assumes that it is the only leap second happened.
- ///
- /// ~~~~
- /// # extern crate chrono; fn main() {
- /// # use chrono::{Duration, NaiveDate};
- /// # let from_ymd = NaiveDate::from_ymd;
- /// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli(h, m, s, milli);
- /// let leap = hmsm(3, 5, 59, 1_300);
- /// assert_eq!(leap.checked_add_signed(Duration::zero()),
- /// Some(hmsm(3, 5, 59, 1_300)));
- /// assert_eq!(leap.checked_add_signed(Duration::milliseconds(-500)),
- /// Some(hmsm(3, 5, 59, 800)));
- /// assert_eq!(leap.checked_add_signed(Duration::milliseconds(500)),
- /// Some(hmsm(3, 5, 59, 1_800)));
- /// assert_eq!(leap.checked_add_signed(Duration::milliseconds(800)),
- /// Some(hmsm(3, 6, 0, 100)));
- /// assert_eq!(leap.checked_add_signed(Duration::seconds(10)),
- /// Some(hmsm(3, 6, 9, 300)));
- /// assert_eq!(leap.checked_add_signed(Duration::seconds(-10)),
- /// Some(hmsm(3, 5, 50, 300)));
- /// assert_eq!(leap.checked_add_signed(Duration::days(1)),
- /// Some(from_ymd(2016, 7, 9).and_hms_milli(3, 5, 59, 300)));
- /// # }
- /// ~~~~
- pub fn checked_add_signed(self, rhs: OldDuration) -> Option<NaiveDateTime> {
- let (time, rhs) = self.time.overflowing_add_signed(rhs);
-
- // early checking to avoid overflow in OldDuration::seconds
- if rhs <= (-1 << MAX_SECS_BITS) || rhs >= (1 << MAX_SECS_BITS) {
- return None;
- }
-
- let date = try_opt!(self.date.checked_add_signed(OldDuration::seconds(rhs)));
- Some(NaiveDateTime { date: date, time: time })
- }
-
- /// Subtracts given `Duration` from the current date and time.
- ///
- /// As a part of Chrono's [leap second handling](./struct.NaiveTime.html#leap-second-handling),
- /// the subtraction assumes that **there is no leap second ever**,
- /// except when the `NaiveDateTime` itself represents a leap second
- /// in which case the assumption becomes that **there is exactly a single leap second ever**.
- ///
- /// Returns `None` when it will result in overflow.
- ///
- /// # Example
- ///
- /// ~~~~
- /// # extern crate chrono; fn main() {
- /// use chrono::{Duration, NaiveDate};
- ///
- /// let from_ymd = NaiveDate::from_ymd;
- ///
- /// let d = from_ymd(2016, 7, 8);
- /// let hms = |h, m, s| d.and_hms(h, m, s);
- /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::zero()),
- /// Some(hms(3, 5, 7)));
- /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::seconds(1)),
- /// Some(hms(3, 5, 6)));
- /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::seconds(-1)),
- /// Some(hms(3, 5, 8)));
- /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::seconds(3600 + 60)),
- /// Some(hms(2, 4, 7)));
- /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::seconds(86_400)),
- /// Some(from_ymd(2016, 7, 7).and_hms(3, 5, 7)));
- ///
- /// let hmsm = |h, m, s, milli| d.and_hms_milli(h, m, s, milli);
- /// assert_eq!(hmsm(3, 5, 7, 450).checked_sub_signed(Duration::milliseconds(670)),
- /// Some(hmsm(3, 5, 6, 780)));
- /// # }
- /// ~~~~
- ///
- /// Overflow returns `None`.
- ///
- /// ~~~~
- /// # extern crate chrono; fn main() {
- /// # use chrono::{Duration, NaiveDate};
- /// # let hms = |h, m, s| NaiveDate::from_ymd(2016, 7, 8).and_hms(h, m, s);
- /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::days(1_000_000_000)), None);
- /// # }
- /// ~~~~
- ///
- /// Leap seconds are handled,
- /// but the subtraction assumes that it is the only leap second happened.
- ///
- /// ~~~~
- /// # extern crate chrono; fn main() {
- /// # use chrono::{Duration, NaiveDate};
- /// # let from_ymd = NaiveDate::from_ymd;
- /// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli(h, m, s, milli);
- /// let leap = hmsm(3, 5, 59, 1_300);
- /// assert_eq!(leap.checked_sub_signed(Duration::zero()),
- /// Some(hmsm(3, 5, 59, 1_300)));
- /// assert_eq!(leap.checked_sub_signed(Duration::milliseconds(200)),
- /// Some(hmsm(3, 5, 59, 1_100)));
- /// assert_eq!(leap.checked_sub_signed(Duration::milliseconds(500)),
- /// Some(hmsm(3, 5, 59, 800)));
- /// assert_eq!(leap.checked_sub_signed(Duration::seconds(60)),
- /// Some(hmsm(3, 5, 0, 300)));
- /// assert_eq!(leap.checked_sub_signed(Duration::days(1)),
- /// Some(from_ymd(2016, 7, 7).and_hms_milli(3, 6, 0, 300)));
- /// # }
- /// ~~~~
- pub fn checked_sub_signed(self, rhs: OldDuration) -> Option<NaiveDateTime> {
- let (time, rhs) = self.time.overflowing_sub_signed(rhs);
-
- // early checking to avoid overflow in OldDuration::seconds
- if rhs <= (-1 << MAX_SECS_BITS) || rhs >= (1 << MAX_SECS_BITS) {
- return None;
- }
-
- let date = try_opt!(self.date.checked_sub_signed(OldDuration::seconds(rhs)));
- Some(NaiveDateTime { date: date, time: time })
- }
-
- /// Subtracts another `NaiveDateTime` from the current date and time.
- /// This does not overflow or underflow at all.
- ///
- /// As a part of Chrono's [leap second handling](./struct.NaiveTime.html#leap-second-handling),
- /// the subtraction assumes that **there is no leap second ever**,
- /// except when any of the `NaiveDateTime`s themselves represents a leap second
- /// in which case the assumption becomes that
- /// **there are exactly one (or two) leap second(s) ever**.
- ///
- /// # Example
- ///
- /// ~~~~
- /// # extern crate chrono; fn main() {
- /// use chrono::{Duration, NaiveDate};
- ///
- /// let from_ymd = NaiveDate::from_ymd;
- ///
- /// let d = from_ymd(2016, 7, 8);
- /// assert_eq!(d.and_hms(3, 5, 7).signed_duration_since(d.and_hms(2, 4, 6)),
- /// Duration::seconds(3600 + 60 + 1));
- ///
- /// // July 8 is 190th day in the year 2016
- /// let d0 = from_ymd(2016, 1, 1);
- /// assert_eq!(d.and_hms_milli(0, 7, 6, 500).signed_duration_since(d0.and_hms(0, 0, 0)),
- /// Duration::seconds(189 * 86_400 + 7 * 60 + 6) + Duration::milliseconds(500));
- /// # }
- /// ~~~~
- ///
- /// Leap seconds are handled, but the subtraction assumes that
- /// there were no other leap seconds happened.
- ///
- /// ~~~~
- /// # extern crate chrono; fn main() {
- /// # use chrono::{Duration, NaiveDate};
- /// # let from_ymd = NaiveDate::from_ymd;
- /// let leap = from_ymd(2015, 6, 30).and_hms_milli(23, 59, 59, 1_500);
- /// assert_eq!(leap.signed_duration_since(from_ymd(2015, 6, 30).and_hms(23, 0, 0)),
- /// Duration::seconds(3600) + Duration::milliseconds(500));
- /// assert_eq!(from_ymd(2015, 7, 1).and_hms(1, 0, 0).signed_duration_since(leap),
- /// Duration::seconds(3600) - Duration::milliseconds(500));
- /// # }
- /// ~~~~
- pub fn signed_duration_since(self, rhs: NaiveDateTime) -> OldDuration {
- self.date.signed_duration_since(rhs.date) + self.time.signed_duration_since(rhs.time)
- }
-
- /// Formats the combined date and time with the specified formatting items.
- /// Otherwise it is the same as the ordinary [`format`](#method.format) method.
- ///
- /// The `Iterator` of items should be `Clone`able,
- /// since the resulting `DelayedFormat` value may be formatted multiple times.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::NaiveDate;
- /// use chrono::format::strftime::StrftimeItems;
- ///
- /// let fmt = StrftimeItems::new("%Y-%m-%d %H:%M:%S");
- /// let dt = NaiveDate::from_ymd(2015, 9, 5).and_hms(23, 56, 4);
- /// assert_eq!(dt.format_with_items(fmt.clone()).to_string(), "2015-09-05 23:56:04");
- /// assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2015-09-05 23:56:04");
- /// ~~~~
- ///
- /// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
- ///
- /// ~~~~
- /// # use chrono::NaiveDate;
- /// # use chrono::format::strftime::StrftimeItems;
- /// # let fmt = StrftimeItems::new("%Y-%m-%d %H:%M:%S").clone();
- /// # let dt = NaiveDate::from_ymd(2015, 9, 5).and_hms(23, 56, 4);
- /// assert_eq!(format!("{}", dt.format_with_items(fmt)), "2015-09-05 23:56:04");
- /// ~~~~
- #[cfg(any(feature = "alloc", feature = "std", test))]
- #[inline]
- pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat<I>
- where
- I: Iterator<Item = B> + Clone,
- B: Borrow<Item<'a>>,
- {
- DelayedFormat::new(Some(self.date), Some(self.time), items)
- }
-
- /// Formats the combined date and time with the specified format string.
- /// See the [`format::strftime` module](../format/strftime/index.html)
- /// on the supported escape sequences.
- ///
- /// This returns a `DelayedFormat`,
- /// which gets converted to a string only when actual formatting happens.
- /// You may use the `to_string` method to get a `String`,
- /// or just feed it into `print!` and other formatting macros.
- /// (In this way it avoids the redundant memory allocation.)
- ///
- /// A wrong format string does *not* issue an error immediately.
- /// Rather, converting or formatting the `DelayedFormat` fails.
- /// You are recommended to immediately use `DelayedFormat` for this reason.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::NaiveDate;
- ///
- /// let dt = NaiveDate::from_ymd(2015, 9, 5).and_hms(23, 56, 4);
- /// assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2015-09-05 23:56:04");
- /// assert_eq!(dt.format("around %l %p on %b %-d").to_string(), "around 11 PM on Sep 5");
- /// ~~~~
- ///
- /// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
- ///
- /// ~~~~
- /// # use chrono::NaiveDate;
- /// # let dt = NaiveDate::from_ymd(2015, 9, 5).and_hms(23, 56, 4);
- /// assert_eq!(format!("{}", dt.format("%Y-%m-%d %H:%M:%S")), "2015-09-05 23:56:04");
- /// assert_eq!(format!("{}", dt.format("around %l %p on %b %-d")), "around 11 PM on Sep 5");
- /// ~~~~
- #[cfg(any(feature = "alloc", feature = "std", test))]
- #[inline]
- pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>> {
- self.format_with_items(StrftimeItems::new(fmt))
- }
-}
-
-impl Datelike for NaiveDateTime {
- /// Returns the year number in the [calendar date](./index.html#calendar-date).
- ///
- /// See also the [`NaiveDate::year`](./struct.NaiveDate.html#method.year) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 25).and_hms(12, 34, 56);
- /// assert_eq!(dt.year(), 2015);
- /// ~~~~
- #[inline]
- fn year(&self) -> i32 {
- self.date.year()
- }
-
- /// Returns the month number starting from 1.
- ///
- /// The return value ranges from 1 to 12.
- ///
- /// See also the [`NaiveDate::month`](./struct.NaiveDate.html#method.month) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 25).and_hms(12, 34, 56);
- /// assert_eq!(dt.month(), 9);
- /// ~~~~
- #[inline]
- fn month(&self) -> u32 {
- self.date.month()
- }
-
- /// Returns the month number starting from 0.
- ///
- /// The return value ranges from 0 to 11.
- ///
- /// See also the [`NaiveDate::month0`](./struct.NaiveDate.html#method.month0) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 25).and_hms(12, 34, 56);
- /// assert_eq!(dt.month0(), 8);
- /// ~~~~
- #[inline]
- fn month0(&self) -> u32 {
- self.date.month0()
- }
-
- /// Returns the day of month starting from 1.
- ///
- /// The return value ranges from 1 to 31. (The last day of month differs by months.)
- ///
- /// See also the [`NaiveDate::day`](./struct.NaiveDate.html#method.day) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 25).and_hms(12, 34, 56);
- /// assert_eq!(dt.day(), 25);
- /// ~~~~
- #[inline]
- fn day(&self) -> u32 {
- self.date.day()
- }
-
- /// Returns the day of month starting from 0.
- ///
- /// The return value ranges from 0 to 30. (The last day of month differs by months.)
- ///
- /// See also the [`NaiveDate::day0`](./struct.NaiveDate.html#method.day0) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 25).and_hms(12, 34, 56);
- /// assert_eq!(dt.day0(), 24);
- /// ~~~~
- #[inline]
- fn day0(&self) -> u32 {
- self.date.day0()
- }
-
- /// Returns the day of year starting from 1.
- ///
- /// The return value ranges from 1 to 366. (The last day of year differs by years.)
- ///
- /// See also the [`NaiveDate::ordinal`](./struct.NaiveDate.html#method.ordinal) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 25).and_hms(12, 34, 56);
- /// assert_eq!(dt.ordinal(), 268);
- /// ~~~~
- #[inline]
- fn ordinal(&self) -> u32 {
- self.date.ordinal()
- }
-
- /// Returns the day of year starting from 0.
- ///
- /// The return value ranges from 0 to 365. (The last day of year differs by years.)
- ///
- /// See also the [`NaiveDate::ordinal0`](./struct.NaiveDate.html#method.ordinal0) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 25).and_hms(12, 34, 56);
- /// assert_eq!(dt.ordinal0(), 267);
- /// ~~~~
- #[inline]
- fn ordinal0(&self) -> u32 {
- self.date.ordinal0()
- }
-
- /// Returns the day of week.
- ///
- /// See also the [`NaiveDate::weekday`](./struct.NaiveDate.html#method.weekday) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Datelike, Weekday};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 25).and_hms(12, 34, 56);
- /// assert_eq!(dt.weekday(), Weekday::Fri);
- /// ~~~~
- #[inline]
- fn weekday(&self) -> Weekday {
- self.date.weekday()
- }
-
- #[inline]
- fn iso_week(&self) -> IsoWeek {
- self.date.iso_week()
- }
-
- /// Makes a new `NaiveDateTime` with the year number changed.
- ///
- /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
- ///
- /// See also the
- /// [`NaiveDate::with_year`](./struct.NaiveDate.html#method.with_year) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 25).and_hms(12, 34, 56);
- /// assert_eq!(dt.with_year(2016), Some(NaiveDate::from_ymd(2016, 9, 25).and_hms(12, 34, 56)));
- /// assert_eq!(dt.with_year(-308), Some(NaiveDate::from_ymd(-308, 9, 25).and_hms(12, 34, 56)));
- /// ~~~~
- #[inline]
- fn with_year(&self, year: i32) -> Option<NaiveDateTime> {
- self.date.with_year(year).map(|d| NaiveDateTime { date: d, ..*self })
- }
-
- /// Makes a new `NaiveDateTime` with the month number (starting from 1) changed.
- ///
- /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
- ///
- /// See also the
- /// [`NaiveDate::with_month`](./struct.NaiveDate.html#method.with_month) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 30).and_hms(12, 34, 56);
- /// assert_eq!(dt.with_month(10), Some(NaiveDate::from_ymd(2015, 10, 30).and_hms(12, 34, 56)));
- /// assert_eq!(dt.with_month(13), None); // no month 13
- /// assert_eq!(dt.with_month(2), None); // no February 30
- /// ~~~~
- #[inline]
- fn with_month(&self, month: u32) -> Option<NaiveDateTime> {
- self.date.with_month(month).map(|d| NaiveDateTime { date: d, ..*self })
- }
-
- /// Makes a new `NaiveDateTime` with the month number (starting from 0) changed.
- ///
- /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
- ///
- /// See also the
- /// [`NaiveDate::with_month0`](./struct.NaiveDate.html#method.with_month0) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 30).and_hms(12, 34, 56);
- /// assert_eq!(dt.with_month0(9), Some(NaiveDate::from_ymd(2015, 10, 30).and_hms(12, 34, 56)));
- /// assert_eq!(dt.with_month0(12), None); // no month 13
- /// assert_eq!(dt.with_month0(1), None); // no February 30
- /// ~~~~
- #[inline]
- fn with_month0(&self, month0: u32) -> Option<NaiveDateTime> {
- self.date.with_month0(month0).map(|d| NaiveDateTime { date: d, ..*self })
- }
-
- /// Makes a new `NaiveDateTime` with the day of month (starting from 1) changed.
- ///
- /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
- ///
- /// See also the
- /// [`NaiveDate::with_day`](./struct.NaiveDate.html#method.with_day) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms(12, 34, 56);
- /// assert_eq!(dt.with_day(30), Some(NaiveDate::from_ymd(2015, 9, 30).and_hms(12, 34, 56)));
- /// assert_eq!(dt.with_day(31), None); // no September 31
- /// ~~~~
- #[inline]
- fn with_day(&self, day: u32) -> Option<NaiveDateTime> {
- self.date.with_day(day).map(|d| NaiveDateTime { date: d, ..*self })
- }
-
- /// Makes a new `NaiveDateTime` with the day of month (starting from 0) changed.
- ///
- /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
- ///
- /// See also the
- /// [`NaiveDate::with_day0`](./struct.NaiveDate.html#method.with_day0) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms(12, 34, 56);
- /// assert_eq!(dt.with_day0(29), Some(NaiveDate::from_ymd(2015, 9, 30).and_hms(12, 34, 56)));
- /// assert_eq!(dt.with_day0(30), None); // no September 31
- /// ~~~~
- #[inline]
- fn with_day0(&self, day0: u32) -> Option<NaiveDateTime> {
- self.date.with_day0(day0).map(|d| NaiveDateTime { date: d, ..*self })
- }
-
- /// Makes a new `NaiveDateTime` with the day of year (starting from 1) changed.
- ///
- /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
- ///
- /// See also the
- /// [`NaiveDate::with_ordinal`](./struct.NaiveDate.html#method.with_ordinal) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms(12, 34, 56);
- /// assert_eq!(dt.with_ordinal(60),
- /// Some(NaiveDate::from_ymd(2015, 3, 1).and_hms(12, 34, 56)));
- /// assert_eq!(dt.with_ordinal(366), None); // 2015 had only 365 days
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2016, 9, 8).and_hms(12, 34, 56);
- /// assert_eq!(dt.with_ordinal(60),
- /// Some(NaiveDate::from_ymd(2016, 2, 29).and_hms(12, 34, 56)));
- /// assert_eq!(dt.with_ordinal(366),
- /// Some(NaiveDate::from_ymd(2016, 12, 31).and_hms(12, 34, 56)));
- /// ~~~~
- #[inline]
- fn with_ordinal(&self, ordinal: u32) -> Option<NaiveDateTime> {
- self.date.with_ordinal(ordinal).map(|d| NaiveDateTime { date: d, ..*self })
- }
-
- /// Makes a new `NaiveDateTime` with the day of year (starting from 0) changed.
- ///
- /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
- ///
- /// See also the
- /// [`NaiveDate::with_ordinal0`](./struct.NaiveDate.html#method.with_ordinal0) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms(12, 34, 56);
- /// assert_eq!(dt.with_ordinal0(59),
- /// Some(NaiveDate::from_ymd(2015, 3, 1).and_hms(12, 34, 56)));
- /// assert_eq!(dt.with_ordinal0(365), None); // 2015 had only 365 days
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2016, 9, 8).and_hms(12, 34, 56);
- /// assert_eq!(dt.with_ordinal0(59),
- /// Some(NaiveDate::from_ymd(2016, 2, 29).and_hms(12, 34, 56)));
- /// assert_eq!(dt.with_ordinal0(365),
- /// Some(NaiveDate::from_ymd(2016, 12, 31).and_hms(12, 34, 56)));
- /// ~~~~
- #[inline]
- fn with_ordinal0(&self, ordinal0: u32) -> Option<NaiveDateTime> {
- self.date.with_ordinal0(ordinal0).map(|d| NaiveDateTime { date: d, ..*self })
- }
-}
-
-impl Timelike for NaiveDateTime {
- /// Returns the hour number from 0 to 23.
- ///
- /// See also the [`NaiveTime::hour`](./struct.NaiveTime.html#method.hour) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(12, 34, 56, 789);
- /// assert_eq!(dt.hour(), 12);
- /// ~~~~
- #[inline]
- fn hour(&self) -> u32 {
- self.time.hour()
- }
-
- /// Returns the minute number from 0 to 59.
- ///
- /// See also the [`NaiveTime::minute`](./struct.NaiveTime.html#method.minute) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(12, 34, 56, 789);
- /// assert_eq!(dt.minute(), 34);
- /// ~~~~
- #[inline]
- fn minute(&self) -> u32 {
- self.time.minute()
- }
-
- /// Returns the second number from 0 to 59.
- ///
- /// See also the [`NaiveTime::second`](./struct.NaiveTime.html#method.second) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(12, 34, 56, 789);
- /// assert_eq!(dt.second(), 56);
- /// ~~~~
- #[inline]
- fn second(&self) -> u32 {
- self.time.second()
- }
-
- /// Returns the number of nanoseconds since the whole non-leap second.
- /// The range from 1,000,000,000 to 1,999,999,999 represents
- /// the [leap second](./struct.NaiveTime.html#leap-second-handling).
- ///
- /// See also the
- /// [`NaiveTime::nanosecond`](./struct.NaiveTime.html#method.nanosecond) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(12, 34, 56, 789);
- /// assert_eq!(dt.nanosecond(), 789_000_000);
- /// ~~~~
- #[inline]
- fn nanosecond(&self) -> u32 {
- self.time.nanosecond()
- }
-
- /// Makes a new `NaiveDateTime` with the hour number changed.
- ///
- /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
- ///
- /// See also the
- /// [`NaiveTime::with_hour`](./struct.NaiveTime.html#method.with_hour) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(12, 34, 56, 789);
- /// assert_eq!(dt.with_hour(7),
- /// Some(NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(7, 34, 56, 789)));
- /// assert_eq!(dt.with_hour(24), None);
- /// ~~~~
- #[inline]
- fn with_hour(&self, hour: u32) -> Option<NaiveDateTime> {
- self.time.with_hour(hour).map(|t| NaiveDateTime { time: t, ..*self })
- }
-
- /// Makes a new `NaiveDateTime` with the minute number changed.
- ///
- /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
- ///
- /// See also the
- /// [`NaiveTime::with_minute`](./struct.NaiveTime.html#method.with_minute) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(12, 34, 56, 789);
- /// assert_eq!(dt.with_minute(45),
- /// Some(NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(12, 45, 56, 789)));
- /// assert_eq!(dt.with_minute(60), None);
- /// ~~~~
- #[inline]
- fn with_minute(&self, min: u32) -> Option<NaiveDateTime> {
- self.time.with_minute(min).map(|t| NaiveDateTime { time: t, ..*self })
- }
-
- /// Makes a new `NaiveDateTime` with the second number changed.
- ///
- /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
- /// As with the [`second`](#method.second) method,
- /// the input range is restricted to 0 through 59.
- ///
- /// See also the
- /// [`NaiveTime::with_second`](./struct.NaiveTime.html#method.with_second) method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(12, 34, 56, 789);
- /// assert_eq!(dt.with_second(17),
- /// Some(NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(12, 34, 17, 789)));
- /// assert_eq!(dt.with_second(60), None);
- /// ~~~~
- #[inline]
- fn with_second(&self, sec: u32) -> Option<NaiveDateTime> {
- self.time.with_second(sec).map(|t| NaiveDateTime { time: t, ..*self })
- }
-
- /// Makes a new `NaiveDateTime` with nanoseconds since the whole non-leap second changed.
- ///
- /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
- /// As with the [`nanosecond`](#method.nanosecond) method,
- /// the input range can exceed 1,000,000,000 for leap seconds.
- ///
- /// See also the
- /// [`NaiveTime::with_nanosecond`](./struct.NaiveTime.html#method.with_nanosecond)
- /// method.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
- ///
- /// let dt: NaiveDateTime = NaiveDate::from_ymd(2015, 9, 8).and_hms_milli(12, 34, 56, 789);
- /// assert_eq!(dt.with_nanosecond(333_333_333),
- /// Some(NaiveDate::from_ymd(2015, 9, 8).and_hms_nano(12, 34, 56, 333_333_333)));
- /// assert_eq!(dt.with_nanosecond(1_333_333_333), // leap second
- /// Some(NaiveDate::from_ymd(2015, 9, 8).and_hms_nano(12, 34, 56, 1_333_333_333)));
- /// assert_eq!(dt.with_nanosecond(2_000_000_000), None);
- /// ~~~~
- #[inline]
- fn with_nanosecond(&self, nano: u32) -> Option<NaiveDateTime> {
- self.time.with_nanosecond(nano).map(|t| NaiveDateTime { time: t, ..*self })
- }
-}
-
-/// `NaiveDateTime` can be used as a key to the hash maps (in principle).
-///
-/// Practically this also takes account of fractional seconds, so it is not recommended.
-/// (For the obvious reason this also distinguishes leap seconds from non-leap seconds.)
-impl hash::Hash for NaiveDateTime {
- fn hash<H: hash::Hasher>(&self, state: &mut H) {
- self.date.hash(state);
- self.time.hash(state);
- }
-}
-
-/// An addition of `Duration` to `NaiveDateTime` yields another `NaiveDateTime`.
-///
-/// As a part of Chrono's [leap second handling](./struct.NaiveTime.html#leap-second-handling),
-/// the addition assumes that **there is no leap second ever**,
-/// except when the `NaiveDateTime` itself represents a leap second
-/// in which case the assumption becomes that **there is exactly a single leap second ever**.
-///
-/// Panics on underflow or overflow.
-/// Use [`NaiveDateTime::checked_add_signed`](#method.checked_add_signed) to detect that.
-///
-/// # Example
-///
-/// ~~~~
-/// # extern crate chrono; fn main() {
-/// use chrono::{Duration, NaiveDate};
-///
-/// let from_ymd = NaiveDate::from_ymd;
-///
-/// let d = from_ymd(2016, 7, 8);
-/// let hms = |h, m, s| d.and_hms(h, m, s);
-/// assert_eq!(hms(3, 5, 7) + Duration::zero(), hms(3, 5, 7));
-/// assert_eq!(hms(3, 5, 7) + Duration::seconds(1), hms(3, 5, 8));
-/// assert_eq!(hms(3, 5, 7) + Duration::seconds(-1), hms(3, 5, 6));
-/// assert_eq!(hms(3, 5, 7) + Duration::seconds(3600 + 60), hms(4, 6, 7));
-/// assert_eq!(hms(3, 5, 7) + Duration::seconds(86_400),
-/// from_ymd(2016, 7, 9).and_hms(3, 5, 7));
-/// assert_eq!(hms(3, 5, 7) + Duration::days(365),
-/// from_ymd(2017, 7, 8).and_hms(3, 5, 7));
-///
-/// let hmsm = |h, m, s, milli| d.and_hms_milli(h, m, s, milli);
-/// assert_eq!(hmsm(3, 5, 7, 980) + Duration::milliseconds(450), hmsm(3, 5, 8, 430));
-/// # }
-/// ~~~~
-///
-/// Leap seconds are handled,
-/// but the addition assumes that it is the only leap second happened.
-///
-/// ~~~~
-/// # extern crate chrono; fn main() {
-/// # use chrono::{Duration, NaiveDate};
-/// # let from_ymd = NaiveDate::from_ymd;
-/// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli(h, m, s, milli);
-/// let leap = hmsm(3, 5, 59, 1_300);
-/// assert_eq!(leap + Duration::zero(), hmsm(3, 5, 59, 1_300));
-/// assert_eq!(leap + Duration::milliseconds(-500), hmsm(3, 5, 59, 800));
-/// assert_eq!(leap + Duration::milliseconds(500), hmsm(3, 5, 59, 1_800));
-/// assert_eq!(leap + Duration::milliseconds(800), hmsm(3, 6, 0, 100));
-/// assert_eq!(leap + Duration::seconds(10), hmsm(3, 6, 9, 300));
-/// assert_eq!(leap + Duration::seconds(-10), hmsm(3, 5, 50, 300));
-/// assert_eq!(leap + Duration::days(1),
-/// from_ymd(2016, 7, 9).and_hms_milli(3, 5, 59, 300));
-/// # }
-/// ~~~~
-impl Add<OldDuration> for NaiveDateTime {
- type Output = NaiveDateTime;
-
- #[inline]
- fn add(self, rhs: OldDuration) -> NaiveDateTime {
- self.checked_add_signed(rhs).expect("`NaiveDateTime + Duration` overflowed")
- }
-}
-
-impl AddAssign<OldDuration> for NaiveDateTime {
- #[inline]
- fn add_assign(&mut self, rhs: OldDuration) {
- *self = self.add(rhs);
- }
-}
-
-/// A subtraction of `Duration` from `NaiveDateTime` yields another `NaiveDateTime`.
-/// It is the same as the addition with a negated `Duration`.
-///
-/// As a part of Chrono's [leap second handling](./struct.NaiveTime.html#leap-second-handling),
-/// the addition assumes that **there is no leap second ever**,
-/// except when the `NaiveDateTime` itself represents a leap second
-/// in which case the assumption becomes that **there is exactly a single leap second ever**.
-///
-/// Panics on underflow or overflow.
-/// Use [`NaiveDateTime::checked_sub_signed`](#method.checked_sub_signed) to detect that.
-///
-/// # Example
-///
-/// ~~~~
-/// # extern crate chrono; fn main() {
-/// use chrono::{Duration, NaiveDate};
-///
-/// let from_ymd = NaiveDate::from_ymd;
-///
-/// let d = from_ymd(2016, 7, 8);
-/// let hms = |h, m, s| d.and_hms(h, m, s);
-/// assert_eq!(hms(3, 5, 7) - Duration::zero(), hms(3, 5, 7));
-/// assert_eq!(hms(3, 5, 7) - Duration::seconds(1), hms(3, 5, 6));
-/// assert_eq!(hms(3, 5, 7) - Duration::seconds(-1), hms(3, 5, 8));
-/// assert_eq!(hms(3, 5, 7) - Duration::seconds(3600 + 60), hms(2, 4, 7));
-/// assert_eq!(hms(3, 5, 7) - Duration::seconds(86_400),
-/// from_ymd(2016, 7, 7).and_hms(3, 5, 7));
-/// assert_eq!(hms(3, 5, 7) - Duration::days(365),
-/// from_ymd(2015, 7, 9).and_hms(3, 5, 7));
-///
-/// let hmsm = |h, m, s, milli| d.and_hms_milli(h, m, s, milli);
-/// assert_eq!(hmsm(3, 5, 7, 450) - Duration::milliseconds(670), hmsm(3, 5, 6, 780));
-/// # }
-/// ~~~~
-///
-/// Leap seconds are handled,
-/// but the subtraction assumes that it is the only leap second happened.
-///
-/// ~~~~
-/// # extern crate chrono; fn main() {
-/// # use chrono::{Duration, NaiveDate};
-/// # let from_ymd = NaiveDate::from_ymd;
-/// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli(h, m, s, milli);
-/// let leap = hmsm(3, 5, 59, 1_300);
-/// assert_eq!(leap - Duration::zero(), hmsm(3, 5, 59, 1_300));
-/// assert_eq!(leap - Duration::milliseconds(200), hmsm(3, 5, 59, 1_100));
-/// assert_eq!(leap - Duration::milliseconds(500), hmsm(3, 5, 59, 800));
-/// assert_eq!(leap - Duration::seconds(60), hmsm(3, 5, 0, 300));
-/// assert_eq!(leap - Duration::days(1),
-/// from_ymd(2016, 7, 7).and_hms_milli(3, 6, 0, 300));
-/// # }
-/// ~~~~
-impl Sub<OldDuration> for NaiveDateTime {
- type Output = NaiveDateTime;
-
- #[inline]
- fn sub(self, rhs: OldDuration) -> NaiveDateTime {
- self.checked_sub_signed(rhs).expect("`NaiveDateTime - Duration` overflowed")
- }
-}
-
-impl SubAssign<OldDuration> for NaiveDateTime {
- #[inline]
- fn sub_assign(&mut self, rhs: OldDuration) {
- *self = self.sub(rhs);
- }
-}
-
-/// Subtracts another `NaiveDateTime` from the current date and time.
-/// This does not overflow or underflow at all.
-///
-/// As a part of Chrono's [leap second handling](./struct.NaiveTime.html#leap-second-handling),
-/// the subtraction assumes that **there is no leap second ever**,
-/// except when any of the `NaiveDateTime`s themselves represents a leap second
-/// in which case the assumption becomes that
-/// **there are exactly one (or two) leap second(s) ever**.
-///
-/// The implementation is a wrapper around
-/// [`NaiveDateTime::signed_duration_since`](#method.signed_duration_since).
-///
-/// # Example
-///
-/// ~~~~
-/// # extern crate chrono; fn main() {
-/// use chrono::{Duration, NaiveDate};
-///
-/// let from_ymd = NaiveDate::from_ymd;
-///
-/// let d = from_ymd(2016, 7, 8);
-/// assert_eq!(d.and_hms(3, 5, 7) - d.and_hms(2, 4, 6), Duration::seconds(3600 + 60 + 1));
-///
-/// // July 8 is 190th day in the year 2016
-/// let d0 = from_ymd(2016, 1, 1);
-/// assert_eq!(d.and_hms_milli(0, 7, 6, 500) - d0.and_hms(0, 0, 0),
-/// Duration::seconds(189 * 86_400 + 7 * 60 + 6) + Duration::milliseconds(500));
-/// # }
-/// ~~~~
-///
-/// Leap seconds are handled, but the subtraction assumes that
-/// there were no other leap seconds happened.
-///
-/// ~~~~
-/// # extern crate chrono; fn main() {
-/// # use chrono::{Duration, NaiveDate};
-/// # let from_ymd = NaiveDate::from_ymd;
-/// let leap = from_ymd(2015, 6, 30).and_hms_milli(23, 59, 59, 1_500);
-/// assert_eq!(leap - from_ymd(2015, 6, 30).and_hms(23, 0, 0),
-/// Duration::seconds(3600) + Duration::milliseconds(500));
-/// assert_eq!(from_ymd(2015, 7, 1).and_hms(1, 0, 0) - leap,
-/// Duration::seconds(3600) - Duration::milliseconds(500));
-/// # }
-/// ~~~~
-impl Sub<NaiveDateTime> for NaiveDateTime {
- type Output = OldDuration;
-
- #[inline]
- fn sub(self, rhs: NaiveDateTime) -> OldDuration {
- self.signed_duration_since(rhs)
- }
-}
-
-/// The `Debug` output of the naive date and time `dt` is the same as
-/// [`dt.format("%Y-%m-%dT%H:%M:%S%.f")`](../format/strftime/index.html).
-///
-/// The string printed can be readily parsed via the `parse` method on `str`.
-///
-/// It should be noted that, for leap seconds not on the minute boundary,
-/// it may print a representation not distinguishable from non-leap seconds.
-/// This doesn't matter in practice, since such leap seconds never happened.
-/// (By the time of the first leap second on 1972-06-30,
-/// every time zone offset around the world has standardized to the 5-minute alignment.)
-///
-/// # Example
-///
-/// ~~~~
-/// use chrono::NaiveDate;
-///
-/// let dt = NaiveDate::from_ymd(2016, 11, 15).and_hms(7, 39, 24);
-/// assert_eq!(format!("{:?}", dt), "2016-11-15T07:39:24");
-/// ~~~~
-///
-/// Leap seconds may also be used.
-///
-/// ~~~~
-/// # use chrono::NaiveDate;
-/// let dt = NaiveDate::from_ymd(2015, 6, 30).and_hms_milli(23, 59, 59, 1_500);
-/// assert_eq!(format!("{:?}", dt), "2015-06-30T23:59:60.500");
-/// ~~~~
-impl fmt::Debug for NaiveDateTime {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{:?}T{:?}", self.date, self.time)
- }
-}
-
-/// The `Display` output of the naive date and time `dt` is the same as
-/// [`dt.format("%Y-%m-%d %H:%M:%S%.f")`](../format/strftime/index.html).
-///
-/// It should be noted that, for leap seconds not on the minute boundary,
-/// it may print a representation not distinguishable from non-leap seconds.
-/// This doesn't matter in practice, since such leap seconds never happened.
-/// (By the time of the first leap second on 1972-06-30,
-/// every time zone offset around the world has standardized to the 5-minute alignment.)
-///
-/// # Example
-///
-/// ~~~~
-/// use chrono::NaiveDate;
-///
-/// let dt = NaiveDate::from_ymd(2016, 11, 15).and_hms(7, 39, 24);
-/// assert_eq!(format!("{}", dt), "2016-11-15 07:39:24");
-/// ~~~~
-///
-/// Leap seconds may also be used.
-///
-/// ~~~~
-/// # use chrono::NaiveDate;
-/// let dt = NaiveDate::from_ymd(2015, 6, 30).and_hms_milli(23, 59, 59, 1_500);
-/// assert_eq!(format!("{}", dt), "2015-06-30 23:59:60.500");
-/// ~~~~
-impl fmt::Display for NaiveDateTime {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{} {}", self.date, self.time)
- }
-}
-
-/// Parsing a `str` into a `NaiveDateTime` uses the same format,
-/// [`%Y-%m-%dT%H:%M:%S%.f`](../format/strftime/index.html), as in `Debug`.
-///
-/// # Example
-///
-/// ~~~~
-/// use chrono::{NaiveDateTime, NaiveDate};
-///
-/// let dt = NaiveDate::from_ymd(2015, 9, 18).and_hms(23, 56, 4);
-/// assert_eq!("2015-09-18T23:56:04".parse::<NaiveDateTime>(), Ok(dt));
-///
-/// let dt = NaiveDate::from_ymd(12345, 6, 7).and_hms_milli(7, 59, 59, 1_500); // leap second
-/// assert_eq!("+12345-6-7T7:59:60.5".parse::<NaiveDateTime>(), Ok(dt));
-///
-/// assert!("foo".parse::<NaiveDateTime>().is_err());
-/// ~~~~
-impl str::FromStr for NaiveDateTime {
- type Err = ParseError;
-
- fn from_str(s: &str) -> ParseResult<NaiveDateTime> {
- const ITEMS: &'static [Item<'static>] = &[
- Item::Numeric(Numeric::Year, Pad::Zero),
- Item::Space(""),
- Item::Literal("-"),
- Item::Numeric(Numeric::Month, Pad::Zero),
- Item::Space(""),
- Item::Literal("-"),
- Item::Numeric(Numeric::Day, Pad::Zero),
- Item::Space(""),
- Item::Literal("T"), // XXX shouldn't this be case-insensitive?
- Item::Numeric(Numeric::Hour, Pad::Zero),
- Item::Space(""),
- Item::Literal(":"),
- Item::Numeric(Numeric::Minute, Pad::Zero),
- Item::Space(""),
- Item::Literal(":"),
- Item::Numeric(Numeric::Second, Pad::Zero),
- Item::Fixed(Fixed::Nanosecond),
- Item::Space(""),
- ];
-
- let mut parsed = Parsed::new();
- parse(&mut parsed, s, ITEMS.iter())?;
- parsed.to_naive_datetime_with_offset(0)
- }
-}
-
-#[cfg(all(test, any(feature = "rustc-serialize", feature = "serde")))]
-fn test_encodable_json<F, E>(to_string: F)
-where
- F: Fn(&NaiveDateTime) -> Result<String, E>,
- E: ::std::fmt::Debug,
-{
- use naive::{MAX_DATE, MIN_DATE};
-
- assert_eq!(
- to_string(&NaiveDate::from_ymd(2016, 7, 8).and_hms_milli(9, 10, 48, 90)).ok(),
- Some(r#""2016-07-08T09:10:48.090""#.into())
- );
- assert_eq!(
- to_string(&NaiveDate::from_ymd(2014, 7, 24).and_hms(12, 34, 6)).ok(),
- Some(r#""2014-07-24T12:34:06""#.into())
- );
- assert_eq!(
- to_string(&NaiveDate::from_ymd(0, 1, 1).and_hms_milli(0, 0, 59, 1_000)).ok(),
- Some(r#""0000-01-01T00:00:60""#.into())
- );
- assert_eq!(
- to_string(&NaiveDate::from_ymd(-1, 12, 31).and_hms_nano(23, 59, 59, 7)).ok(),
- Some(r#""-0001-12-31T23:59:59.000000007""#.into())
- );
- assert_eq!(
- to_string(&MIN_DATE.and_hms(0, 0, 0)).ok(),
- Some(r#""-262144-01-01T00:00:00""#.into())
- );
- assert_eq!(
- to_string(&MAX_DATE.and_hms_nano(23, 59, 59, 1_999_999_999)).ok(),
- Some(r#""+262143-12-31T23:59:60.999999999""#.into())
- );
-}
-
-#[cfg(all(test, any(feature = "rustc-serialize", feature = "serde")))]
-fn test_decodable_json<F, E>(from_str: F)
-where
- F: Fn(&str) -> Result<NaiveDateTime, E>,
- E: ::std::fmt::Debug,
-{
- use naive::{MAX_DATE, MIN_DATE};
-
- assert_eq!(
- from_str(r#""2016-07-08T09:10:48.090""#).ok(),
- Some(NaiveDate::from_ymd(2016, 7, 8).and_hms_milli(9, 10, 48, 90))
- );
- assert_eq!(
- from_str(r#""2016-7-8T9:10:48.09""#).ok(),
- Some(NaiveDate::from_ymd(2016, 7, 8).and_hms_milli(9, 10, 48, 90))
- );
- assert_eq!(
- from_str(r#""2014-07-24T12:34:06""#).ok(),
- Some(NaiveDate::from_ymd(2014, 7, 24).and_hms(12, 34, 6))
- );
- assert_eq!(
- from_str(r#""0000-01-01T00:00:60""#).ok(),
- Some(NaiveDate::from_ymd(0, 1, 1).and_hms_milli(0, 0, 59, 1_000))
- );
- assert_eq!(
- from_str(r#""0-1-1T0:0:60""#).ok(),
- Some(NaiveDate::from_ymd(0, 1, 1).and_hms_milli(0, 0, 59, 1_000))
- );
- assert_eq!(
- from_str(r#""-0001-12-31T23:59:59.000000007""#).ok(),
- Some(NaiveDate::from_ymd(-1, 12, 31).and_hms_nano(23, 59, 59, 7))
- );
- assert_eq!(from_str(r#""-262144-01-01T00:00:00""#).ok(), Some(MIN_DATE.and_hms(0, 0, 0)));
- assert_eq!(
- from_str(r#""+262143-12-31T23:59:60.999999999""#).ok(),
- Some(MAX_DATE.and_hms_nano(23, 59, 59, 1_999_999_999))
- );
- assert_eq!(
- from_str(r#""+262143-12-31T23:59:60.9999999999997""#).ok(), // excess digits are ignored
- Some(MAX_DATE.and_hms_nano(23, 59, 59, 1_999_999_999))
- );
-
- // bad formats
- assert!(from_str(r#""""#).is_err());
- assert!(from_str(r#""2016-07-08""#).is_err());
- assert!(from_str(r#""09:10:48.090""#).is_err());
- assert!(from_str(r#""20160708T091048.090""#).is_err());
- assert!(from_str(r#""2000-00-00T00:00:00""#).is_err());
- assert!(from_str(r#""2000-02-30T00:00:00""#).is_err());
- assert!(from_str(r#""2001-02-29T00:00:00""#).is_err());
- assert!(from_str(r#""2002-02-28T24:00:00""#).is_err());
- assert!(from_str(r#""2002-02-28T23:60:00""#).is_err());
- assert!(from_str(r#""2002-02-28T23:59:61""#).is_err());
- assert!(from_str(r#""2016-07-08T09:10:48,090""#).is_err());
- assert!(from_str(r#""2016-07-08 09:10:48.090""#).is_err());
- assert!(from_str(r#""2016-007-08T09:10:48.090""#).is_err());
- assert!(from_str(r#""yyyy-mm-ddThh:mm:ss.fffffffff""#).is_err());
- assert!(from_str(r#"20160708000000"#).is_err());
- assert!(from_str(r#"{}"#).is_err());
- // pre-0.3.0 rustc-serialize format is now invalid
- assert!(from_str(r#"{"date":{"ymdf":20},"time":{"secs":0,"frac":0}}"#).is_err());
- assert!(from_str(r#"null"#).is_err());
-}
-
-#[cfg(all(test, feature = "rustc-serialize"))]
-fn test_decodable_json_timestamp<F, E>(from_str: F)
-where
- F: Fn(&str) -> Result<rustc_serialize::TsSeconds, E>,
- E: ::std::fmt::Debug,
-{
- assert_eq!(
- *from_str("0").unwrap(),
- NaiveDate::from_ymd(1970, 1, 1).and_hms(0, 0, 0),
- "should parse integers as timestamps"
- );
- assert_eq!(
- *from_str("-1").unwrap(),
- NaiveDate::from_ymd(1969, 12, 31).and_hms(23, 59, 59),
- "should parse integers as timestamps"
- );
-}
-
-#[cfg(feature = "rustc-serialize")]
-pub mod rustc_serialize {
- use super::NaiveDateTime;
- use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
- use std::ops::Deref;
-
- impl Encodable for NaiveDateTime {
- fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
- format!("{:?}", self).encode(s)
- }
- }
-
- impl Decodable for NaiveDateTime {
- fn decode<D: Decoder>(d: &mut D) -> Result<NaiveDateTime, D::Error> {
- d.read_str()?.parse().map_err(|_| d.error("invalid date time string"))
- }
- }
-
- /// A `DateTime` that can be deserialized from a seconds-based timestamp
- #[derive(Debug)]
- #[deprecated(
- since = "1.4.2",
- note = "RustcSerialize will be removed before chrono 1.0, use Serde instead"
- )]
- pub struct TsSeconds(NaiveDateTime);
-
- #[allow(deprecated)]
- impl From<TsSeconds> for NaiveDateTime {
- /// Pull the internal NaiveDateTime out
- #[allow(deprecated)]
- fn from(obj: TsSeconds) -> NaiveDateTime {
- obj.0
- }
- }
-
- #[allow(deprecated)]
- impl Deref for TsSeconds {
- type Target = NaiveDateTime;
-
- #[allow(deprecated)]
- fn deref(&self) -> &Self::Target {
- &self.0
- }
- }
-
- #[allow(deprecated)]
- impl Decodable for TsSeconds {
- #[allow(deprecated)]
- fn decode<D: Decoder>(d: &mut D) -> Result<TsSeconds, D::Error> {
- Ok(TsSeconds(
- NaiveDateTime::from_timestamp_opt(d.read_i64()?, 0)
- .ok_or_else(|| d.error("invalid timestamp"))?,
- ))
- }
- }
-
- #[cfg(test)]
- use rustc_serialize::json;
-
- #[test]
- fn test_encodable() {
- super::test_encodable_json(json::encode);
- }
-
- #[test]
- fn test_decodable() {
- super::test_decodable_json(json::decode);
- }
-
- #[test]
- fn test_decodable_timestamps() {
- super::test_decodable_json_timestamp(json::decode);
- }
-}
-
-/// Tools to help serializing/deserializing `NaiveDateTime`s
-#[cfg(feature = "serde")]
-pub mod serde {
- use super::NaiveDateTime;
- use core::fmt;
- use serdelib::{de, ser};
-
- /// Serialize a `NaiveDateTime` as an RFC 3339 string
- ///
- /// See [the `serde` module](./serde/index.html) for alternate
- /// serialization formats.
- impl ser::Serialize for NaiveDateTime {
- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- where
- S: ser::Serializer,
- {
- struct FormatWrapped<'a, D: 'a> {
- inner: &'a D,
- }
-
- impl<'a, D: fmt::Debug> fmt::Display for FormatWrapped<'a, D> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- self.inner.fmt(f)
- }
- }
-
- serializer.collect_str(&FormatWrapped { inner: &self })
- }
- }
-
- struct NaiveDateTimeVisitor;
-
- impl<'de> de::Visitor<'de> for NaiveDateTimeVisitor {
- type Value = NaiveDateTime;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- write!(formatter, "a formatted date and time string")
- }
-
- fn visit_str<E>(self, value: &str) -> Result<NaiveDateTime, E>
- where
- E: de::Error,
- {
- value.parse().map_err(E::custom)
- }
- }
-
- impl<'de> de::Deserialize<'de> for NaiveDateTime {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: de::Deserializer<'de>,
- {
- deserializer.deserialize_str(NaiveDateTimeVisitor)
- }
- }
-
- /// Used to serialize/deserialize from nanosecond-precision timestamps
- ///
- /// # Example:
- ///
- /// ```rust
- /// # // We mark this ignored so that we can test on 1.13 (which does not
- /// # // support custom derive), and run tests with --ignored on beta and
- /// # // nightly to actually trigger these.
- /// #
- /// # #[macro_use] extern crate serde_derive;
- /// # extern crate serde_json;
- /// # extern crate serde;
- /// # extern crate chrono;
- /// # use chrono::{TimeZone, NaiveDate, NaiveDateTime, Utc};
- /// use chrono::naive::serde::ts_nanoseconds;
- /// #[derive(Deserialize, Serialize)]
- /// struct S {
- /// #[serde(with = "ts_nanoseconds")]
- /// time: NaiveDateTime
- /// }
- ///
- /// # fn example() -> Result<S, serde_json::Error> {
- /// let time = NaiveDate::from_ymd(2018, 5, 17).and_hms_nano(02, 04, 59, 918355733);
- /// let my_s = S {
- /// time: time.clone(),
- /// };
- ///
- /// let as_string = serde_json::to_string(&my_s)?;
- /// assert_eq!(as_string, r#"{"time":1526522699918355733}"#);
- /// let my_s: S = serde_json::from_str(&as_string)?;
- /// assert_eq!(my_s.time, time);
- /// # Ok(my_s)
- /// # }
- /// # fn main() { example().unwrap(); }
- /// ```
- pub mod ts_nanoseconds {
- use core::fmt;
- use serdelib::{de, ser};
-
- use {ne_timestamp, NaiveDateTime};
-
- /// Serialize a UTC datetime into an integer number of nanoseconds since the epoch
- ///
- /// Intended for use with `serde`s `serialize_with` attribute.
- ///
- /// # Example:
- ///
- /// ```rust
- /// # // We mark this ignored so that we can test on 1.13 (which does not
- /// # // support custom derive), and run tests with --ignored on beta and
- /// # // nightly to actually trigger these.
- /// #
- /// # #[macro_use] extern crate serde_derive;
- /// # #[macro_use] extern crate serde_json;
- /// # #[macro_use] extern crate serde;
- /// # extern crate chrono;
- /// # use chrono::{TimeZone, NaiveDate, NaiveDateTime, Utc};
- /// # use serde::Serialize;
- /// use chrono::naive::serde::ts_nanoseconds::serialize as to_nano_ts;
- /// #[derive(Serialize)]
- /// struct S {
- /// #[serde(serialize_with = "to_nano_ts")]
- /// time: NaiveDateTime
- /// }
- ///
- /// # fn example() -> Result<String, serde_json::Error> {
- /// let my_s = S {
- /// time: NaiveDate::from_ymd(2018, 5, 17).and_hms_nano(02, 04, 59, 918355733),
- /// };
- /// let as_string = serde_json::to_string(&my_s)?;
- /// assert_eq!(as_string, r#"{"time":1526522699918355733}"#);
- /// # Ok(as_string)
- /// # }
- /// # fn main() { example().unwrap(); }
- /// ```
- pub fn serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
- where
- S: ser::Serializer,
- {
- serializer.serialize_i64(dt.timestamp_nanos())
- }
-
- /// Deserialize a `DateTime` from a nanoseconds timestamp
- ///
- /// Intended for use with `serde`s `deserialize_with` attribute.
- ///
- /// # Example:
- ///
- /// ```rust
- /// # // We mark this ignored so that we can test on 1.13 (which does not
- /// # // support custom derive), and run tests with --ignored on beta and
- /// # // nightly to actually trigger these.
- /// #
- /// # #[macro_use] extern crate serde_derive;
- /// # #[macro_use] extern crate serde_json;
- /// # extern crate serde;
- /// # extern crate chrono;
- /// # use chrono::{NaiveDateTime, Utc};
- /// # use serde::Deserialize;
- /// use chrono::naive::serde::ts_nanoseconds::deserialize as from_nano_ts;
- /// #[derive(Deserialize)]
- /// struct S {
- /// #[serde(deserialize_with = "from_nano_ts")]
- /// time: NaiveDateTime
- /// }
- ///
- /// # fn example() -> Result<S, serde_json::Error> {
- /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355733 }"#)?;
- /// # Ok(my_s)
- /// # }
- /// # fn main() { example().unwrap(); }
- /// ```
- pub fn deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error>
- where
- D: de::Deserializer<'de>,
- {
- Ok(d.deserialize_i64(NaiveDateTimeFromNanoSecondsVisitor)?)
- }
-
- struct NaiveDateTimeFromNanoSecondsVisitor;
-
- impl<'de> de::Visitor<'de> for NaiveDateTimeFromNanoSecondsVisitor {
- type Value = NaiveDateTime;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str("a unix timestamp")
- }
-
- fn visit_i64<E>(self, value: i64) -> Result<NaiveDateTime, E>
- where
- E: de::Error,
- {
- NaiveDateTime::from_timestamp_opt(
- value / 1_000_000_000,
- (value % 1_000_000_000) as u32,
- )
- .ok_or_else(|| E::custom(ne_timestamp(value)))
- }
-
- fn visit_u64<E>(self, value: u64) -> Result<NaiveDateTime, E>
- where
- E: de::Error,
- {
- NaiveDateTime::from_timestamp_opt(
- value as i64 / 1_000_000_000,
- (value as i64 % 1_000_000_000) as u32,
- )
- .ok_or_else(|| E::custom(ne_timestamp(value)))
- }
- }
- }
-
- /// Used to serialize/deserialize from millisecond-precision timestamps
- ///
- /// # Example:
- ///
- /// ```rust
- /// # // We mark this ignored so that we can test on 1.13 (which does not
- /// # // support custom derive), and run tests with --ignored on beta and
- /// # // nightly to actually trigger these.
- /// #
- /// # #[macro_use] extern crate serde_derive;
- /// # extern crate serde_json;
- /// # extern crate serde;
- /// # extern crate chrono;
- /// # use chrono::{TimeZone, NaiveDate, NaiveDateTime, Utc};
- /// use chrono::naive::serde::ts_milliseconds;
- /// #[derive(Deserialize, Serialize)]
- /// struct S {
- /// #[serde(with = "ts_milliseconds")]
- /// time: NaiveDateTime
- /// }
- ///
- /// # fn example() -> Result<S, serde_json::Error> {
- /// let time = NaiveDate::from_ymd(2018, 5, 17).and_hms_milli(02, 04, 59, 918);
- /// let my_s = S {
- /// time: time.clone(),
- /// };
- ///
- /// let as_string = serde_json::to_string(&my_s)?;
- /// assert_eq!(as_string, r#"{"time":1526522699918}"#);
- /// let my_s: S = serde_json::from_str(&as_string)?;
- /// assert_eq!(my_s.time, time);
- /// # Ok(my_s)
- /// # }
- /// # fn main() { example().unwrap(); }
- /// ```
- pub mod ts_milliseconds {
- use core::fmt;
- use serdelib::{de, ser};
-
- use {ne_timestamp, NaiveDateTime};
-
- /// Serialize a UTC datetime into an integer number of milliseconds since the epoch
- ///
- /// Intended for use with `serde`s `serialize_with` attribute.
- ///
- /// # Example:
- ///
- /// ```rust
- /// # // We mark this ignored so that we can test on 1.13 (which does not
- /// # // support custom derive), and run tests with --ignored on beta and
- /// # // nightly to actually trigger these.
- /// #
- /// # #[macro_use] extern crate serde_derive;
- /// # #[macro_use] extern crate serde_json;
- /// # #[macro_use] extern crate serde;
- /// # extern crate chrono;
- /// # use chrono::{TimeZone, NaiveDate, NaiveDateTime, Utc};
- /// # use serde::Serialize;
- /// use chrono::naive::serde::ts_milliseconds::serialize as to_milli_ts;
- /// #[derive(Serialize)]
- /// struct S {
- /// #[serde(serialize_with = "to_milli_ts")]
- /// time: NaiveDateTime
- /// }
- ///
- /// # fn example() -> Result<String, serde_json::Error> {
- /// let my_s = S {
- /// time: NaiveDate::from_ymd(2018, 5, 17).and_hms_milli(02, 04, 59, 918),
- /// };
- /// let as_string = serde_json::to_string(&my_s)?;
- /// assert_eq!(as_string, r#"{"time":1526522699918}"#);
- /// # Ok(as_string)
- /// # }
- /// # fn main() { example().unwrap(); }
- /// ```
- pub fn serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
- where
- S: ser::Serializer,
- {
- serializer.serialize_i64(dt.timestamp_millis())
- }
-
- /// Deserialize a `DateTime` from a milliseconds timestamp
- ///
- /// Intended for use with `serde`s `deserialize_with` attribute.
- ///
- /// # Example:
- ///
- /// ```rust
- /// # // We mark this ignored so that we can test on 1.13 (which does not
- /// # // support custom derive), and run tests with --ignored on beta and
- /// # // nightly to actually trigger these.
- /// #
- /// # #[macro_use] extern crate serde_derive;
- /// # #[macro_use] extern crate serde_json;
- /// # extern crate serde;
- /// # extern crate chrono;
- /// # use chrono::{NaiveDateTime, Utc};
- /// # use serde::Deserialize;
- /// use chrono::naive::serde::ts_milliseconds::deserialize as from_milli_ts;
- /// #[derive(Deserialize)]
- /// struct S {
- /// #[serde(deserialize_with = "from_milli_ts")]
- /// time: NaiveDateTime
- /// }
- ///
- /// # fn example() -> Result<S, serde_json::Error> {
- /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918 }"#)?;
- /// # Ok(my_s)
- /// # }
- /// # fn main() { example().unwrap(); }
- /// ```
- pub fn deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error>
- where
- D: de::Deserializer<'de>,
- {
- Ok(d.deserialize_i64(NaiveDateTimeFromMilliSecondsVisitor)?)
- }
-
- struct NaiveDateTimeFromMilliSecondsVisitor;
-
- impl<'de> de::Visitor<'de> for NaiveDateTimeFromMilliSecondsVisitor {
- type Value = NaiveDateTime;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str("a unix timestamp")
- }
-
- fn visit_i64<E>(self, value: i64) -> Result<NaiveDateTime, E>
- where
- E: de::Error,
- {
- NaiveDateTime::from_timestamp_opt(value / 1000, ((value % 1000) * 1_000_000) as u32)
- .ok_or_else(|| E::custom(ne_timestamp(value)))
- }
-
- fn visit_u64<E>(self, value: u64) -> Result<NaiveDateTime, E>
- where
- E: de::Error,
- {
- NaiveDateTime::from_timestamp_opt(
- (value / 1000) as i64,
- ((value % 1000) * 1_000_000) as u32,
- )
- .ok_or_else(|| E::custom(ne_timestamp(value)))
- }
- }
- }
-
- /// Used to serialize/deserialize from second-precision timestamps
- ///
- /// # Example:
- ///
- /// ```rust
- /// # // We mark this ignored so that we can test on 1.13 (which does not
- /// # // support custom derive), and run tests with --ignored on beta and
- /// # // nightly to actually trigger these.
- /// #
- /// # #[macro_use] extern crate serde_derive;
- /// # extern crate serde_json;
- /// # extern crate serde;
- /// # extern crate chrono;
- /// # use chrono::{TimeZone, NaiveDate, NaiveDateTime, Utc};
- /// use chrono::naive::serde::ts_seconds;
- /// #[derive(Deserialize, Serialize)]
- /// struct S {
- /// #[serde(with = "ts_seconds")]
- /// time: NaiveDateTime
- /// }
- ///
- /// # fn example() -> Result<S, serde_json::Error> {
- /// let time = NaiveDate::from_ymd(2015, 5, 15).and_hms(10, 0, 0);
- /// let my_s = S {
- /// time: time.clone(),
- /// };
- ///
- /// let as_string = serde_json::to_string(&my_s)?;
- /// assert_eq!(as_string, r#"{"time":1431684000}"#);
- /// let my_s: S = serde_json::from_str(&as_string)?;
- /// assert_eq!(my_s.time, time);
- /// # Ok(my_s)
- /// # }
- /// # fn main() { example().unwrap(); }
- /// ```
- pub mod ts_seconds {
- use core::fmt;
- use serdelib::{de, ser};
-
- use {ne_timestamp, NaiveDateTime};
-
- /// Serialize a UTC datetime into an integer number of seconds since the epoch
- ///
- /// Intended for use with `serde`s `serialize_with` attribute.
- ///
- /// # Example:
- ///
- /// ```rust
- /// # // We mark this ignored so that we can test on 1.13 (which does not
- /// # // support custom derive), and run tests with --ignored on beta and
- /// # // nightly to actually trigger these.
- /// #
- /// # #[macro_use] extern crate serde_derive;
- /// # #[macro_use] extern crate serde_json;
- /// # #[macro_use] extern crate serde;
- /// # extern crate chrono;
- /// # use chrono::{TimeZone, NaiveDate, NaiveDateTime, Utc};
- /// # use serde::Serialize;
- /// use chrono::naive::serde::ts_seconds::serialize as to_ts;
- /// #[derive(Serialize)]
- /// struct S {
- /// #[serde(serialize_with = "to_ts")]
- /// time: NaiveDateTime
- /// }
- ///
- /// # fn example() -> Result<String, serde_json::Error> {
- /// let my_s = S {
- /// time: NaiveDate::from_ymd(2015, 5, 15).and_hms(10, 0, 0),
- /// };
- /// let as_string = serde_json::to_string(&my_s)?;
- /// assert_eq!(as_string, r#"{"time":1431684000}"#);
- /// # Ok(as_string)
- /// # }
- /// # fn main() { example().unwrap(); }
- /// ```
- pub fn serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
- where
- S: ser::Serializer,
- {
- serializer.serialize_i64(dt.timestamp())
- }
-
- /// Deserialize a `DateTime` from a seconds timestamp
- ///
- /// Intended for use with `serde`s `deserialize_with` attribute.
- ///
- /// # Example:
- ///
- /// ```rust
- /// # // We mark this ignored so that we can test on 1.13 (which does not
- /// # // support custom derive), and run tests with --ignored on beta and
- /// # // nightly to actually trigger these.
- /// #
- /// # #[macro_use] extern crate serde_derive;
- /// # #[macro_use] extern crate serde_json;
- /// # extern crate serde;
- /// # extern crate chrono;
- /// # use chrono::{NaiveDateTime, Utc};
- /// # use serde::Deserialize;
- /// use chrono::naive::serde::ts_seconds::deserialize as from_ts;
- /// #[derive(Deserialize)]
- /// struct S {
- /// #[serde(deserialize_with = "from_ts")]
- /// time: NaiveDateTime
- /// }
- ///
- /// # fn example() -> Result<S, serde_json::Error> {
- /// let my_s: S = serde_json::from_str(r#"{ "time": 1431684000 }"#)?;
- /// # Ok(my_s)
- /// # }
- /// # fn main() { example().unwrap(); }
- /// ```
- pub fn deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error>
- where
- D: de::Deserializer<'de>,
- {
- Ok(d.deserialize_i64(NaiveDateTimeFromSecondsVisitor)?)
- }
-
- struct NaiveDateTimeFromSecondsVisitor;
-
- impl<'de> de::Visitor<'de> for NaiveDateTimeFromSecondsVisitor {
- type Value = NaiveDateTime;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str("a unix timestamp")
- }
-
- fn visit_i64<E>(self, value: i64) -> Result<NaiveDateTime, E>
- where
- E: de::Error,
- {
- NaiveDateTime::from_timestamp_opt(value, 0)
- .ok_or_else(|| E::custom(ne_timestamp(value)))
- }
-
- fn visit_u64<E>(self, value: u64) -> Result<NaiveDateTime, E>
- where
- E: de::Error,
- {
- NaiveDateTime::from_timestamp_opt(value as i64, 0)
- .ok_or_else(|| E::custom(ne_timestamp(value)))
- }
- }
- }
-
- #[cfg(test)]
- extern crate bincode;
- #[cfg(test)]
- extern crate serde_derive;
- #[cfg(test)]
- extern crate serde_json;
-
- #[test]
- fn test_serde_serialize() {
- super::test_encodable_json(self::serde_json::to_string);
- }
-
- #[test]
- fn test_serde_deserialize() {
- super::test_decodable_json(|input| self::serde_json::from_str(&input));
- }
-
- // Bincode is relevant to test separately from JSON because
- // it is not self-describing.
- #[test]
- fn test_serde_bincode() {
- use self::bincode::{deserialize, serialize, Infinite};
- use naive::NaiveDate;
-
- let dt = NaiveDate::from_ymd(2016, 7, 8).and_hms_milli(9, 10, 48, 90);
- let encoded = serialize(&dt, Infinite).unwrap();
- let decoded: NaiveDateTime = deserialize(&encoded).unwrap();
- assert_eq!(dt, decoded);
- }
-
- #[test]
- fn test_serde_bincode_optional() {
- use self::bincode::{deserialize, serialize, Infinite};
- use self::serde_derive::{Deserialize, Serialize};
- use prelude::*;
- use serde::ts_nanoseconds_option;
-
- #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
- struct Test {
- one: Option<i64>,
- #[serde(with = "ts_nanoseconds_option")]
- two: Option<DateTime<Utc>>,
- }
-
- let expected = Test { one: Some(1), two: Some(Utc.ymd(1970, 1, 1).and_hms(0, 1, 1)) };
- let bytes: Vec<u8> = serialize(&expected, Infinite).unwrap();
- let actual = deserialize::<Test>(&(bytes)).unwrap();
-
- assert_eq!(expected, actual);
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::NaiveDateTime;
- use naive::{NaiveDate, MAX_DATE, MIN_DATE};
- use oldtime::Duration;
- use std::i64;
- use Datelike;
-
- #[test]
- fn test_datetime_from_timestamp() {
- let from_timestamp = |secs| NaiveDateTime::from_timestamp_opt(secs, 0);
- let ymdhms = |y, m, d, h, n, s| NaiveDate::from_ymd(y, m, d).and_hms(h, n, s);
- assert_eq!(from_timestamp(-1), Some(ymdhms(1969, 12, 31, 23, 59, 59)));
- assert_eq!(from_timestamp(0), Some(ymdhms(1970, 1, 1, 0, 0, 0)));
- assert_eq!(from_timestamp(1), Some(ymdhms(1970, 1, 1, 0, 0, 1)));
- assert_eq!(from_timestamp(1_000_000_000), Some(ymdhms(2001, 9, 9, 1, 46, 40)));
- assert_eq!(from_timestamp(0x7fffffff), Some(ymdhms(2038, 1, 19, 3, 14, 7)));
- assert_eq!(from_timestamp(i64::MIN), None);
- assert_eq!(from_timestamp(i64::MAX), None);
- }
-
- #[test]
- fn test_datetime_add() {
- fn check(
- (y, m, d, h, n, s): (i32, u32, u32, u32, u32, u32),
- rhs: Duration,
- result: Option<(i32, u32, u32, u32, u32, u32)>,
- ) {
- let lhs = NaiveDate::from_ymd(y, m, d).and_hms(h, n, s);
- let sum =
- result.map(|(y, m, d, h, n, s)| NaiveDate::from_ymd(y, m, d).and_hms(h, n, s));
- assert_eq!(lhs.checked_add_signed(rhs), sum);
- assert_eq!(lhs.checked_sub_signed(-rhs), sum);
- };
-
- check(
- (2014, 5, 6, 7, 8, 9),
- Duration::seconds(3600 + 60 + 1),
- Some((2014, 5, 6, 8, 9, 10)),
- );
- check(
- (2014, 5, 6, 7, 8, 9),
- Duration::seconds(-(3600 + 60 + 1)),
- Some((2014, 5, 6, 6, 7, 8)),
- );
- check((2014, 5, 6, 7, 8, 9), Duration::seconds(86399), Some((2014, 5, 7, 7, 8, 8)));
- check((2014, 5, 6, 7, 8, 9), Duration::seconds(86_400 * 10), Some((2014, 5, 16, 7, 8, 9)));
- check((2014, 5, 6, 7, 8, 9), Duration::seconds(-86_400 * 10), Some((2014, 4, 26, 7, 8, 9)));
- check((2014, 5, 6, 7, 8, 9), Duration::seconds(86_400 * 10), Some((2014, 5, 16, 7, 8, 9)));
-
- // overflow check
- // assumes that we have correct values for MAX/MIN_DAYS_FROM_YEAR_0 from `naive::date`.
- // (they are private constants, but the equivalence is tested in that module.)
- let max_days_from_year_0 = MAX_DATE.signed_duration_since(NaiveDate::from_ymd(0, 1, 1));
- check((0, 1, 1, 0, 0, 0), max_days_from_year_0, Some((MAX_DATE.year(), 12, 31, 0, 0, 0)));
- check(
- (0, 1, 1, 0, 0, 0),
- max_days_from_year_0 + Duration::seconds(86399),
- Some((MAX_DATE.year(), 12, 31, 23, 59, 59)),
- );
- check((0, 1, 1, 0, 0, 0), max_days_from_year_0 + Duration::seconds(86_400), None);
- check((0, 1, 1, 0, 0, 0), Duration::max_value(), None);
-
- let min_days_from_year_0 = MIN_DATE.signed_duration_since(NaiveDate::from_ymd(0, 1, 1));
- check((0, 1, 1, 0, 0, 0), min_days_from_year_0, Some((MIN_DATE.year(), 1, 1, 0, 0, 0)));
- check((0, 1, 1, 0, 0, 0), min_days_from_year_0 - Duration::seconds(1), None);
- check((0, 1, 1, 0, 0, 0), Duration::min_value(), None);
- }
-
- #[test]
- fn test_datetime_sub() {
- let ymdhms = |y, m, d, h, n, s| NaiveDate::from_ymd(y, m, d).and_hms(h, n, s);
- let since = NaiveDateTime::signed_duration_since;
- assert_eq!(
- since(ymdhms(2014, 5, 6, 7, 8, 9), ymdhms(2014, 5, 6, 7, 8, 9)),
- Duration::zero()
- );
- assert_eq!(
- since(ymdhms(2014, 5, 6, 7, 8, 10), ymdhms(2014, 5, 6, 7, 8, 9)),
- Duration::seconds(1)
- );
- assert_eq!(
- since(ymdhms(2014, 5, 6, 7, 8, 9), ymdhms(2014, 5, 6, 7, 8, 10)),
- Duration::seconds(-1)
- );
- assert_eq!(
- since(ymdhms(2014, 5, 7, 7, 8, 9), ymdhms(2014, 5, 6, 7, 8, 10)),
- Duration::seconds(86399)
- );
- assert_eq!(
- since(ymdhms(2001, 9, 9, 1, 46, 39), ymdhms(1970, 1, 1, 0, 0, 0)),
- Duration::seconds(999_999_999)
- );
- }
-
- #[test]
- fn test_datetime_addassignment() {
- let ymdhms = |y, m, d, h, n, s| NaiveDate::from_ymd(y, m, d).and_hms(h, n, s);
- let mut date = ymdhms(2016, 10, 1, 10, 10, 10);
- date += Duration::minutes(10_000_000);
- assert_eq!(date, ymdhms(2035, 10, 6, 20, 50, 10));
- date += Duration::days(10);
- assert_eq!(date, ymdhms(2035, 10, 16, 20, 50, 10));
- }
-
- #[test]
- fn test_datetime_subassignment() {
- let ymdhms = |y, m, d, h, n, s| NaiveDate::from_ymd(y, m, d).and_hms(h, n, s);
- let mut date = ymdhms(2016, 10, 1, 10, 10, 10);
- date -= Duration::minutes(10_000_000);
- assert_eq!(date, ymdhms(1997, 9, 26, 23, 30, 10));
- date -= Duration::days(10);
- assert_eq!(date, ymdhms(1997, 9, 16, 23, 30, 10));
- }
-
- #[test]
- fn test_datetime_timestamp() {
- let to_timestamp =
- |y, m, d, h, n, s| NaiveDate::from_ymd(y, m, d).and_hms(h, n, s).timestamp();
- assert_eq!(to_timestamp(1969, 12, 31, 23, 59, 59), -1);
- assert_eq!(to_timestamp(1970, 1, 1, 0, 0, 0), 0);
- assert_eq!(to_timestamp(1970, 1, 1, 0, 0, 1), 1);
- assert_eq!(to_timestamp(2001, 9, 9, 1, 46, 40), 1_000_000_000);
- assert_eq!(to_timestamp(2038, 1, 19, 3, 14, 7), 0x7fffffff);
- }
-
- #[test]
- fn test_datetime_from_str() {
- // valid cases
- let valid = [
- "2015-2-18T23:16:9.15",
- "-77-02-18T23:16:09",
- " +82701 - 05 - 6 T 15 : 9 : 60.898989898989 ",
- ];
- for &s in &valid {
- let d = match s.parse::<NaiveDateTime>() {
- Ok(d) => d,
- Err(e) => panic!("parsing `{}` has failed: {}", s, e),
- };
- let s_ = format!("{:?}", d);
- // `s` and `s_` may differ, but `s.parse()` and `s_.parse()` must be same
- let d_ = match s_.parse::<NaiveDateTime>() {
- Ok(d) => d,
- Err(e) => {
- panic!("`{}` is parsed into `{:?}`, but reparsing that has failed: {}", s, d, e)
- }
- };
- assert!(
- d == d_,
- "`{}` is parsed into `{:?}`, but reparsed result \
- `{:?}` does not match",
- s,
- d,
- d_
- );
- }
-
- // some invalid cases
- // since `ParseErrorKind` is private, all we can do is to check if there was an error
- assert!("".parse::<NaiveDateTime>().is_err());
- assert!("x".parse::<NaiveDateTime>().is_err());
- assert!("15".parse::<NaiveDateTime>().is_err());
- assert!("15:8:9".parse::<NaiveDateTime>().is_err());
- assert!("15-8-9".parse::<NaiveDateTime>().is_err());
- assert!("2015-15-15T15:15:15".parse::<NaiveDateTime>().is_err());
- assert!("2012-12-12T12:12:12x".parse::<NaiveDateTime>().is_err());
- assert!("2012-123-12T12:12:12".parse::<NaiveDateTime>().is_err());
- assert!("+ 82701-123-12T12:12:12".parse::<NaiveDateTime>().is_err());
- assert!("+802701-123-12T12:12:12".parse::<NaiveDateTime>().is_err()); // out-of-bound
- }
-
- #[test]
- fn test_datetime_parse_from_str() {
- let ymdhms = |y, m, d, h, n, s| NaiveDate::from_ymd(y, m, d).and_hms(h, n, s);
- let ymdhmsn =
- |y, m, d, h, n, s, nano| NaiveDate::from_ymd(y, m, d).and_hms_nano(h, n, s, nano);
- assert_eq!(
- NaiveDateTime::parse_from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
- Ok(ymdhms(2014, 5, 7, 12, 34, 56))
- ); // ignore offset
- assert_eq!(
- NaiveDateTime::parse_from_str("2015-W06-1 000000", "%G-W%V-%u%H%M%S"),
- Ok(ymdhms(2015, 2, 2, 0, 0, 0))
- );
- assert_eq!(
- NaiveDateTime::parse_from_str(
- "Fri, 09 Aug 2013 23:54:35 GMT",
- "%a, %d %b %Y %H:%M:%S GMT"
- ),
- Ok(ymdhms(2013, 8, 9, 23, 54, 35))
- );
- assert!(NaiveDateTime::parse_from_str(
- "Sat, 09 Aug 2013 23:54:35 GMT",
- "%a, %d %b %Y %H:%M:%S GMT"
- )
- .is_err());
- assert!(NaiveDateTime::parse_from_str("2014-5-7 12:3456", "%Y-%m-%d %H:%M:%S").is_err());
- assert!(NaiveDateTime::parse_from_str("12:34:56", "%H:%M:%S").is_err()); // insufficient
- assert_eq!(
- NaiveDateTime::parse_from_str("1441497364", "%s"),
- Ok(ymdhms(2015, 9, 5, 23, 56, 4))
- );
- assert_eq!(
- NaiveDateTime::parse_from_str("1283929614.1234", "%s.%f"),
- Ok(ymdhmsn(2010, 9, 8, 7, 6, 54, 1234))
- );
- assert_eq!(
- NaiveDateTime::parse_from_str("1441497364.649", "%s%.3f"),
- Ok(ymdhmsn(2015, 9, 5, 23, 56, 4, 649000000))
- );
- assert_eq!(
- NaiveDateTime::parse_from_str("1497854303.087654", "%s%.6f"),
- Ok(ymdhmsn(2017, 6, 19, 6, 38, 23, 87654000))
- );
- assert_eq!(
- NaiveDateTime::parse_from_str("1437742189.918273645", "%s%.9f"),
- Ok(ymdhmsn(2015, 7, 24, 12, 49, 49, 918273645))
- );
- }
-
- #[test]
- fn test_datetime_format() {
- let dt = NaiveDate::from_ymd(2010, 9, 8).and_hms_milli(7, 6, 54, 321);
- assert_eq!(dt.format("%c").to_string(), "Wed Sep 8 07:06:54 2010");
- assert_eq!(dt.format("%s").to_string(), "1283929614");
- assert_eq!(dt.format("%t%n%%%n%t").to_string(), "\t\n%\n\t");
-
- // a horror of leap second: coming near to you.
- let dt = NaiveDate::from_ymd(2012, 6, 30).and_hms_milli(23, 59, 59, 1_000);
- assert_eq!(dt.format("%c").to_string(), "Sat Jun 30 23:59:60 2012");
- assert_eq!(dt.format("%s").to_string(), "1341100799"); // not 1341100800, it's intentional.
- }
-
- #[test]
- fn test_datetime_add_sub_invariant() {
- // issue #37
- let base = NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0);
- let t = -946684799990000;
- let time = base + Duration::microseconds(t);
- assert_eq!(t, time.signed_duration_since(base).num_microseconds().unwrap());
- }
-
- #[test]
- fn test_nanosecond_range() {
- const A_BILLION: i64 = 1_000_000_000;
- let maximum = "2262-04-11T23:47:16.854775804";
- let parsed: NaiveDateTime = maximum.parse().unwrap();
- let nanos = parsed.timestamp_nanos();
- assert_eq!(
- parsed,
- NaiveDateTime::from_timestamp(nanos / A_BILLION, (nanos % A_BILLION) as u32)
- );
-
- let minimum = "1677-09-21T00:12:44.000000000";
- let parsed: NaiveDateTime = minimum.parse().unwrap();
- let nanos = parsed.timestamp_nanos();
- assert_eq!(
- parsed,
- NaiveDateTime::from_timestamp(nanos / A_BILLION, (nanos % A_BILLION) as u32)
- );
- }
-}
diff --git a/vendor/chrono/src/naive/datetime/mod.rs b/vendor/chrono/src/naive/datetime/mod.rs
new file mode 100644
index 000000000..ec0d842c0
--- /dev/null
+++ b/vendor/chrono/src/naive/datetime/mod.rs
@@ -0,0 +1,1946 @@
+// This is a part of Chrono.
+// See README.md and LICENSE.txt for details.
+
+//! ISO 8601 date and time without timezone.
+
+#[cfg(any(feature = "alloc", feature = "std", test))]
+use core::borrow::Borrow;
+use core::convert::TryFrom;
+use core::fmt::Write;
+use core::ops::{Add, AddAssign, Sub, SubAssign};
+use core::{fmt, str};
+
+use num_integer::div_mod_floor;
+use num_traits::ToPrimitive;
+#[cfg(feature = "rkyv")]
+use rkyv::{Archive, Deserialize, Serialize};
+
+#[cfg(any(feature = "alloc", feature = "std", test))]
+use crate::format::DelayedFormat;
+use crate::format::{parse, ParseError, ParseResult, Parsed, StrftimeItems};
+use crate::format::{Fixed, Item, Numeric, Pad};
+use crate::naive::{Days, IsoWeek, NaiveDate, NaiveTime};
+use crate::oldtime::Duration as OldDuration;
+use crate::{DateTime, Datelike, LocalResult, Months, TimeZone, Timelike, Weekday};
+use core::cmp::Ordering;
+
+#[cfg(feature = "rustc-serialize")]
+pub(super) mod rustc_serialize;
+
+/// Tools to help serializing/deserializing `NaiveDateTime`s
+#[cfg(feature = "serde")]
+pub(crate) mod serde;
+
+#[cfg(test)]
+mod tests;
+
+/// The tight upper bound guarantees that a duration with `|Duration| >= 2^MAX_SECS_BITS`
+/// will always overflow the addition with any date and time type.
+///
+/// So why is this needed? `Duration::seconds(rhs)` may overflow, and we don't have
+/// an alternative returning `Option` or `Result`. Thus we need some early bound to avoid
+/// touching that call when we are already sure that it WILL overflow...
+const MAX_SECS_BITS: usize = 44;
+
+/// Number of nanoseconds in a millisecond
+const NANOS_IN_MILLISECOND: u32 = 1_000_000;
+/// Number of nanoseconds in a second
+const NANOS_IN_SECOND: u32 = 1000 * NANOS_IN_MILLISECOND;
+
+/// The minimum possible `NaiveDateTime`.
+#[deprecated(since = "0.4.20", note = "Use NaiveDateTime::MIN instead")]
+pub const MIN_DATETIME: NaiveDateTime = NaiveDateTime::MIN;
+/// The maximum possible `NaiveDateTime`.
+#[deprecated(since = "0.4.20", note = "Use NaiveDateTime::MAX instead")]
+pub const MAX_DATETIME: NaiveDateTime = NaiveDateTime::MAX;
+
+/// ISO 8601 combined date and time without timezone.
+///
+/// # Example
+///
+/// `NaiveDateTime` is commonly created from [`NaiveDate`](./struct.NaiveDate.html).
+///
+/// ```
+/// use chrono::{NaiveDate, NaiveDateTime};
+///
+/// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_opt(9, 10, 11).unwrap();
+/// # let _ = dt;
+/// ```
+///
+/// You can use typical [date-like](../trait.Datelike.html) and
+/// [time-like](../trait.Timelike.html) methods,
+/// provided that relevant traits are in the scope.
+///
+/// ```
+/// # use chrono::{NaiveDate, NaiveDateTime};
+/// # let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_opt(9, 10, 11).unwrap();
+/// use chrono::{Datelike, Timelike, Weekday};
+///
+/// assert_eq!(dt.weekday(), Weekday::Fri);
+/// assert_eq!(dt.num_seconds_from_midnight(), 33011);
+/// ```
+#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Copy, Clone)]
+#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
+#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
+pub struct NaiveDateTime {
+ date: NaiveDate,
+ time: NaiveTime,
+}
+
+/// The unit of a timestamp expressed in fractions of a second.
+/// Currently either milliseconds or microseconds.
+///
+/// This is a private type, used in the implementation of
+/// [NaiveDateTime::from_timestamp_millis] and [NaiveDateTime::from_timestamp_micros].
+#[derive(Clone, Copy, Debug)]
+enum TimestampUnit {
+ Millis,
+ Micros,
+}
+
+impl TimestampUnit {
+ fn per_second(self) -> u32 {
+ match self {
+ TimestampUnit::Millis => 1_000,
+ TimestampUnit::Micros => 1_000_000,
+ }
+ }
+ fn nanos_per(self) -> u32 {
+ match self {
+ TimestampUnit::Millis => 1_000_000,
+ TimestampUnit::Micros => 1_000,
+ }
+ }
+}
+
+impl NaiveDateTime {
+ /// Makes a new `NaiveDateTime` from date and time components.
+ /// Equivalent to [`date.and_time(time)`](./struct.NaiveDate.html#method.and_time)
+ /// and many other helper constructors on `NaiveDate`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveTime, NaiveDateTime};
+ ///
+ /// let d = NaiveDate::from_ymd_opt(2015, 6, 3).unwrap();
+ /// let t = NaiveTime::from_hms_milli_opt(12, 34, 56, 789).unwrap();
+ ///
+ /// let dt = NaiveDateTime::new(d, t);
+ /// assert_eq!(dt.date(), d);
+ /// assert_eq!(dt.time(), t);
+ /// ```
+ #[inline]
+ pub const fn new(date: NaiveDate, time: NaiveTime) -> NaiveDateTime {
+ NaiveDateTime { date, time }
+ }
+
+ /// Makes a new `NaiveDateTime` corresponding to a UTC date and time,
+ /// from the number of non-leap seconds
+ /// since the midnight UTC on January 1, 1970 (aka "UNIX timestamp")
+ /// and the number of nanoseconds since the last whole non-leap second.
+ ///
+ /// For a non-naive version of this function see
+ /// [`TimeZone::timestamp`](../offset/trait.TimeZone.html#method.timestamp).
+ ///
+ /// The nanosecond part can exceed 1,000,000,000 in order to represent the
+ /// [leap second](./struct.NaiveTime.html#leap-second-handling). (The true "UNIX
+ /// timestamp" cannot represent a leap second unambiguously.)
+ ///
+ /// Panics on the out-of-range number of seconds and/or invalid nanosecond.
+ #[deprecated(since = "0.4.23", note = "use `from_timestamp_opt()` instead")]
+ #[inline]
+ pub fn from_timestamp(secs: i64, nsecs: u32) -> NaiveDateTime {
+ let datetime = NaiveDateTime::from_timestamp_opt(secs, nsecs);
+ datetime.expect("invalid or out-of-range datetime")
+ }
+
+ /// Creates a new [NaiveDateTime] from milliseconds since the UNIX epoch.
+ ///
+ /// The UNIX epoch starts on midnight, January 1, 1970, UTC.
+ ///
+ /// Returns `None` on an out-of-range number of milliseconds.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::NaiveDateTime;
+ /// let timestamp_millis: i64 = 1662921288000; //Sunday, September 11, 2022 6:34:48 PM
+ /// let naive_datetime = NaiveDateTime::from_timestamp_millis(timestamp_millis);
+ /// assert!(naive_datetime.is_some());
+ /// assert_eq!(timestamp_millis, naive_datetime.unwrap().timestamp_millis());
+ ///
+ /// // Negative timestamps (before the UNIX epoch) are supported as well.
+ /// let timestamp_millis: i64 = -2208936075000; //Mon Jan 01 1900 14:38:45 GMT+0000
+ /// let naive_datetime = NaiveDateTime::from_timestamp_millis(timestamp_millis);
+ /// assert!(naive_datetime.is_some());
+ /// assert_eq!(timestamp_millis, naive_datetime.unwrap().timestamp_millis());
+ /// ```
+ #[inline]
+ pub fn from_timestamp_millis(millis: i64) -> Option<NaiveDateTime> {
+ Self::from_timestamp_unit(millis, TimestampUnit::Millis)
+ }
+
+ /// Creates a new [NaiveDateTime] from microseconds since the UNIX epoch.
+ ///
+ /// The UNIX epoch starts on midnight, January 1, 1970, UTC.
+ ///
+ /// Returns `None` on an out-of-range number of microseconds.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::NaiveDateTime;
+ /// let timestamp_micros: i64 = 1662921288000000; //Sunday, September 11, 2022 6:34:48 PM
+ /// let naive_datetime = NaiveDateTime::from_timestamp_micros(timestamp_micros);
+ /// assert!(naive_datetime.is_some());
+ /// assert_eq!(timestamp_micros, naive_datetime.unwrap().timestamp_micros());
+ ///
+ /// // Negative timestamps (before the UNIX epoch) are supported as well.
+ /// let timestamp_micros: i64 = -2208936075000000; //Mon Jan 01 1900 14:38:45 GMT+0000
+ /// let naive_datetime = NaiveDateTime::from_timestamp_micros(timestamp_micros);
+ /// assert!(naive_datetime.is_some());
+ /// assert_eq!(timestamp_micros, naive_datetime.unwrap().timestamp_micros());
+ /// ```
+ #[inline]
+ pub fn from_timestamp_micros(micros: i64) -> Option<NaiveDateTime> {
+ Self::from_timestamp_unit(micros, TimestampUnit::Micros)
+ }
+
+ /// Makes a new `NaiveDateTime` corresponding to a UTC date and time,
+ /// from the number of non-leap seconds
+ /// since the midnight UTC on January 1, 1970 (aka "UNIX timestamp")
+ /// and the number of nanoseconds since the last whole non-leap second.
+ ///
+ /// The nanosecond part can exceed 1,000,000,000
+ /// in order to represent the [leap second](./struct.NaiveTime.html#leap-second-handling).
+ /// (The true "UNIX timestamp" cannot represent a leap second unambiguously.)
+ ///
+ /// Returns `None` on the out-of-range number of seconds (more than 262 000 years away
+ /// from common era) and/or invalid nanosecond (2 seconds or more).
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDateTime, NaiveDate};
+ /// use std::i64;
+ ///
+ /// let from_timestamp_opt = NaiveDateTime::from_timestamp_opt;
+ ///
+ /// assert!(from_timestamp_opt(0, 0).is_some());
+ /// assert!(from_timestamp_opt(0, 999_999_999).is_some());
+ /// assert!(from_timestamp_opt(0, 1_500_000_000).is_some()); // leap second
+ /// assert!(from_timestamp_opt(0, 2_000_000_000).is_none());
+ /// assert!(from_timestamp_opt(i64::MAX, 0).is_none());
+ /// ```
+ #[inline]
+ pub fn from_timestamp_opt(secs: i64, nsecs: u32) -> Option<NaiveDateTime> {
+ let (days, secs) = div_mod_floor(secs, 86_400);
+ let date = days
+ .to_i32()
+ .and_then(|days| days.checked_add(719_163))
+ .and_then(NaiveDate::from_num_days_from_ce_opt);
+ let time = NaiveTime::from_num_seconds_from_midnight_opt(secs as u32, nsecs);
+ match (date, time) {
+ (Some(date), Some(time)) => Some(NaiveDateTime { date, time }),
+ (_, _) => None,
+ }
+ }
+
+ /// Parses a string with the specified format string and returns a new `NaiveDateTime`.
+ /// See the [`format::strftime` module](../format/strftime/index.html)
+ /// on the supported escape sequences.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDateTime, NaiveDate};
+ ///
+ /// let parse_from_str = NaiveDateTime::parse_from_str;
+ ///
+ /// assert_eq!(parse_from_str("2015-09-05 23:56:04", "%Y-%m-%d %H:%M:%S"),
+ /// Ok(NaiveDate::from_ymd_opt(2015, 9, 5).unwrap().and_hms_opt(23, 56, 4).unwrap()));
+ /// assert_eq!(parse_from_str("5sep2015pm012345.6789", "%d%b%Y%p%I%M%S%.f"),
+ /// Ok(NaiveDate::from_ymd_opt(2015, 9, 5).unwrap().and_hms_micro_opt(13, 23, 45, 678_900).unwrap()));
+ /// ```
+ ///
+ /// Offset is ignored for the purpose of parsing.
+ ///
+ /// ```
+ /// # use chrono::{NaiveDateTime, NaiveDate};
+ /// # let parse_from_str = NaiveDateTime::parse_from_str;
+ /// assert_eq!(parse_from_str("2014-5-17T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
+ /// Ok(NaiveDate::from_ymd_opt(2014, 5, 17).unwrap().and_hms_opt(12, 34, 56).unwrap()));
+ /// ```
+ ///
+ /// [Leap seconds](./struct.NaiveTime.html#leap-second-handling) are correctly handled by
+ /// treating any time of the form `hh:mm:60` as a leap second.
+ /// (This equally applies to the formatting, so the round trip is possible.)
+ ///
+ /// ```
+ /// # use chrono::{NaiveDateTime, NaiveDate};
+ /// # let parse_from_str = NaiveDateTime::parse_from_str;
+ /// assert_eq!(parse_from_str("2015-07-01 08:59:60.123", "%Y-%m-%d %H:%M:%S%.f"),
+ /// Ok(NaiveDate::from_ymd_opt(2015, 7, 1).unwrap().and_hms_milli_opt(8, 59, 59, 1_123).unwrap()));
+ /// ```
+ ///
+ /// Missing seconds are assumed to be zero,
+ /// but out-of-bound times or insufficient fields are errors otherwise.
+ ///
+ /// ```
+ /// # use chrono::{NaiveDateTime, NaiveDate};
+ /// # let parse_from_str = NaiveDateTime::parse_from_str;
+ /// assert_eq!(parse_from_str("94/9/4 7:15", "%y/%m/%d %H:%M"),
+ /// Ok(NaiveDate::from_ymd_opt(1994, 9, 4).unwrap().and_hms_opt(7, 15, 0).unwrap()));
+ ///
+ /// assert!(parse_from_str("04m33s", "%Mm%Ss").is_err());
+ /// assert!(parse_from_str("94/9/4 12", "%y/%m/%d %H").is_err());
+ /// assert!(parse_from_str("94/9/4 17:60", "%y/%m/%d %H:%M").is_err());
+ /// assert!(parse_from_str("94/9/4 24:00:00", "%y/%m/%d %H:%M:%S").is_err());
+ /// ```
+ ///
+ /// All parsed fields should be consistent to each other, otherwise it's an error.
+ ///
+ /// ```
+ /// # use chrono::NaiveDateTime;
+ /// # let parse_from_str = NaiveDateTime::parse_from_str;
+ /// let fmt = "%Y-%m-%d %H:%M:%S = UNIX timestamp %s";
+ /// assert!(parse_from_str("2001-09-09 01:46:39 = UNIX timestamp 999999999", fmt).is_ok());
+ /// assert!(parse_from_str("1970-01-01 00:00:00 = UNIX timestamp 1", fmt).is_err());
+ /// ```
+ ///
+ /// Years before 1 BCE or after 9999 CE, require an initial sign
+ ///
+ ///```
+ /// # use chrono::{NaiveDate, NaiveDateTime};
+ /// # let parse_from_str = NaiveDateTime::parse_from_str;
+ /// let fmt = "%Y-%m-%d %H:%M:%S";
+ /// assert!(parse_from_str("10000-09-09 01:46:39", fmt).is_err());
+ /// assert!(parse_from_str("+10000-09-09 01:46:39", fmt).is_ok());
+ ///```
+ pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveDateTime> {
+ let mut parsed = Parsed::new();
+ parse(&mut parsed, s, StrftimeItems::new(fmt))?;
+ parsed.to_naive_datetime_with_offset(0) // no offset adjustment
+ }
+
+ /// Retrieves a date component.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::NaiveDate;
+ ///
+ /// let dt = NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_opt(9, 10, 11).unwrap();
+ /// assert_eq!(dt.date(), NaiveDate::from_ymd_opt(2016, 7, 8).unwrap());
+ /// ```
+ #[inline]
+ pub const fn date(&self) -> NaiveDate {
+ self.date
+ }
+
+ /// Retrieves a time component.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveTime};
+ ///
+ /// let dt = NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_opt(9, 10, 11).unwrap();
+ /// assert_eq!(dt.time(), NaiveTime::from_hms_opt(9, 10, 11).unwrap());
+ /// ```
+ #[inline]
+ pub const fn time(&self) -> NaiveTime {
+ self.time
+ }
+
+ /// Returns the number of non-leap seconds since the midnight on January 1, 1970.
+ ///
+ /// Note that this does *not* account for the timezone!
+ /// The true "UNIX timestamp" would count seconds since the midnight *UTC* on the epoch.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::NaiveDate;
+ ///
+ /// let dt = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap().and_hms_milli_opt(0, 0, 1, 980).unwrap();
+ /// assert_eq!(dt.timestamp(), 1);
+ ///
+ /// let dt = NaiveDate::from_ymd_opt(2001, 9, 9).unwrap().and_hms_opt(1, 46, 40).unwrap();
+ /// assert_eq!(dt.timestamp(), 1_000_000_000);
+ ///
+ /// let dt = NaiveDate::from_ymd_opt(1969, 12, 31).unwrap().and_hms_opt(23, 59, 59).unwrap();
+ /// assert_eq!(dt.timestamp(), -1);
+ ///
+ /// let dt = NaiveDate::from_ymd_opt(-1, 1, 1).unwrap().and_hms_opt(0, 0, 0).unwrap();
+ /// assert_eq!(dt.timestamp(), -62198755200);
+ /// ```
+ #[inline]
+ pub fn timestamp(&self) -> i64 {
+ const UNIX_EPOCH_DAY: i64 = 719_163;
+ let gregorian_day = i64::from(self.date.num_days_from_ce());
+ let seconds_from_midnight = i64::from(self.time.num_seconds_from_midnight());
+ (gregorian_day - UNIX_EPOCH_DAY) * 86_400 + seconds_from_midnight
+ }
+
+ /// Returns the number of non-leap *milliseconds* since midnight on January 1, 1970.
+ ///
+ /// Note that this does *not* account for the timezone!
+ /// The true "UNIX timestamp" would count seconds since the midnight *UTC* on the epoch.
+ ///
+ /// Note also that this does reduce the number of years that can be
+ /// represented from ~584 Billion to ~584 Million. (If this is a problem,
+ /// please file an issue to let me know what domain needs millisecond
+ /// precision over billions of years, I'm curious.)
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::NaiveDate;
+ ///
+ /// let dt = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap().and_hms_milli_opt(0, 0, 1, 444).unwrap();
+ /// assert_eq!(dt.timestamp_millis(), 1_444);
+ ///
+ /// let dt = NaiveDate::from_ymd_opt(2001, 9, 9).unwrap().and_hms_milli_opt(1, 46, 40, 555).unwrap();
+ /// assert_eq!(dt.timestamp_millis(), 1_000_000_000_555);
+ ///
+ /// let dt = NaiveDate::from_ymd_opt(1969, 12, 31).unwrap().and_hms_milli_opt(23, 59, 59, 100).unwrap();
+ /// assert_eq!(dt.timestamp_millis(), -900);
+ /// ```
+ #[inline]
+ pub fn timestamp_millis(&self) -> i64 {
+ let as_ms = self.timestamp() * 1000;
+ as_ms + i64::from(self.timestamp_subsec_millis())
+ }
+
+ /// Returns the number of non-leap *microseconds* since midnight on January 1, 1970.
+ ///
+ /// Note that this does *not* account for the timezone!
+ /// The true "UNIX timestamp" would count seconds since the midnight *UTC* on the epoch.
+ ///
+ /// Note also that this does reduce the number of years that can be
+ /// represented from ~584 Billion to ~584 Thousand. (If this is a problem,
+ /// please file an issue to let me know what domain needs microsecond
+ /// precision over millennia, I'm curious.)
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::NaiveDate;
+ ///
+ /// let dt = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap().and_hms_micro_opt(0, 0, 1, 444).unwrap();
+ /// assert_eq!(dt.timestamp_micros(), 1_000_444);
+ ///
+ /// let dt = NaiveDate::from_ymd_opt(2001, 9, 9).unwrap().and_hms_micro_opt(1, 46, 40, 555).unwrap();
+ /// assert_eq!(dt.timestamp_micros(), 1_000_000_000_000_555);
+ /// ```
+ #[inline]
+ pub fn timestamp_micros(&self) -> i64 {
+ let as_us = self.timestamp() * 1_000_000;
+ as_us + i64::from(self.timestamp_subsec_micros())
+ }
+
+ /// Returns the number of non-leap *nanoseconds* since midnight on January 1, 1970.
+ ///
+ /// Note that this does *not* account for the timezone!
+ /// The true "UNIX timestamp" would count seconds since the midnight *UTC* on the epoch.
+ ///
+ /// # Panics
+ ///
+ /// Note also that this does reduce the number of years that can be
+ /// represented from ~584 Billion to ~584 years. The dates that can be
+ /// represented as nanoseconds are between 1677-09-21T00:12:44.0 and
+ /// 2262-04-11T23:47:16.854775804.
+ ///
+ /// (If this is a problem, please file an issue to let me know what domain
+ /// needs nanosecond precision over millennia, I'm curious.)
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime};
+ ///
+ /// let dt = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap().and_hms_nano_opt(0, 0, 1, 444).unwrap();
+ /// assert_eq!(dt.timestamp_nanos(), 1_000_000_444);
+ ///
+ /// let dt = NaiveDate::from_ymd_opt(2001, 9, 9).unwrap().and_hms_nano_opt(1, 46, 40, 555).unwrap();
+ ///
+ /// const A_BILLION: i64 = 1_000_000_000;
+ /// let nanos = dt.timestamp_nanos();
+ /// assert_eq!(nanos, 1_000_000_000_000_000_555);
+ /// assert_eq!(
+ /// dt,
+ /// NaiveDateTime::from_timestamp(nanos / A_BILLION, (nanos % A_BILLION) as u32)
+ /// );
+ /// ```
+ #[inline]
+ pub fn timestamp_nanos(&self) -> i64 {
+ let as_ns = self.timestamp() * 1_000_000_000;
+ as_ns + i64::from(self.timestamp_subsec_nanos())
+ }
+
+ /// Returns the number of milliseconds since the last whole non-leap second.
+ ///
+ /// The return value ranges from 0 to 999,
+ /// or for [leap seconds](./struct.NaiveTime.html#leap-second-handling), to 1,999.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::NaiveDate;
+ ///
+ /// let dt = NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_nano_opt(9, 10, 11, 123_456_789).unwrap();
+ /// assert_eq!(dt.timestamp_subsec_millis(), 123);
+ ///
+ /// let dt = NaiveDate::from_ymd_opt(2015, 7, 1).unwrap().and_hms_nano_opt(8, 59, 59, 1_234_567_890).unwrap();
+ /// assert_eq!(dt.timestamp_subsec_millis(), 1_234);
+ /// ```
+ #[inline]
+ pub fn timestamp_subsec_millis(&self) -> u32 {
+ self.timestamp_subsec_nanos() / 1_000_000
+ }
+
+ /// Returns the number of microseconds since the last whole non-leap second.
+ ///
+ /// The return value ranges from 0 to 999,999,
+ /// or for [leap seconds](./struct.NaiveTime.html#leap-second-handling), to 1,999,999.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::NaiveDate;
+ ///
+ /// let dt = NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_nano_opt(9, 10, 11, 123_456_789).unwrap();
+ /// assert_eq!(dt.timestamp_subsec_micros(), 123_456);
+ ///
+ /// let dt = NaiveDate::from_ymd_opt(2015, 7, 1).unwrap().and_hms_nano_opt(8, 59, 59, 1_234_567_890).unwrap();
+ /// assert_eq!(dt.timestamp_subsec_micros(), 1_234_567);
+ /// ```
+ #[inline]
+ pub fn timestamp_subsec_micros(&self) -> u32 {
+ self.timestamp_subsec_nanos() / 1_000
+ }
+
+ /// Returns the number of nanoseconds since the last whole non-leap second.
+ ///
+ /// The return value ranges from 0 to 999,999,999,
+ /// or for [leap seconds](./struct.NaiveTime.html#leap-second-handling), to 1,999,999,999.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::NaiveDate;
+ ///
+ /// let dt = NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_nano_opt(9, 10, 11, 123_456_789).unwrap();
+ /// assert_eq!(dt.timestamp_subsec_nanos(), 123_456_789);
+ ///
+ /// let dt = NaiveDate::from_ymd_opt(2015, 7, 1).unwrap().and_hms_nano_opt(8, 59, 59, 1_234_567_890).unwrap();
+ /// assert_eq!(dt.timestamp_subsec_nanos(), 1_234_567_890);
+ /// ```
+ #[inline]
+ pub fn timestamp_subsec_nanos(&self) -> u32 {
+ self.time.nanosecond()
+ }
+
+ /// Adds given `Duration` to the current date and time.
+ ///
+ /// As a part of Chrono's [leap second handling](./struct.NaiveTime.html#leap-second-handling),
+ /// the addition assumes that **there is no leap second ever**,
+ /// except when the `NaiveDateTime` itself represents a leap second
+ /// in which case the assumption becomes that **there is exactly a single leap second ever**.
+ ///
+ /// Returns `None` when it will result in overflow.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{Duration, NaiveDate};
+ ///
+ /// let from_ymd = NaiveDate::from_ymd;
+ ///
+ /// let d = from_ymd(2016, 7, 8);
+ /// let hms = |h, m, s| d.and_hms_opt(h, m, s).unwrap();
+ /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::zero()),
+ /// Some(hms(3, 5, 7)));
+ /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::seconds(1)),
+ /// Some(hms(3, 5, 8)));
+ /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::seconds(-1)),
+ /// Some(hms(3, 5, 6)));
+ /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::seconds(3600 + 60)),
+ /// Some(hms(4, 6, 7)));
+ /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::seconds(86_400)),
+ /// Some(from_ymd(2016, 7, 9).and_hms_opt(3, 5, 7).unwrap()));
+ ///
+ /// let hmsm = |h, m, s, milli| d.and_hms_milli_opt(h, m, s, milli).unwrap();
+ /// assert_eq!(hmsm(3, 5, 7, 980).checked_add_signed(Duration::milliseconds(450)),
+ /// Some(hmsm(3, 5, 8, 430)));
+ /// ```
+ ///
+ /// Overflow returns `None`.
+ ///
+ /// ```
+ /// # use chrono::{Duration, NaiveDate};
+ /// # let hms = |h, m, s| NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_opt(h, m, s).unwrap();
+ /// assert_eq!(hms(3, 5, 7).checked_add_signed(Duration::days(1_000_000_000)), None);
+ /// ```
+ ///
+ /// Leap seconds are handled,
+ /// but the addition assumes that it is the only leap second happened.
+ ///
+ /// ```
+ /// # use chrono::{Duration, NaiveDate};
+ /// # let from_ymd = NaiveDate::from_ymd;
+ /// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli_opt(h, m, s, milli).unwrap();
+ /// let leap = hmsm(3, 5, 59, 1_300);
+ /// assert_eq!(leap.checked_add_signed(Duration::zero()),
+ /// Some(hmsm(3, 5, 59, 1_300)));
+ /// assert_eq!(leap.checked_add_signed(Duration::milliseconds(-500)),
+ /// Some(hmsm(3, 5, 59, 800)));
+ /// assert_eq!(leap.checked_add_signed(Duration::milliseconds(500)),
+ /// Some(hmsm(3, 5, 59, 1_800)));
+ /// assert_eq!(leap.checked_add_signed(Duration::milliseconds(800)),
+ /// Some(hmsm(3, 6, 0, 100)));
+ /// assert_eq!(leap.checked_add_signed(Duration::seconds(10)),
+ /// Some(hmsm(3, 6, 9, 300)));
+ /// assert_eq!(leap.checked_add_signed(Duration::seconds(-10)),
+ /// Some(hmsm(3, 5, 50, 300)));
+ /// assert_eq!(leap.checked_add_signed(Duration::days(1)),
+ /// Some(from_ymd(2016, 7, 9).and_hms_milli_opt(3, 5, 59, 300).unwrap()));
+ /// ```
+ pub fn checked_add_signed(self, rhs: OldDuration) -> Option<NaiveDateTime> {
+ let (time, rhs) = self.time.overflowing_add_signed(rhs);
+
+ // early checking to avoid overflow in OldDuration::seconds
+ if rhs <= (-1 << MAX_SECS_BITS) || rhs >= (1 << MAX_SECS_BITS) {
+ return None;
+ }
+
+ let date = self.date.checked_add_signed(OldDuration::seconds(rhs))?;
+ Some(NaiveDateTime { date, time })
+ }
+
+ /// Adds given `Months` to the current date and time.
+ ///
+ /// Returns `None` when it will result in overflow.
+ ///
+ /// Overflow returns `None`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::str::FromStr;
+ /// use chrono::{Months, NaiveDate, NaiveDateTime};
+ ///
+ /// assert_eq!(
+ /// NaiveDate::from_ymd_opt(2014, 1, 1).unwrap().and_hms_opt(1, 0, 0).unwrap()
+ /// .checked_add_months(Months::new(1)),
+ /// Some(NaiveDate::from_ymd_opt(2014, 2, 1).unwrap().and_hms_opt(1, 0, 0).unwrap())
+ /// );
+ ///
+ /// assert_eq!(
+ /// NaiveDate::from_ymd_opt(2014, 1, 1).unwrap().and_hms_opt(1, 0, 0).unwrap()
+ /// .checked_add_months(Months::new(core::i32::MAX as u32 + 1)),
+ /// None
+ /// );
+ /// ```
+ pub fn checked_add_months(self, rhs: Months) -> Option<NaiveDateTime> {
+ Some(Self { date: self.date.checked_add_months(rhs)?, time: self.time })
+ }
+
+ /// Subtracts given `Duration` from the current date and time.
+ ///
+ /// As a part of Chrono's [leap second handling](./struct.NaiveTime.html#leap-second-handling),
+ /// the subtraction assumes that **there is no leap second ever**,
+ /// except when the `NaiveDateTime` itself represents a leap second
+ /// in which case the assumption becomes that **there is exactly a single leap second ever**.
+ ///
+ /// Returns `None` when it will result in overflow.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{Duration, NaiveDate};
+ ///
+ /// let from_ymd = NaiveDate::from_ymd;
+ ///
+ /// let d = from_ymd(2016, 7, 8);
+ /// let hms = |h, m, s| d.and_hms_opt(h, m, s).unwrap();
+ /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::zero()),
+ /// Some(hms(3, 5, 7)));
+ /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::seconds(1)),
+ /// Some(hms(3, 5, 6)));
+ /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::seconds(-1)),
+ /// Some(hms(3, 5, 8)));
+ /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::seconds(3600 + 60)),
+ /// Some(hms(2, 4, 7)));
+ /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::seconds(86_400)),
+ /// Some(from_ymd(2016, 7, 7).and_hms_opt(3, 5, 7).unwrap()));
+ ///
+ /// let hmsm = |h, m, s, milli| d.and_hms_milli_opt(h, m, s, milli).unwrap();
+ /// assert_eq!(hmsm(3, 5, 7, 450).checked_sub_signed(Duration::milliseconds(670)),
+ /// Some(hmsm(3, 5, 6, 780)));
+ /// ```
+ ///
+ /// Overflow returns `None`.
+ ///
+ /// ```
+ /// # use chrono::{Duration, NaiveDate};
+ /// # let hms = |h, m, s| NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_opt(h, m, s).unwrap();
+ /// assert_eq!(hms(3, 5, 7).checked_sub_signed(Duration::days(1_000_000_000)), None);
+ /// ```
+ ///
+ /// Leap seconds are handled,
+ /// but the subtraction assumes that it is the only leap second happened.
+ ///
+ /// ```
+ /// # use chrono::{Duration, NaiveDate};
+ /// # let from_ymd = NaiveDate::from_ymd;
+ /// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli_opt(h, m, s, milli).unwrap();
+ /// let leap = hmsm(3, 5, 59, 1_300);
+ /// assert_eq!(leap.checked_sub_signed(Duration::zero()),
+ /// Some(hmsm(3, 5, 59, 1_300)));
+ /// assert_eq!(leap.checked_sub_signed(Duration::milliseconds(200)),
+ /// Some(hmsm(3, 5, 59, 1_100)));
+ /// assert_eq!(leap.checked_sub_signed(Duration::milliseconds(500)),
+ /// Some(hmsm(3, 5, 59, 800)));
+ /// assert_eq!(leap.checked_sub_signed(Duration::seconds(60)),
+ /// Some(hmsm(3, 5, 0, 300)));
+ /// assert_eq!(leap.checked_sub_signed(Duration::days(1)),
+ /// Some(from_ymd(2016, 7, 7).and_hms_milli_opt(3, 6, 0, 300).unwrap()));
+ /// ```
+ pub fn checked_sub_signed(self, rhs: OldDuration) -> Option<NaiveDateTime> {
+ let (time, rhs) = self.time.overflowing_sub_signed(rhs);
+
+ // early checking to avoid overflow in OldDuration::seconds
+ if rhs <= (-1 << MAX_SECS_BITS) || rhs >= (1 << MAX_SECS_BITS) {
+ return None;
+ }
+
+ let date = self.date.checked_sub_signed(OldDuration::seconds(rhs))?;
+ Some(NaiveDateTime { date, time })
+ }
+
+ /// Subtracts given `Months` from the current date and time.
+ ///
+ /// Returns `None` when it will result in overflow.
+ ///
+ /// Overflow returns `None`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use std::str::FromStr;
+ /// use chrono::{Months, NaiveDate, NaiveDateTime};
+ ///
+ /// assert_eq!(
+ /// NaiveDate::from_ymd_opt(2014, 1, 1).unwrap().and_hms_opt(1, 0, 0).unwrap()
+ /// .checked_sub_months(Months::new(1)),
+ /// Some(NaiveDate::from_ymd_opt(2013, 12, 1).unwrap().and_hms_opt(1, 0, 0).unwrap())
+ /// );
+ ///
+ /// assert_eq!(
+ /// NaiveDate::from_ymd_opt(2014, 1, 1).unwrap().and_hms_opt(1, 0, 0).unwrap()
+ /// .checked_sub_months(Months::new(core::i32::MAX as u32 + 1)),
+ /// None
+ /// );
+ /// ```
+ pub fn checked_sub_months(self, rhs: Months) -> Option<NaiveDateTime> {
+ Some(Self { date: self.date.checked_sub_months(rhs)?, time: self.time })
+ }
+
+ /// Add a duration in [`Days`] to the date part of the `NaiveDateTime`
+ ///
+ /// Returns `None` if the resulting date would be out of range.
+ pub fn checked_add_days(self, days: Days) -> Option<Self> {
+ Some(Self { date: self.date.checked_add_days(days)?, ..self })
+ }
+
+ /// Subtract a duration in [`Days`] from the date part of the `NaiveDateTime`
+ ///
+ /// Returns `None` if the resulting date would be out of range.
+ pub fn checked_sub_days(self, days: Days) -> Option<Self> {
+ Some(Self { date: self.date.checked_sub_days(days)?, ..self })
+ }
+
+ /// Subtracts another `NaiveDateTime` from the current date and time.
+ /// This does not overflow or underflow at all.
+ ///
+ /// As a part of Chrono's [leap second handling](./struct.NaiveTime.html#leap-second-handling),
+ /// the subtraction assumes that **there is no leap second ever**,
+ /// except when any of the `NaiveDateTime`s themselves represents a leap second
+ /// in which case the assumption becomes that
+ /// **there are exactly one (or two) leap second(s) ever**.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{Duration, NaiveDate};
+ ///
+ /// let from_ymd = NaiveDate::from_ymd;
+ ///
+ /// let d = from_ymd(2016, 7, 8);
+ /// assert_eq!(d.and_hms_opt(3, 5, 7).unwrap().signed_duration_since(d.and_hms_opt(2, 4, 6).unwrap()),
+ /// Duration::seconds(3600 + 60 + 1));
+ ///
+ /// // July 8 is 190th day in the year 2016
+ /// let d0 = from_ymd(2016, 1, 1);
+ /// assert_eq!(d.and_hms_milli_opt(0, 7, 6, 500).unwrap().signed_duration_since(d0.and_hms_opt(0, 0, 0).unwrap()),
+ /// Duration::seconds(189 * 86_400 + 7 * 60 + 6) + Duration::milliseconds(500));
+ /// ```
+ ///
+ /// Leap seconds are handled, but the subtraction assumes that
+ /// there were no other leap seconds happened.
+ ///
+ /// ```
+ /// # use chrono::{Duration, NaiveDate};
+ /// # let from_ymd = NaiveDate::from_ymd;
+ /// let leap = from_ymd(2015, 6, 30).and_hms_milli_opt(23, 59, 59, 1_500).unwrap();
+ /// assert_eq!(leap.signed_duration_since(from_ymd(2015, 6, 30).and_hms_opt(23, 0, 0).unwrap()),
+ /// Duration::seconds(3600) + Duration::milliseconds(500));
+ /// assert_eq!(from_ymd(2015, 7, 1).and_hms_opt(1, 0, 0).unwrap().signed_duration_since(leap),
+ /// Duration::seconds(3600) - Duration::milliseconds(500));
+ /// ```
+ pub fn signed_duration_since(self, rhs: NaiveDateTime) -> OldDuration {
+ self.date.signed_duration_since(rhs.date) + self.time.signed_duration_since(rhs.time)
+ }
+
+ /// Formats the combined date and time with the specified formatting items.
+ /// Otherwise it is the same as the ordinary [`format`](#method.format) method.
+ ///
+ /// The `Iterator` of items should be `Clone`able,
+ /// since the resulting `DelayedFormat` value may be formatted multiple times.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::NaiveDate;
+ /// use chrono::format::strftime::StrftimeItems;
+ ///
+ /// let fmt = StrftimeItems::new("%Y-%m-%d %H:%M:%S");
+ /// let dt = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap().and_hms_opt(23, 56, 4).unwrap();
+ /// assert_eq!(dt.format_with_items(fmt.clone()).to_string(), "2015-09-05 23:56:04");
+ /// assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2015-09-05 23:56:04");
+ /// ```
+ ///
+ /// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
+ ///
+ /// ```
+ /// # use chrono::NaiveDate;
+ /// # use chrono::format::strftime::StrftimeItems;
+ /// # let fmt = StrftimeItems::new("%Y-%m-%d %H:%M:%S").clone();
+ /// # let dt = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap().and_hms_opt(23, 56, 4).unwrap();
+ /// assert_eq!(format!("{}", dt.format_with_items(fmt)), "2015-09-05 23:56:04");
+ /// ```
+ #[cfg(any(feature = "alloc", feature = "std", test))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
+ #[inline]
+ pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat<I>
+ where
+ I: Iterator<Item = B> + Clone,
+ B: Borrow<Item<'a>>,
+ {
+ DelayedFormat::new(Some(self.date), Some(self.time), items)
+ }
+
+ /// Formats the combined date and time with the specified format string.
+ /// See the [`format::strftime` module](../format/strftime/index.html)
+ /// on the supported escape sequences.
+ ///
+ /// This returns a `DelayedFormat`,
+ /// which gets converted to a string only when actual formatting happens.
+ /// You may use the `to_string` method to get a `String`,
+ /// or just feed it into `print!` and other formatting macros.
+ /// (In this way it avoids the redundant memory allocation.)
+ ///
+ /// A wrong format string does *not* issue an error immediately.
+ /// Rather, converting or formatting the `DelayedFormat` fails.
+ /// You are recommended to immediately use `DelayedFormat` for this reason.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::NaiveDate;
+ ///
+ /// let dt = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap().and_hms_opt(23, 56, 4).unwrap();
+ /// assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2015-09-05 23:56:04");
+ /// assert_eq!(dt.format("around %l %p on %b %-d").to_string(), "around 11 PM on Sep 5");
+ /// ```
+ ///
+ /// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
+ ///
+ /// ```
+ /// # use chrono::NaiveDate;
+ /// # let dt = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap().and_hms_opt(23, 56, 4).unwrap();
+ /// assert_eq!(format!("{}", dt.format("%Y-%m-%d %H:%M:%S")), "2015-09-05 23:56:04");
+ /// assert_eq!(format!("{}", dt.format("around %l %p on %b %-d")), "around 11 PM on Sep 5");
+ /// ```
+ #[cfg(any(feature = "alloc", feature = "std", test))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
+ #[inline]
+ pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>> {
+ self.format_with_items(StrftimeItems::new(fmt))
+ }
+
+ /// Converts the `NaiveDateTime` into the timezone-aware `DateTime<Tz>`
+ /// with the provided timezone, if possible.
+ ///
+ /// This can fail in cases where the local time represented by the `NaiveDateTime`
+ /// is not a valid local timestamp in the target timezone due to an offset transition
+ /// for example if the target timezone had a change from +00:00 to +01:00
+ /// occuring at 2015-09-05 22:59:59, then a local time of 2015-09-05 23:56:04
+ /// could never occur. Similarly, if the offset transitioned in the opposite direction
+ /// then there would be two local times of 2015-09-05 23:56:04, one at +00:00 and one
+ /// at +01:00.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, Utc};
+ /// let dt = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap().and_hms_opt(23, 56, 4).unwrap().and_local_timezone(Utc).unwrap();
+ /// assert_eq!(dt.timezone(), Utc);
+ pub fn and_local_timezone<Tz: TimeZone>(&self, tz: Tz) -> LocalResult<DateTime<Tz>> {
+ tz.from_local_datetime(self)
+ }
+
+ /// The minimum possible `NaiveDateTime`.
+ pub const MIN: Self = Self { date: NaiveDate::MIN, time: NaiveTime::MIN };
+ /// The maximum possible `NaiveDateTime`.
+ pub const MAX: Self = Self { date: NaiveDate::MAX, time: NaiveTime::MAX };
+
+ /// Creates a new [NaiveDateTime] from milliseconds or microseconds since the UNIX epoch.
+ ///
+ /// This is a private function used by [from_timestamp_millis] and [from_timestamp_micros].
+ #[inline]
+ fn from_timestamp_unit(value: i64, unit: TimestampUnit) -> Option<NaiveDateTime> {
+ let (secs, subsecs) =
+ (value / i64::from(unit.per_second()), value % i64::from(unit.per_second()));
+
+ match subsecs.cmp(&0) {
+ Ordering::Less => {
+ // in the case where our subsec part is negative, then we are actually in the earlier second
+ // hence we subtract one from the seconds part, and we then add a whole second worth of nanos
+ // to our nanos part. Due to the use of u32 datatype, it is more convenient to subtract
+ // the absolute value of the subsec nanos from a whole second worth of nanos
+ let nsecs = u32::try_from(subsecs.abs()).ok()? * unit.nanos_per();
+ NaiveDateTime::from_timestamp_opt(
+ secs.checked_sub(1)?,
+ NANOS_IN_SECOND.checked_sub(nsecs)?,
+ )
+ }
+ Ordering::Equal => NaiveDateTime::from_timestamp_opt(secs, 0),
+ Ordering::Greater => {
+ // convert the subsec millis into nanosecond scale so they can be supplied
+ // as the nanoseconds parameter
+ let nsecs = u32::try_from(subsecs).ok()? * unit.nanos_per();
+ NaiveDateTime::from_timestamp_opt(secs, nsecs)
+ }
+ }
+ }
+}
+
+impl Datelike for NaiveDateTime {
+ /// Returns the year number in the [calendar date](./index.html#calendar-date).
+ ///
+ /// See also the [`NaiveDate::year`] method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 25).unwrap().and_hms_opt(12, 34, 56).unwrap();
+ /// assert_eq!(dt.year(), 2015);
+ /// ```
+ #[inline]
+ fn year(&self) -> i32 {
+ self.date.year()
+ }
+
+ /// Returns the month number starting from 1.
+ ///
+ /// The return value ranges from 1 to 12.
+ ///
+ /// See also the [`NaiveDate::month`](./struct.NaiveDate.html#method.month) method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 25).unwrap().and_hms_opt(12, 34, 56).unwrap();
+ /// assert_eq!(dt.month(), 9);
+ /// ```
+ #[inline]
+ fn month(&self) -> u32 {
+ self.date.month()
+ }
+
+ /// Returns the month number starting from 0.
+ ///
+ /// The return value ranges from 0 to 11.
+ ///
+ /// See also the [`NaiveDate::month0`](./struct.NaiveDate.html#method.month0) method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 25).unwrap().and_hms_opt(12, 34, 56).unwrap();
+ /// assert_eq!(dt.month0(), 8);
+ /// ```
+ #[inline]
+ fn month0(&self) -> u32 {
+ self.date.month0()
+ }
+
+ /// Returns the day of month starting from 1.
+ ///
+ /// The return value ranges from 1 to 31. (The last day of month differs by months.)
+ ///
+ /// See also the [`NaiveDate::day`](./struct.NaiveDate.html#method.day) method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 25).unwrap().and_hms_opt(12, 34, 56).unwrap();
+ /// assert_eq!(dt.day(), 25);
+ /// ```
+ #[inline]
+ fn day(&self) -> u32 {
+ self.date.day()
+ }
+
+ /// Returns the day of month starting from 0.
+ ///
+ /// The return value ranges from 0 to 30. (The last day of month differs by months.)
+ ///
+ /// See also the [`NaiveDate::day0`](./struct.NaiveDate.html#method.day0) method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 25).unwrap().and_hms_opt(12, 34, 56).unwrap();
+ /// assert_eq!(dt.day0(), 24);
+ /// ```
+ #[inline]
+ fn day0(&self) -> u32 {
+ self.date.day0()
+ }
+
+ /// Returns the day of year starting from 1.
+ ///
+ /// The return value ranges from 1 to 366. (The last day of year differs by years.)
+ ///
+ /// See also the [`NaiveDate::ordinal`](./struct.NaiveDate.html#method.ordinal) method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 25).unwrap().and_hms_opt(12, 34, 56).unwrap();
+ /// assert_eq!(dt.ordinal(), 268);
+ /// ```
+ #[inline]
+ fn ordinal(&self) -> u32 {
+ self.date.ordinal()
+ }
+
+ /// Returns the day of year starting from 0.
+ ///
+ /// The return value ranges from 0 to 365. (The last day of year differs by years.)
+ ///
+ /// See also the [`NaiveDate::ordinal0`](./struct.NaiveDate.html#method.ordinal0) method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 25).unwrap().and_hms_opt(12, 34, 56).unwrap();
+ /// assert_eq!(dt.ordinal0(), 267);
+ /// ```
+ #[inline]
+ fn ordinal0(&self) -> u32 {
+ self.date.ordinal0()
+ }
+
+ /// Returns the day of week.
+ ///
+ /// See also the [`NaiveDate::weekday`](./struct.NaiveDate.html#method.weekday) method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Datelike, Weekday};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 25).unwrap().and_hms_opt(12, 34, 56).unwrap();
+ /// assert_eq!(dt.weekday(), Weekday::Fri);
+ /// ```
+ #[inline]
+ fn weekday(&self) -> Weekday {
+ self.date.weekday()
+ }
+
+ #[inline]
+ fn iso_week(&self) -> IsoWeek {
+ self.date.iso_week()
+ }
+
+ /// Makes a new `NaiveDateTime` with the year number changed.
+ ///
+ /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
+ ///
+ /// See also the [`NaiveDate::with_year`] method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 25).unwrap().and_hms_opt(12, 34, 56).unwrap();
+ /// assert_eq!(dt.with_year(2016), Some(NaiveDate::from_ymd_opt(2016, 9, 25).unwrap().and_hms_opt(12, 34, 56).unwrap()));
+ /// assert_eq!(dt.with_year(-308), Some(NaiveDate::from_ymd_opt(-308, 9, 25).unwrap().and_hms_opt(12, 34, 56).unwrap()));
+ /// ```
+ #[inline]
+ fn with_year(&self, year: i32) -> Option<NaiveDateTime> {
+ self.date.with_year(year).map(|d| NaiveDateTime { date: d, ..*self })
+ }
+
+ /// Makes a new `NaiveDateTime` with the month number (starting from 1) changed.
+ ///
+ /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
+ ///
+ /// See also the [`NaiveDate::with_month`] method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 30).unwrap().and_hms_opt(12, 34, 56).unwrap();
+ /// assert_eq!(dt.with_month(10), Some(NaiveDate::from_ymd_opt(2015, 10, 30).unwrap().and_hms_opt(12, 34, 56).unwrap()));
+ /// assert_eq!(dt.with_month(13), None); // no month 13
+ /// assert_eq!(dt.with_month(2), None); // no February 30
+ /// ```
+ #[inline]
+ fn with_month(&self, month: u32) -> Option<NaiveDateTime> {
+ self.date.with_month(month).map(|d| NaiveDateTime { date: d, ..*self })
+ }
+
+ /// Makes a new `NaiveDateTime` with the month number (starting from 0) changed.
+ ///
+ /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
+ ///
+ /// See also the [`NaiveDate::with_month0`] method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 30).unwrap().and_hms_opt(12, 34, 56).unwrap();
+ /// assert_eq!(dt.with_month0(9), Some(NaiveDate::from_ymd_opt(2015, 10, 30).unwrap().and_hms_opt(12, 34, 56).unwrap()));
+ /// assert_eq!(dt.with_month0(12), None); // no month 13
+ /// assert_eq!(dt.with_month0(1), None); // no February 30
+ /// ```
+ #[inline]
+ fn with_month0(&self, month0: u32) -> Option<NaiveDateTime> {
+ self.date.with_month0(month0).map(|d| NaiveDateTime { date: d, ..*self })
+ }
+
+ /// Makes a new `NaiveDateTime` with the day of month (starting from 1) changed.
+ ///
+ /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
+ ///
+ /// See also the [`NaiveDate::with_day`] method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().and_hms_opt(12, 34, 56).unwrap();
+ /// assert_eq!(dt.with_day(30), Some(NaiveDate::from_ymd_opt(2015, 9, 30).unwrap().and_hms_opt(12, 34, 56).unwrap()));
+ /// assert_eq!(dt.with_day(31), None); // no September 31
+ /// ```
+ #[inline]
+ fn with_day(&self, day: u32) -> Option<NaiveDateTime> {
+ self.date.with_day(day).map(|d| NaiveDateTime { date: d, ..*self })
+ }
+
+ /// Makes a new `NaiveDateTime` with the day of month (starting from 0) changed.
+ ///
+ /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
+ ///
+ /// See also the [`NaiveDate::with_day0`] method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().and_hms_opt(12, 34, 56).unwrap();
+ /// assert_eq!(dt.with_day0(29), Some(NaiveDate::from_ymd_opt(2015, 9, 30).unwrap().and_hms_opt(12, 34, 56).unwrap()));
+ /// assert_eq!(dt.with_day0(30), None); // no September 31
+ /// ```
+ #[inline]
+ fn with_day0(&self, day0: u32) -> Option<NaiveDateTime> {
+ self.date.with_day0(day0).map(|d| NaiveDateTime { date: d, ..*self })
+ }
+
+ /// Makes a new `NaiveDateTime` with the day of year (starting from 1) changed.
+ ///
+ /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
+ ///
+ /// See also the [`NaiveDate::with_ordinal`] method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().and_hms_opt(12, 34, 56).unwrap();
+ /// assert_eq!(dt.with_ordinal(60),
+ /// Some(NaiveDate::from_ymd_opt(2015, 3, 1).unwrap().and_hms_opt(12, 34, 56).unwrap()));
+ /// assert_eq!(dt.with_ordinal(366), None); // 2015 had only 365 days
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2016, 9, 8).unwrap().and_hms_opt(12, 34, 56).unwrap();
+ /// assert_eq!(dt.with_ordinal(60),
+ /// Some(NaiveDate::from_ymd_opt(2016, 2, 29).unwrap().and_hms_opt(12, 34, 56).unwrap()));
+ /// assert_eq!(dt.with_ordinal(366),
+ /// Some(NaiveDate::from_ymd_opt(2016, 12, 31).unwrap().and_hms_opt(12, 34, 56).unwrap()));
+ /// ```
+ #[inline]
+ fn with_ordinal(&self, ordinal: u32) -> Option<NaiveDateTime> {
+ self.date.with_ordinal(ordinal).map(|d| NaiveDateTime { date: d, ..*self })
+ }
+
+ /// Makes a new `NaiveDateTime` with the day of year (starting from 0) changed.
+ ///
+ /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
+ ///
+ /// See also the [`NaiveDate::with_ordinal0`] method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Datelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().and_hms_opt(12, 34, 56).unwrap();
+ /// assert_eq!(dt.with_ordinal0(59),
+ /// Some(NaiveDate::from_ymd_opt(2015, 3, 1).unwrap().and_hms_opt(12, 34, 56).unwrap()));
+ /// assert_eq!(dt.with_ordinal0(365), None); // 2015 had only 365 days
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2016, 9, 8).unwrap().and_hms_opt(12, 34, 56).unwrap();
+ /// assert_eq!(dt.with_ordinal0(59),
+ /// Some(NaiveDate::from_ymd_opt(2016, 2, 29).unwrap().and_hms_opt(12, 34, 56).unwrap()));
+ /// assert_eq!(dt.with_ordinal0(365),
+ /// Some(NaiveDate::from_ymd_opt(2016, 12, 31).unwrap().and_hms_opt(12, 34, 56).unwrap()));
+ /// ```
+ #[inline]
+ fn with_ordinal0(&self, ordinal0: u32) -> Option<NaiveDateTime> {
+ self.date.with_ordinal0(ordinal0).map(|d| NaiveDateTime { date: d, ..*self })
+ }
+}
+
+impl Timelike for NaiveDateTime {
+ /// Returns the hour number from 0 to 23.
+ ///
+ /// See also the [`NaiveTime::hour`] method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().and_hms_milli_opt(12, 34, 56, 789).unwrap();
+ /// assert_eq!(dt.hour(), 12);
+ /// ```
+ #[inline]
+ fn hour(&self) -> u32 {
+ self.time.hour()
+ }
+
+ /// Returns the minute number from 0 to 59.
+ ///
+ /// See also the [`NaiveTime::minute`] method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().and_hms_milli_opt(12, 34, 56, 789).unwrap();
+ /// assert_eq!(dt.minute(), 34);
+ /// ```
+ #[inline]
+ fn minute(&self) -> u32 {
+ self.time.minute()
+ }
+
+ /// Returns the second number from 0 to 59.
+ ///
+ /// See also the [`NaiveTime::second`] method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().and_hms_milli_opt(12, 34, 56, 789).unwrap();
+ /// assert_eq!(dt.second(), 56);
+ /// ```
+ #[inline]
+ fn second(&self) -> u32 {
+ self.time.second()
+ }
+
+ /// Returns the number of nanoseconds since the whole non-leap second.
+ /// The range from 1,000,000,000 to 1,999,999,999 represents
+ /// the [leap second](./struct.NaiveTime.html#leap-second-handling).
+ ///
+ /// See also the [`NaiveTime::nanosecond`] method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().and_hms_milli_opt(12, 34, 56, 789).unwrap();
+ /// assert_eq!(dt.nanosecond(), 789_000_000);
+ /// ```
+ #[inline]
+ fn nanosecond(&self) -> u32 {
+ self.time.nanosecond()
+ }
+
+ /// Makes a new `NaiveDateTime` with the hour number changed.
+ ///
+ /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
+ ///
+ /// See also the [`NaiveTime::with_hour`] method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().and_hms_milli_opt(12, 34, 56, 789).unwrap();
+ /// assert_eq!(dt.with_hour(7),
+ /// Some(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().and_hms_milli_opt(7, 34, 56, 789).unwrap()));
+ /// assert_eq!(dt.with_hour(24), None);
+ /// ```
+ #[inline]
+ fn with_hour(&self, hour: u32) -> Option<NaiveDateTime> {
+ self.time.with_hour(hour).map(|t| NaiveDateTime { time: t, ..*self })
+ }
+
+ /// Makes a new `NaiveDateTime` with the minute number changed.
+ ///
+ /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
+ ///
+ /// See also the
+ /// [`NaiveTime::with_minute`] method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().and_hms_milli_opt(12, 34, 56, 789).unwrap();
+ /// assert_eq!(dt.with_minute(45),
+ /// Some(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().and_hms_milli_opt(12, 45, 56, 789).unwrap()));
+ /// assert_eq!(dt.with_minute(60), None);
+ /// ```
+ #[inline]
+ fn with_minute(&self, min: u32) -> Option<NaiveDateTime> {
+ self.time.with_minute(min).map(|t| NaiveDateTime { time: t, ..*self })
+ }
+
+ /// Makes a new `NaiveDateTime` with the second number changed.
+ ///
+ /// Returns `None` when the resulting `NaiveDateTime` would be invalid. As
+ /// with the [`NaiveDateTime::second`] method, the input range is
+ /// restricted to 0 through 59.
+ ///
+ /// See also the [`NaiveTime::with_second`] method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().and_hms_milli_opt(12, 34, 56, 789).unwrap();
+ /// assert_eq!(dt.with_second(17),
+ /// Some(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().and_hms_milli_opt(12, 34, 17, 789).unwrap()));
+ /// assert_eq!(dt.with_second(60), None);
+ /// ```
+ #[inline]
+ fn with_second(&self, sec: u32) -> Option<NaiveDateTime> {
+ self.time.with_second(sec).map(|t| NaiveDateTime { time: t, ..*self })
+ }
+
+ /// Makes a new `NaiveDateTime` with nanoseconds since the whole non-leap second changed.
+ ///
+ /// Returns `None` when the resulting `NaiveDateTime` would be invalid.
+ /// As with the [`NaiveDateTime::nanosecond`] method,
+ /// the input range can exceed 1,000,000,000 for leap seconds.
+ ///
+ /// See also the [`NaiveTime::with_nanosecond`] method.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{NaiveDate, NaiveDateTime, Timelike};
+ ///
+ /// let dt: NaiveDateTime = NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().and_hms_milli_opt(12, 34, 56, 789).unwrap();
+ /// assert_eq!(dt.with_nanosecond(333_333_333),
+ /// Some(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().and_hms_nano_opt(12, 34, 56, 333_333_333).unwrap()));
+ /// assert_eq!(dt.with_nanosecond(1_333_333_333), // leap second
+ /// Some(NaiveDate::from_ymd_opt(2015, 9, 8).unwrap().and_hms_nano_opt(12, 34, 56, 1_333_333_333).unwrap()));
+ /// assert_eq!(dt.with_nanosecond(2_000_000_000), None);
+ /// ```
+ #[inline]
+ fn with_nanosecond(&self, nano: u32) -> Option<NaiveDateTime> {
+ self.time.with_nanosecond(nano).map(|t| NaiveDateTime { time: t, ..*self })
+ }
+}
+
+/// An addition of `Duration` to `NaiveDateTime` yields another `NaiveDateTime`.
+///
+/// As a part of Chrono's [leap second handling](./struct.NaiveTime.html#leap-second-handling),
+/// the addition assumes that **there is no leap second ever**,
+/// except when the `NaiveDateTime` itself represents a leap second
+/// in which case the assumption becomes that **there is exactly a single leap second ever**.
+///
+/// Panics on underflow or overflow. Use [`NaiveDateTime::checked_add_signed`]
+/// to detect that.
+///
+/// # Example
+///
+/// ```
+/// use chrono::{Duration, NaiveDate};
+///
+/// let from_ymd = NaiveDate::from_ymd;
+///
+/// let d = from_ymd(2016, 7, 8);
+/// let hms = |h, m, s| d.and_hms_opt(h, m, s).unwrap();
+/// assert_eq!(hms(3, 5, 7) + Duration::zero(), hms(3, 5, 7));
+/// assert_eq!(hms(3, 5, 7) + Duration::seconds(1), hms(3, 5, 8));
+/// assert_eq!(hms(3, 5, 7) + Duration::seconds(-1), hms(3, 5, 6));
+/// assert_eq!(hms(3, 5, 7) + Duration::seconds(3600 + 60), hms(4, 6, 7));
+/// assert_eq!(hms(3, 5, 7) + Duration::seconds(86_400),
+/// from_ymd(2016, 7, 9).and_hms_opt(3, 5, 7).unwrap());
+/// assert_eq!(hms(3, 5, 7) + Duration::days(365),
+/// from_ymd(2017, 7, 8).and_hms_opt(3, 5, 7).unwrap());
+///
+/// let hmsm = |h, m, s, milli| d.and_hms_milli_opt(h, m, s, milli).unwrap();
+/// assert_eq!(hmsm(3, 5, 7, 980) + Duration::milliseconds(450), hmsm(3, 5, 8, 430));
+/// ```
+///
+/// Leap seconds are handled,
+/// but the addition assumes that it is the only leap second happened.
+///
+/// ```
+/// # use chrono::{Duration, NaiveDate};
+/// # let from_ymd = NaiveDate::from_ymd;
+/// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli_opt(h, m, s, milli).unwrap();
+/// let leap = hmsm(3, 5, 59, 1_300);
+/// assert_eq!(leap + Duration::zero(), hmsm(3, 5, 59, 1_300));
+/// assert_eq!(leap + Duration::milliseconds(-500), hmsm(3, 5, 59, 800));
+/// assert_eq!(leap + Duration::milliseconds(500), hmsm(3, 5, 59, 1_800));
+/// assert_eq!(leap + Duration::milliseconds(800), hmsm(3, 6, 0, 100));
+/// assert_eq!(leap + Duration::seconds(10), hmsm(3, 6, 9, 300));
+/// assert_eq!(leap + Duration::seconds(-10), hmsm(3, 5, 50, 300));
+/// assert_eq!(leap + Duration::days(1),
+/// from_ymd(2016, 7, 9).and_hms_milli_opt(3, 5, 59, 300).unwrap());
+/// ```
+impl Add<OldDuration> for NaiveDateTime {
+ type Output = NaiveDateTime;
+
+ #[inline]
+ fn add(self, rhs: OldDuration) -> NaiveDateTime {
+ self.checked_add_signed(rhs).expect("`NaiveDateTime + Duration` overflowed")
+ }
+}
+
+impl AddAssign<OldDuration> for NaiveDateTime {
+ #[inline]
+ fn add_assign(&mut self, rhs: OldDuration) {
+ *self = self.add(rhs);
+ }
+}
+
+impl Add<Months> for NaiveDateTime {
+ type Output = NaiveDateTime;
+
+ /// An addition of months to `NaiveDateTime` clamped to valid days in resulting month.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the resulting date would be out of range.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use chrono::{Duration, NaiveDateTime, Months, NaiveDate};
+ /// use std::str::FromStr;
+ ///
+ /// assert_eq!(
+ /// NaiveDate::from_ymd_opt(2014, 1, 1).unwrap().and_hms_opt(1, 0, 0).unwrap() + Months::new(1),
+ /// NaiveDate::from_ymd_opt(2014, 2, 1).unwrap().and_hms_opt(1, 0, 0).unwrap()
+ /// );
+ /// assert_eq!(
+ /// NaiveDate::from_ymd_opt(2014, 1, 1).unwrap().and_hms_opt(0, 2, 0).unwrap() + Months::new(11),
+ /// NaiveDate::from_ymd_opt(2014, 12, 1).unwrap().and_hms_opt(0, 2, 0).unwrap()
+ /// );
+ /// assert_eq!(
+ /// NaiveDate::from_ymd_opt(2014, 1, 1).unwrap().and_hms_opt(0, 0, 3).unwrap() + Months::new(12),
+ /// NaiveDate::from_ymd_opt(2015, 1, 1).unwrap().and_hms_opt(0, 0, 3).unwrap()
+ /// );
+ /// assert_eq!(
+ /// NaiveDate::from_ymd_opt(2014, 1, 1).unwrap().and_hms_opt(0, 0, 4).unwrap() + Months::new(13),
+ /// NaiveDate::from_ymd_opt(2015, 2, 1).unwrap().and_hms_opt(0, 0, 4).unwrap()
+ /// );
+ /// assert_eq!(
+ /// NaiveDate::from_ymd_opt(2014, 1, 31).unwrap().and_hms_opt(0, 5, 0).unwrap() + Months::new(1),
+ /// NaiveDate::from_ymd_opt(2014, 2, 28).unwrap().and_hms_opt(0, 5, 0).unwrap()
+ /// );
+ /// assert_eq!(
+ /// NaiveDate::from_ymd_opt(2020, 1, 31).unwrap().and_hms_opt(6, 0, 0).unwrap() + Months::new(1),
+ /// NaiveDate::from_ymd_opt(2020, 2, 29).unwrap().and_hms_opt(6, 0, 0).unwrap()
+ /// );
+ /// ```
+ fn add(self, rhs: Months) -> Self::Output {
+ Self { date: self.date.checked_add_months(rhs).unwrap(), time: self.time }
+ }
+}
+
+/// A subtraction of `Duration` from `NaiveDateTime` yields another `NaiveDateTime`.
+/// It is the same as the addition with a negated `Duration`.
+///
+/// As a part of Chrono's [leap second handling](./struct.NaiveTime.html#leap-second-handling),
+/// the addition assumes that **there is no leap second ever**,
+/// except when the `NaiveDateTime` itself represents a leap second
+/// in which case the assumption becomes that **there is exactly a single leap second ever**.
+///
+/// Panics on underflow or overflow. Use [`NaiveDateTime::checked_sub_signed`]
+/// to detect that.
+///
+/// # Example
+///
+/// ```
+/// use chrono::{Duration, NaiveDate};
+///
+/// let from_ymd = NaiveDate::from_ymd;
+///
+/// let d = from_ymd(2016, 7, 8);
+/// let hms = |h, m, s| d.and_hms_opt(h, m, s).unwrap();
+/// assert_eq!(hms(3, 5, 7) - Duration::zero(), hms(3, 5, 7));
+/// assert_eq!(hms(3, 5, 7) - Duration::seconds(1), hms(3, 5, 6));
+/// assert_eq!(hms(3, 5, 7) - Duration::seconds(-1), hms(3, 5, 8));
+/// assert_eq!(hms(3, 5, 7) - Duration::seconds(3600 + 60), hms(2, 4, 7));
+/// assert_eq!(hms(3, 5, 7) - Duration::seconds(86_400),
+/// from_ymd(2016, 7, 7).and_hms_opt(3, 5, 7).unwrap());
+/// assert_eq!(hms(3, 5, 7) - Duration::days(365),
+/// from_ymd(2015, 7, 9).and_hms_opt(3, 5, 7).unwrap());
+///
+/// let hmsm = |h, m, s, milli| d.and_hms_milli_opt(h, m, s, milli).unwrap();
+/// assert_eq!(hmsm(3, 5, 7, 450) - Duration::milliseconds(670), hmsm(3, 5, 6, 780));
+/// ```
+///
+/// Leap seconds are handled,
+/// but the subtraction assumes that it is the only leap second happened.
+///
+/// ```
+/// # use chrono::{Duration, NaiveDate};
+/// # let from_ymd = NaiveDate::from_ymd;
+/// # let hmsm = |h, m, s, milli| from_ymd(2016, 7, 8).and_hms_milli_opt(h, m, s, milli).unwrap();
+/// let leap = hmsm(3, 5, 59, 1_300);
+/// assert_eq!(leap - Duration::zero(), hmsm(3, 5, 59, 1_300));
+/// assert_eq!(leap - Duration::milliseconds(200), hmsm(3, 5, 59, 1_100));
+/// assert_eq!(leap - Duration::milliseconds(500), hmsm(3, 5, 59, 800));
+/// assert_eq!(leap - Duration::seconds(60), hmsm(3, 5, 0, 300));
+/// assert_eq!(leap - Duration::days(1),
+/// from_ymd(2016, 7, 7).and_hms_milli_opt(3, 6, 0, 300).unwrap());
+/// ```
+impl Sub<OldDuration> for NaiveDateTime {
+ type Output = NaiveDateTime;
+
+ #[inline]
+ fn sub(self, rhs: OldDuration) -> NaiveDateTime {
+ self.checked_sub_signed(rhs).expect("`NaiveDateTime - Duration` overflowed")
+ }
+}
+
+impl SubAssign<OldDuration> for NaiveDateTime {
+ #[inline]
+ fn sub_assign(&mut self, rhs: OldDuration) {
+ *self = self.sub(rhs);
+ }
+}
+
+/// A subtraction of Months from `NaiveDateTime` clamped to valid days in resulting month.
+///
+/// # Panics
+///
+/// Panics if the resulting date would be out of range.
+///
+/// # Example
+///
+/// ```
+/// use chrono::{Duration, NaiveDateTime, Months, NaiveDate};
+/// use std::str::FromStr;
+///
+/// assert_eq!(
+/// NaiveDate::from_ymd_opt(2014, 01, 01).unwrap().and_hms_opt(01, 00, 00).unwrap() - Months::new(11),
+/// NaiveDate::from_ymd_opt(2013, 02, 01).unwrap().and_hms_opt(01, 00, 00).unwrap()
+/// );
+/// assert_eq!(
+/// NaiveDate::from_ymd_opt(2014, 01, 01).unwrap().and_hms_opt(00, 02, 00).unwrap() - Months::new(12),
+/// NaiveDate::from_ymd_opt(2013, 01, 01).unwrap().and_hms_opt(00, 02, 00).unwrap()
+/// );
+/// assert_eq!(
+/// NaiveDate::from_ymd_opt(2014, 01, 01).unwrap().and_hms_opt(00, 00, 03).unwrap() - Months::new(13),
+/// NaiveDate::from_ymd_opt(2012, 12, 01).unwrap().and_hms_opt(00, 00, 03).unwrap()
+/// );
+/// ```
+impl Sub<Months> for NaiveDateTime {
+ type Output = NaiveDateTime;
+
+ fn sub(self, rhs: Months) -> Self::Output {
+ Self { date: self.date.checked_sub_months(rhs).unwrap(), time: self.time }
+ }
+}
+
+/// Subtracts another `NaiveDateTime` from the current date and time.
+/// This does not overflow or underflow at all.
+///
+/// As a part of Chrono's [leap second handling](./struct.NaiveTime.html#leap-second-handling),
+/// the subtraction assumes that **there is no leap second ever**,
+/// except when any of the `NaiveDateTime`s themselves represents a leap second
+/// in which case the assumption becomes that
+/// **there are exactly one (or two) leap second(s) ever**.
+///
+/// The implementation is a wrapper around [`NaiveDateTime::signed_duration_since`].
+///
+/// # Example
+///
+/// ```
+/// use chrono::{Duration, NaiveDate};
+///
+/// let from_ymd = NaiveDate::from_ymd;
+///
+/// let d = from_ymd(2016, 7, 8);
+/// assert_eq!(d.and_hms_opt(3, 5, 7).unwrap() - d.and_hms_opt(2, 4, 6).unwrap(), Duration::seconds(3600 + 60 + 1));
+///
+/// // July 8 is 190th day in the year 2016
+/// let d0 = from_ymd(2016, 1, 1);
+/// assert_eq!(d.and_hms_milli_opt(0, 7, 6, 500).unwrap() - d0.and_hms_opt(0, 0, 0).unwrap(),
+/// Duration::seconds(189 * 86_400 + 7 * 60 + 6) + Duration::milliseconds(500));
+/// ```
+///
+/// Leap seconds are handled, but the subtraction assumes that no other leap
+/// seconds happened.
+///
+/// ```
+/// # use chrono::{Duration, NaiveDate};
+/// # let from_ymd = NaiveDate::from_ymd;
+/// let leap = from_ymd(2015, 6, 30).and_hms_milli_opt(23, 59, 59, 1_500).unwrap();
+/// assert_eq!(leap - from_ymd(2015, 6, 30).and_hms_opt(23, 0, 0).unwrap(),
+/// Duration::seconds(3600) + Duration::milliseconds(500));
+/// assert_eq!(from_ymd(2015, 7, 1).and_hms_opt(1, 0, 0).unwrap() - leap,
+/// Duration::seconds(3600) - Duration::milliseconds(500));
+/// ```
+impl Sub<NaiveDateTime> for NaiveDateTime {
+ type Output = OldDuration;
+
+ #[inline]
+ fn sub(self, rhs: NaiveDateTime) -> OldDuration {
+ self.signed_duration_since(rhs)
+ }
+}
+
+impl Add<Days> for NaiveDateTime {
+ type Output = NaiveDateTime;
+
+ fn add(self, days: Days) -> Self::Output {
+ self.checked_add_days(days).unwrap()
+ }
+}
+
+impl Sub<Days> for NaiveDateTime {
+ type Output = NaiveDateTime;
+
+ fn sub(self, days: Days) -> Self::Output {
+ self.checked_sub_days(days).unwrap()
+ }
+}
+
+/// The `Debug` output of the naive date and time `dt` is the same as
+/// [`dt.format("%Y-%m-%dT%H:%M:%S%.f")`](crate::format::strftime).
+///
+/// The string printed can be readily parsed via the `parse` method on `str`.
+///
+/// It should be noted that, for leap seconds not on the minute boundary,
+/// it may print a representation not distinguishable from non-leap seconds.
+/// This doesn't matter in practice, since such leap seconds never happened.
+/// (By the time of the first leap second on 1972-06-30,
+/// every time zone offset around the world has standardized to the 5-minute alignment.)
+///
+/// # Example
+///
+/// ```
+/// use chrono::NaiveDate;
+///
+/// let dt = NaiveDate::from_ymd_opt(2016, 11, 15).unwrap().and_hms_opt(7, 39, 24).unwrap();
+/// assert_eq!(format!("{:?}", dt), "2016-11-15T07:39:24");
+/// ```
+///
+/// Leap seconds may also be used.
+///
+/// ```
+/// # use chrono::NaiveDate;
+/// let dt = NaiveDate::from_ymd_opt(2015, 6, 30).unwrap().and_hms_milli_opt(23, 59, 59, 1_500).unwrap();
+/// assert_eq!(format!("{:?}", dt), "2015-06-30T23:59:60.500");
+/// ```
+impl fmt::Debug for NaiveDateTime {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.date.fmt(f)?;
+ f.write_char('T')?;
+ self.time.fmt(f)
+ }
+}
+
+/// The `Display` output of the naive date and time `dt` is the same as
+/// [`dt.format("%Y-%m-%d %H:%M:%S%.f")`](crate::format::strftime).
+///
+/// It should be noted that, for leap seconds not on the minute boundary,
+/// it may print a representation not distinguishable from non-leap seconds.
+/// This doesn't matter in practice, since such leap seconds never happened.
+/// (By the time of the first leap second on 1972-06-30,
+/// every time zone offset around the world has standardized to the 5-minute alignment.)
+///
+/// # Example
+///
+/// ```
+/// use chrono::NaiveDate;
+///
+/// let dt = NaiveDate::from_ymd_opt(2016, 11, 15).unwrap().and_hms_opt(7, 39, 24).unwrap();
+/// assert_eq!(format!("{}", dt), "2016-11-15 07:39:24");
+/// ```
+///
+/// Leap seconds may also be used.
+///
+/// ```
+/// # use chrono::NaiveDate;
+/// let dt = NaiveDate::from_ymd_opt(2015, 6, 30).unwrap().and_hms_milli_opt(23, 59, 59, 1_500).unwrap();
+/// assert_eq!(format!("{}", dt), "2015-06-30 23:59:60.500");
+/// ```
+impl fmt::Display for NaiveDateTime {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.date.fmt(f)?;
+ f.write_char(' ')?;
+ self.time.fmt(f)
+ }
+}
+
+/// Parsing a `str` into a `NaiveDateTime` uses the same format,
+/// [`%Y-%m-%dT%H:%M:%S%.f`](crate::format::strftime), as in `Debug`.
+///
+/// # Example
+///
+/// ```
+/// use chrono::{NaiveDateTime, NaiveDate};
+///
+/// let dt = NaiveDate::from_ymd_opt(2015, 9, 18).unwrap().and_hms_opt(23, 56, 4).unwrap();
+/// assert_eq!("2015-09-18T23:56:04".parse::<NaiveDateTime>(), Ok(dt));
+///
+/// let dt = NaiveDate::from_ymd_opt(12345, 6, 7).unwrap().and_hms_milli_opt(7, 59, 59, 1_500).unwrap(); // leap second
+/// assert_eq!("+12345-6-7T7:59:60.5".parse::<NaiveDateTime>(), Ok(dt));
+///
+/// assert!("foo".parse::<NaiveDateTime>().is_err());
+/// ```
+impl str::FromStr for NaiveDateTime {
+ type Err = ParseError;
+
+ fn from_str(s: &str) -> ParseResult<NaiveDateTime> {
+ const ITEMS: &[Item<'static>] = &[
+ Item::Numeric(Numeric::Year, Pad::Zero),
+ Item::Space(""),
+ Item::Literal("-"),
+ Item::Numeric(Numeric::Month, Pad::Zero),
+ Item::Space(""),
+ Item::Literal("-"),
+ Item::Numeric(Numeric::Day, Pad::Zero),
+ Item::Space(""),
+ Item::Literal("T"), // XXX shouldn't this be case-insensitive?
+ Item::Numeric(Numeric::Hour, Pad::Zero),
+ Item::Space(""),
+ Item::Literal(":"),
+ Item::Numeric(Numeric::Minute, Pad::Zero),
+ Item::Space(""),
+ Item::Literal(":"),
+ Item::Numeric(Numeric::Second, Pad::Zero),
+ Item::Fixed(Fixed::Nanosecond),
+ Item::Space(""),
+ ];
+
+ let mut parsed = Parsed::new();
+ parse(&mut parsed, s, ITEMS.iter())?;
+ parsed.to_naive_datetime_with_offset(0)
+ }
+}
+
+/// The default value for a NaiveDateTime is one with epoch 0
+/// that is, 1st of January 1970 at 00:00:00.
+///
+/// # Example
+///
+/// ```rust
+/// use chrono::NaiveDateTime;
+///
+/// let default_date = NaiveDateTime::default();
+/// assert_eq!(default_date, NaiveDateTime::from_timestamp(0, 0));
+/// ```
+impl Default for NaiveDateTime {
+ fn default() -> Self {
+ NaiveDateTime::from_timestamp_opt(0, 0).unwrap()
+ }
+}
+
+#[cfg(all(test, any(feature = "rustc-serialize", feature = "serde")))]
+fn test_encodable_json<F, E>(to_string: F)
+where
+ F: Fn(&NaiveDateTime) -> Result<String, E>,
+ E: ::std::fmt::Debug,
+{
+ assert_eq!(
+ to_string(
+ &NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_milli_opt(9, 10, 48, 90).unwrap()
+ )
+ .ok(),
+ Some(r#""2016-07-08T09:10:48.090""#.into())
+ );
+ assert_eq!(
+ to_string(&NaiveDate::from_ymd_opt(2014, 7, 24).unwrap().and_hms_opt(12, 34, 6).unwrap())
+ .ok(),
+ Some(r#""2014-07-24T12:34:06""#.into())
+ );
+ assert_eq!(
+ to_string(
+ &NaiveDate::from_ymd_opt(0, 1, 1).unwrap().and_hms_milli_opt(0, 0, 59, 1_000).unwrap()
+ )
+ .ok(),
+ Some(r#""0000-01-01T00:00:60""#.into())
+ );
+ assert_eq!(
+ to_string(
+ &NaiveDate::from_ymd_opt(-1, 12, 31).unwrap().and_hms_nano_opt(23, 59, 59, 7).unwrap()
+ )
+ .ok(),
+ Some(r#""-0001-12-31T23:59:59.000000007""#.into())
+ );
+ assert_eq!(
+ to_string(&NaiveDate::MIN.and_hms_opt(0, 0, 0).unwrap()).ok(),
+ Some(r#""-262144-01-01T00:00:00""#.into())
+ );
+ assert_eq!(
+ to_string(&NaiveDate::MAX.and_hms_nano_opt(23, 59, 59, 1_999_999_999).unwrap()).ok(),
+ Some(r#""+262143-12-31T23:59:60.999999999""#.into())
+ );
+}
+
+#[cfg(all(test, any(feature = "rustc-serialize", feature = "serde")))]
+fn test_decodable_json<F, E>(from_str: F)
+where
+ F: Fn(&str) -> Result<NaiveDateTime, E>,
+ E: ::std::fmt::Debug,
+{
+ assert_eq!(
+ from_str(r#""2016-07-08T09:10:48.090""#).ok(),
+ Some(
+ NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_milli_opt(9, 10, 48, 90).unwrap()
+ )
+ );
+ assert_eq!(
+ from_str(r#""2016-7-8T9:10:48.09""#).ok(),
+ Some(
+ NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_milli_opt(9, 10, 48, 90).unwrap()
+ )
+ );
+ assert_eq!(
+ from_str(r#""2014-07-24T12:34:06""#).ok(),
+ Some(NaiveDate::from_ymd_opt(2014, 7, 24).unwrap().and_hms_opt(12, 34, 6).unwrap())
+ );
+ assert_eq!(
+ from_str(r#""0000-01-01T00:00:60""#).ok(),
+ Some(NaiveDate::from_ymd_opt(0, 1, 1).unwrap().and_hms_milli_opt(0, 0, 59, 1_000).unwrap())
+ );
+ assert_eq!(
+ from_str(r#""0-1-1T0:0:60""#).ok(),
+ Some(NaiveDate::from_ymd_opt(0, 1, 1).unwrap().and_hms_milli_opt(0, 0, 59, 1_000).unwrap())
+ );
+ assert_eq!(
+ from_str(r#""-0001-12-31T23:59:59.000000007""#).ok(),
+ Some(NaiveDate::from_ymd_opt(-1, 12, 31).unwrap().and_hms_nano_opt(23, 59, 59, 7).unwrap())
+ );
+ assert_eq!(
+ from_str(r#""-262144-01-01T00:00:00""#).ok(),
+ Some(NaiveDate::MIN.and_hms_opt(0, 0, 0).unwrap())
+ );
+ assert_eq!(
+ from_str(r#""+262143-12-31T23:59:60.999999999""#).ok(),
+ Some(NaiveDate::MAX.and_hms_nano_opt(23, 59, 59, 1_999_999_999).unwrap())
+ );
+ assert_eq!(
+ from_str(r#""+262143-12-31T23:59:60.9999999999997""#).ok(), // excess digits are ignored
+ Some(NaiveDate::MAX.and_hms_nano_opt(23, 59, 59, 1_999_999_999).unwrap())
+ );
+
+ // bad formats
+ assert!(from_str(r#""""#).is_err());
+ assert!(from_str(r#""2016-07-08""#).is_err());
+ assert!(from_str(r#""09:10:48.090""#).is_err());
+ assert!(from_str(r#""20160708T091048.090""#).is_err());
+ assert!(from_str(r#""2000-00-00T00:00:00""#).is_err());
+ assert!(from_str(r#""2000-02-30T00:00:00""#).is_err());
+ assert!(from_str(r#""2001-02-29T00:00:00""#).is_err());
+ assert!(from_str(r#""2002-02-28T24:00:00""#).is_err());
+ assert!(from_str(r#""2002-02-28T23:60:00""#).is_err());
+ assert!(from_str(r#""2002-02-28T23:59:61""#).is_err());
+ assert!(from_str(r#""2016-07-08T09:10:48,090""#).is_err());
+ assert!(from_str(r#""2016-07-08 09:10:48.090""#).is_err());
+ assert!(from_str(r#""2016-007-08T09:10:48.090""#).is_err());
+ assert!(from_str(r#""yyyy-mm-ddThh:mm:ss.fffffffff""#).is_err());
+ assert!(from_str(r#"20160708000000"#).is_err());
+ assert!(from_str(r#"{}"#).is_err());
+ // pre-0.3.0 rustc-serialize format is now invalid
+ assert!(from_str(r#"{"date":{"ymdf":20},"time":{"secs":0,"frac":0}}"#).is_err());
+ assert!(from_str(r#"null"#).is_err());
+}
+
+#[cfg(all(test, feature = "rustc-serialize"))]
+fn test_decodable_json_timestamp<F, E>(from_str: F)
+where
+ F: Fn(&str) -> Result<rustc_serialize::TsSeconds, E>,
+ E: ::std::fmt::Debug,
+{
+ assert_eq!(
+ *from_str("0").unwrap(),
+ NaiveDate::from_ymd_opt(1970, 1, 1).unwrap().and_hms_opt(0, 0, 0).unwrap(),
+ "should parse integers as timestamps"
+ );
+ assert_eq!(
+ *from_str("-1").unwrap(),
+ NaiveDate::from_ymd_opt(1969, 12, 31).unwrap().and_hms_opt(23, 59, 59).unwrap(),
+ "should parse integers as timestamps"
+ );
+}
diff --git a/vendor/chrono/src/naive/datetime/rustc_serialize.rs b/vendor/chrono/src/naive/datetime/rustc_serialize.rs
new file mode 100644
index 000000000..6e33829e0
--- /dev/null
+++ b/vendor/chrono/src/naive/datetime/rustc_serialize.rs
@@ -0,0 +1,73 @@
+#![cfg_attr(docsrs, doc(cfg(feature = "rustc-serialize")))]
+
+use super::NaiveDateTime;
+use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
+use std::ops::Deref;
+
+impl Encodable for NaiveDateTime {
+ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+ format!("{:?}", self).encode(s)
+ }
+}
+
+impl Decodable for NaiveDateTime {
+ fn decode<D: Decoder>(d: &mut D) -> Result<NaiveDateTime, D::Error> {
+ d.read_str()?.parse().map_err(|_| d.error("invalid date time string"))
+ }
+}
+
+/// A `DateTime` that can be deserialized from a seconds-based timestamp
+#[derive(Debug)]
+#[deprecated(
+ since = "1.4.2",
+ note = "RustcSerialize will be removed before chrono 1.0, use Serde instead"
+)]
+pub struct TsSeconds(NaiveDateTime);
+
+#[allow(deprecated)]
+impl From<TsSeconds> for NaiveDateTime {
+ /// Pull the internal NaiveDateTime out
+ #[allow(deprecated)]
+ fn from(obj: TsSeconds) -> NaiveDateTime {
+ obj.0
+ }
+}
+
+#[allow(deprecated)]
+impl Deref for TsSeconds {
+ type Target = NaiveDateTime;
+
+ #[allow(deprecated)]
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+#[allow(deprecated)]
+impl Decodable for TsSeconds {
+ #[allow(deprecated)]
+ fn decode<D: Decoder>(d: &mut D) -> Result<TsSeconds, D::Error> {
+ Ok(TsSeconds(
+ NaiveDateTime::from_timestamp_opt(d.read_i64()?, 0)
+ .ok_or_else(|| d.error("invalid timestamp"))?,
+ ))
+ }
+}
+
+#[cfg(test)]
+use rustc_serialize::json;
+
+#[test]
+fn test_encodable() {
+ super::test_encodable_json(json::encode);
+}
+
+#[test]
+fn test_decodable() {
+ super::test_decodable_json(json::decode);
+}
+
+#[test]
+fn test_decodable_timestamps() {
+ super::test_decodable_json_timestamp(json::decode);
+}
diff --git a/vendor/chrono/src/naive/datetime/serde.rs b/vendor/chrono/src/naive/datetime/serde.rs
new file mode 100644
index 000000000..40695fa74
--- /dev/null
+++ b/vendor/chrono/src/naive/datetime/serde.rs
@@ -0,0 +1,1133 @@
+#![cfg_attr(docsrs, doc(cfg(feature = "serde")))]
+
+use core::fmt;
+use serde::{de, ser};
+
+use super::NaiveDateTime;
+use crate::offset::LocalResult;
+
+/// Serialize a `NaiveDateTime` as an RFC 3339 string
+///
+/// See [the `serde` module](./serde/index.html) for alternate
+/// serialization formats.
+impl ser::Serialize for NaiveDateTime {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ struct FormatWrapped<'a, D: 'a> {
+ inner: &'a D,
+ }
+
+ impl<'a, D: fmt::Debug> fmt::Display for FormatWrapped<'a, D> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.inner.fmt(f)
+ }
+ }
+
+ serializer.collect_str(&FormatWrapped { inner: &self })
+ }
+}
+
+struct NaiveDateTimeVisitor;
+
+impl<'de> de::Visitor<'de> for NaiveDateTimeVisitor {
+ type Value = NaiveDateTime;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a formatted date and time string")
+ }
+
+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ value.parse().map_err(E::custom)
+ }
+}
+
+impl<'de> de::Deserialize<'de> for NaiveDateTime {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ deserializer.deserialize_str(NaiveDateTimeVisitor)
+ }
+}
+
+/// Used to serialize/deserialize from nanosecond-precision timestamps
+///
+/// # Example:
+///
+/// ```rust
+/// # use chrono::{NaiveDate, NaiveDateTime};
+/// # use serde_derive::{Deserialize, Serialize};
+/// use chrono::naive::serde::ts_nanoseconds;
+/// #[derive(Deserialize, Serialize)]
+/// struct S {
+/// #[serde(with = "ts_nanoseconds")]
+/// time: NaiveDateTime
+/// }
+///
+/// let time = NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_nano_opt(02, 04, 59, 918355733).unwrap();
+/// let my_s = S {
+/// time: time.clone(),
+/// };
+///
+/// let as_string = serde_json::to_string(&my_s)?;
+/// assert_eq!(as_string, r#"{"time":1526522699918355733}"#);
+/// let my_s: S = serde_json::from_str(&as_string)?;
+/// assert_eq!(my_s.time, time);
+/// # Ok::<(), serde_json::Error>(())
+/// ```
+pub mod ts_nanoseconds {
+ use core::fmt;
+ use serde::{de, ser};
+
+ use super::ne_timestamp;
+ use crate::NaiveDateTime;
+
+ /// Serialize a datetime into an integer number of nanoseconds since the epoch
+ ///
+ /// Intended for use with `serde`s `serialize_with` attribute.
+ ///
+ /// # Example:
+ ///
+ /// ```rust
+ /// # use chrono::{NaiveDate, NaiveDateTime};
+ /// # use serde_derive::Serialize;
+ /// use chrono::naive::serde::ts_nanoseconds::serialize as to_nano_ts;
+ /// #[derive(Serialize)]
+ /// struct S {
+ /// #[serde(serialize_with = "to_nano_ts")]
+ /// time: NaiveDateTime
+ /// }
+ ///
+ /// let my_s = S {
+ /// time: NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_nano_opt(02, 04, 59, 918355733).unwrap(),
+ /// };
+ /// let as_string = serde_json::to_string(&my_s)?;
+ /// assert_eq!(as_string, r#"{"time":1526522699918355733}"#);
+ /// # Ok::<(), serde_json::Error>(())
+ /// ```
+ pub fn serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ serializer.serialize_i64(dt.timestamp_nanos())
+ }
+
+ /// Deserialize a `NaiveDateTime` from a nanoseconds timestamp
+ ///
+ /// Intended for use with `serde`s `deserialize_with` attribute.
+ ///
+ /// # Example:
+ ///
+ /// ```rust
+ /// # use chrono::NaiveDateTime;
+ /// # use serde_derive::Deserialize;
+ /// use chrono::naive::serde::ts_nanoseconds::deserialize as from_nano_ts;
+ /// #[derive(Deserialize)]
+ /// struct S {
+ /// #[serde(deserialize_with = "from_nano_ts")]
+ /// time: NaiveDateTime
+ /// }
+ ///
+ /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355733 }"#)?;
+ /// # Ok::<(), serde_json::Error>(())
+ /// ```
+ pub fn deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ d.deserialize_i64(NanoSecondsTimestampVisitor)
+ }
+
+ pub(super) struct NanoSecondsTimestampVisitor;
+
+ impl<'de> de::Visitor<'de> for NanoSecondsTimestampVisitor {
+ type Value = NaiveDateTime;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a unix timestamp")
+ }
+
+ fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ NaiveDateTime::from_timestamp_opt(value / 1_000_000_000, (value % 1_000_000_000) as u32)
+ .ok_or_else(|| E::custom(ne_timestamp(value)))
+ }
+
+ fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ NaiveDateTime::from_timestamp_opt(
+ value as i64 / 1_000_000_000,
+ (value as i64 % 1_000_000_000) as u32,
+ )
+ .ok_or_else(|| E::custom(ne_timestamp(value)))
+ }
+ }
+}
+
+/// Ser/de to/from optional timestamps in nanoseconds
+///
+/// Intended for use with `serde`'s `with` attribute.
+///
+/// # Example:
+///
+/// ```rust
+/// # use chrono::naive::{NaiveDate, NaiveDateTime};
+/// # use serde_derive::{Deserialize, Serialize};
+/// use chrono::naive::serde::ts_nanoseconds_option;
+/// #[derive(Deserialize, Serialize)]
+/// struct S {
+/// #[serde(with = "ts_nanoseconds_option")]
+/// time: Option<NaiveDateTime>
+/// }
+///
+/// let time = Some(NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_nano_opt(02, 04, 59, 918355733).unwrap());
+/// let my_s = S {
+/// time: time.clone(),
+/// };
+///
+/// let as_string = serde_json::to_string(&my_s)?;
+/// assert_eq!(as_string, r#"{"time":1526522699918355733}"#);
+/// let my_s: S = serde_json::from_str(&as_string)?;
+/// assert_eq!(my_s.time, time);
+/// # Ok::<(), serde_json::Error>(())
+/// ```
+pub mod ts_nanoseconds_option {
+ use core::fmt;
+ use serde::{de, ser};
+
+ use super::ts_nanoseconds::NanoSecondsTimestampVisitor;
+ use crate::NaiveDateTime;
+
+ /// Serialize a datetime into an integer number of nanoseconds since the epoch or none
+ ///
+ /// Intended for use with `serde`s `serialize_with` attribute.
+ ///
+ /// # Example:
+ ///
+ /// ```rust
+ /// # use chrono::naive::{NaiveDate, NaiveDateTime};
+ /// # use serde_derive::Serialize;
+ /// use chrono::naive::serde::ts_nanoseconds_option::serialize as to_nano_tsopt;
+ /// #[derive(Serialize)]
+ /// struct S {
+ /// #[serde(serialize_with = "to_nano_tsopt")]
+ /// time: Option<NaiveDateTime>
+ /// }
+ ///
+ /// let my_s = S {
+ /// time: Some(NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_nano_opt(02, 04, 59, 918355733).unwrap()),
+ /// };
+ /// let as_string = serde_json::to_string(&my_s)?;
+ /// assert_eq!(as_string, r#"{"time":1526522699918355733}"#);
+ /// # Ok::<(), serde_json::Error>(())
+ /// ```
+ pub fn serialize<S>(opt: &Option<NaiveDateTime>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ match *opt {
+ Some(ref dt) => serializer.serialize_some(&dt.timestamp_nanos()),
+ None => serializer.serialize_none(),
+ }
+ }
+
+ /// Deserialize a `NaiveDateTime` from a nanosecond timestamp or none
+ ///
+ /// Intended for use with `serde`s `deserialize_with` attribute.
+ ///
+ /// # Example:
+ ///
+ /// ```rust
+ /// # use chrono::naive::{NaiveDate, NaiveDateTime};
+ /// # use serde_derive::Deserialize;
+ /// use chrono::naive::serde::ts_nanoseconds_option::deserialize as from_nano_tsopt;
+ /// #[derive(Deserialize)]
+ /// struct S {
+ /// #[serde(deserialize_with = "from_nano_tsopt")]
+ /// time: Option<NaiveDateTime>
+ /// }
+ ///
+ /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355733 }"#)?;
+ /// # Ok::<(), serde_json::Error>(())
+ /// ```
+ pub fn deserialize<'de, D>(d: D) -> Result<Option<NaiveDateTime>, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ d.deserialize_option(OptionNanoSecondsTimestampVisitor)
+ }
+
+ struct OptionNanoSecondsTimestampVisitor;
+
+ impl<'de> de::Visitor<'de> for OptionNanoSecondsTimestampVisitor {
+ type Value = Option<NaiveDateTime>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a unix timestamp in nanoseconds or none")
+ }
+
+ /// Deserialize a timestamp in nanoseconds since the epoch
+ fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ d.deserialize_i64(NanoSecondsTimestampVisitor).map(Some)
+ }
+
+ /// Deserialize a timestamp in nanoseconds since the epoch
+ fn visit_none<E>(self) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(None)
+ }
+
+ /// Deserialize a timestamp in nanoseconds since the epoch
+ fn visit_unit<E>(self) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(None)
+ }
+ }
+}
+
+/// Used to serialize/deserialize from microsecond-precision timestamps
+///
+/// # Example:
+///
+/// ```rust
+/// # use chrono::{NaiveDate, NaiveDateTime};
+/// # use serde_derive::{Deserialize, Serialize};
+/// use chrono::naive::serde::ts_microseconds;
+/// #[derive(Deserialize, Serialize)]
+/// struct S {
+/// #[serde(with = "ts_microseconds")]
+/// time: NaiveDateTime
+/// }
+///
+/// let time = NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_micro_opt(02, 04, 59, 918355).unwrap();
+/// let my_s = S {
+/// time: time.clone(),
+/// };
+///
+/// let as_string = serde_json::to_string(&my_s)?;
+/// assert_eq!(as_string, r#"{"time":1526522699918355}"#);
+/// let my_s: S = serde_json::from_str(&as_string)?;
+/// assert_eq!(my_s.time, time);
+/// # Ok::<(), serde_json::Error>(())
+/// ```
+pub mod ts_microseconds {
+ use core::fmt;
+ use serde::{de, ser};
+
+ use super::ne_timestamp;
+ use crate::NaiveDateTime;
+
+ /// Serialize a datetime into an integer number of microseconds since the epoch
+ ///
+ /// Intended for use with `serde`s `serialize_with` attribute.
+ ///
+ /// # Example:
+ ///
+ /// ```rust
+ /// # use chrono::{NaiveDate, NaiveDateTime};
+ /// # use serde_derive::Serialize;
+ /// use chrono::naive::serde::ts_microseconds::serialize as to_micro_ts;
+ /// #[derive(Serialize)]
+ /// struct S {
+ /// #[serde(serialize_with = "to_micro_ts")]
+ /// time: NaiveDateTime
+ /// }
+ ///
+ /// let my_s = S {
+ /// time: NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_micro_opt(02, 04, 59, 918355).unwrap(),
+ /// };
+ /// let as_string = serde_json::to_string(&my_s)?;
+ /// assert_eq!(as_string, r#"{"time":1526522699918355}"#);
+ /// # Ok::<(), serde_json::Error>(())
+ /// ```
+ pub fn serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ serializer.serialize_i64(dt.timestamp_micros())
+ }
+
+ /// Deserialize a `NaiveDateTime` from a microseconds timestamp
+ ///
+ /// Intended for use with `serde`s `deserialize_with` attribute.
+ ///
+ /// # Example:
+ ///
+ /// ```rust
+ /// # use chrono::NaiveDateTime;
+ /// # use serde_derive::Deserialize;
+ /// use chrono::naive::serde::ts_microseconds::deserialize as from_micro_ts;
+ /// #[derive(Deserialize)]
+ /// struct S {
+ /// #[serde(deserialize_with = "from_micro_ts")]
+ /// time: NaiveDateTime
+ /// }
+ ///
+ /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355 }"#)?;
+ /// # Ok::<(), serde_json::Error>(())
+ /// ```
+ pub fn deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ d.deserialize_i64(MicroSecondsTimestampVisitor)
+ }
+
+ pub(super) struct MicroSecondsTimestampVisitor;
+
+ impl<'de> de::Visitor<'de> for MicroSecondsTimestampVisitor {
+ type Value = NaiveDateTime;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a unix timestamp")
+ }
+
+ fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ NaiveDateTime::from_timestamp_opt(
+ value / 1_000_000,
+ ((value % 1_000_000) * 1000) as u32,
+ )
+ .ok_or_else(|| E::custom(ne_timestamp(value)))
+ }
+
+ fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ NaiveDateTime::from_timestamp_opt(
+ (value / 1_000_000) as i64,
+ ((value % 1_000_000) * 1_000) as u32,
+ )
+ .ok_or_else(|| E::custom(ne_timestamp(value)))
+ }
+ }
+}
+
+/// Ser/de to/from optional timestamps in microseconds
+///
+/// Intended for use with `serde`'s `with` attribute.
+///
+/// # Example:
+///
+/// ```rust
+/// # use chrono::naive::{NaiveDate, NaiveDateTime};
+/// # use serde_derive::{Deserialize, Serialize};
+/// use chrono::naive::serde::ts_microseconds_option;
+/// #[derive(Deserialize, Serialize)]
+/// struct S {
+/// #[serde(with = "ts_microseconds_option")]
+/// time: Option<NaiveDateTime>
+/// }
+///
+/// let time = Some(NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_micro_opt(02, 04, 59, 918355).unwrap());
+/// let my_s = S {
+/// time: time.clone(),
+/// };
+///
+/// let as_string = serde_json::to_string(&my_s)?;
+/// assert_eq!(as_string, r#"{"time":1526522699918355}"#);
+/// let my_s: S = serde_json::from_str(&as_string)?;
+/// assert_eq!(my_s.time, time);
+/// # Ok::<(), serde_json::Error>(())
+/// ```
+pub mod ts_microseconds_option {
+ use core::fmt;
+ use serde::{de, ser};
+
+ use super::ts_microseconds::MicroSecondsTimestampVisitor;
+ use crate::NaiveDateTime;
+
+ /// Serialize a datetime into an integer number of microseconds since the epoch or none
+ ///
+ /// Intended for use with `serde`s `serialize_with` attribute.
+ ///
+ /// # Example:
+ ///
+ /// ```rust
+ /// # use chrono::naive::{NaiveDate, NaiveDateTime};
+ /// # use serde_derive::Serialize;
+ /// use chrono::naive::serde::ts_microseconds_option::serialize as to_micro_tsopt;
+ /// #[derive(Serialize)]
+ /// struct S {
+ /// #[serde(serialize_with = "to_micro_tsopt")]
+ /// time: Option<NaiveDateTime>
+ /// }
+ ///
+ /// let my_s = S {
+ /// time: Some(NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_micro_opt(02, 04, 59, 918355).unwrap()),
+ /// };
+ /// let as_string = serde_json::to_string(&my_s)?;
+ /// assert_eq!(as_string, r#"{"time":1526522699918355}"#);
+ /// # Ok::<(), serde_json::Error>(())
+ /// ```
+ pub fn serialize<S>(opt: &Option<NaiveDateTime>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ match *opt {
+ Some(ref dt) => serializer.serialize_some(&dt.timestamp_micros()),
+ None => serializer.serialize_none(),
+ }
+ }
+
+ /// Deserialize a `NaiveDateTime` from a nanosecond timestamp or none
+ ///
+ /// Intended for use with `serde`s `deserialize_with` attribute.
+ ///
+ /// # Example:
+ ///
+ /// ```rust
+ /// # use chrono::naive::{NaiveDate, NaiveDateTime};
+ /// # use serde_derive::Deserialize;
+ /// use chrono::naive::serde::ts_microseconds_option::deserialize as from_micro_tsopt;
+ /// #[derive(Deserialize)]
+ /// struct S {
+ /// #[serde(deserialize_with = "from_micro_tsopt")]
+ /// time: Option<NaiveDateTime>
+ /// }
+ ///
+ /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355 }"#)?;
+ /// # Ok::<(), serde_json::Error>(())
+ /// ```
+ pub fn deserialize<'de, D>(d: D) -> Result<Option<NaiveDateTime>, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ d.deserialize_option(OptionMicroSecondsTimestampVisitor)
+ }
+
+ struct OptionMicroSecondsTimestampVisitor;
+
+ impl<'de> de::Visitor<'de> for OptionMicroSecondsTimestampVisitor {
+ type Value = Option<NaiveDateTime>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a unix timestamp in microseconds or none")
+ }
+
+ /// Deserialize a timestamp in microseconds since the epoch
+ fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ d.deserialize_i64(MicroSecondsTimestampVisitor).map(Some)
+ }
+
+ /// Deserialize a timestamp in microseconds since the epoch
+ fn visit_none<E>(self) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(None)
+ }
+
+ /// Deserialize a timestamp in microseconds since the epoch
+ fn visit_unit<E>(self) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(None)
+ }
+ }
+}
+
+/// Used to serialize/deserialize from millisecond-precision timestamps
+///
+/// # Example:
+///
+/// ```rust
+/// # use chrono::{NaiveDate, NaiveDateTime};
+/// # use serde_derive::{Deserialize, Serialize};
+/// use chrono::naive::serde::ts_milliseconds;
+/// #[derive(Deserialize, Serialize)]
+/// struct S {
+/// #[serde(with = "ts_milliseconds")]
+/// time: NaiveDateTime
+/// }
+///
+/// let time = NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_milli_opt(02, 04, 59, 918).unwrap();
+/// let my_s = S {
+/// time: time.clone(),
+/// };
+///
+/// let as_string = serde_json::to_string(&my_s)?;
+/// assert_eq!(as_string, r#"{"time":1526522699918}"#);
+/// let my_s: S = serde_json::from_str(&as_string)?;
+/// assert_eq!(my_s.time, time);
+/// # Ok::<(), serde_json::Error>(())
+/// ```
+pub mod ts_milliseconds {
+ use core::fmt;
+ use serde::{de, ser};
+
+ use super::ne_timestamp;
+ use crate::NaiveDateTime;
+
+ /// Serialize a datetime into an integer number of milliseconds since the epoch
+ ///
+ /// Intended for use with `serde`s `serialize_with` attribute.
+ ///
+ /// # Example:
+ ///
+ /// ```rust
+ /// # use chrono::{NaiveDate, NaiveDateTime};
+ /// # use serde_derive::Serialize;
+ /// use chrono::naive::serde::ts_milliseconds::serialize as to_milli_ts;
+ /// #[derive(Serialize)]
+ /// struct S {
+ /// #[serde(serialize_with = "to_milli_ts")]
+ /// time: NaiveDateTime
+ /// }
+ ///
+ /// let my_s = S {
+ /// time: NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_milli_opt(02, 04, 59, 918).unwrap(),
+ /// };
+ /// let as_string = serde_json::to_string(&my_s)?;
+ /// assert_eq!(as_string, r#"{"time":1526522699918}"#);
+ /// # Ok::<(), serde_json::Error>(())
+ /// ```
+ pub fn serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ serializer.serialize_i64(dt.timestamp_millis())
+ }
+
+ /// Deserialize a `NaiveDateTime` from a milliseconds timestamp
+ ///
+ /// Intended for use with `serde`s `deserialize_with` attribute.
+ ///
+ /// # Example:
+ ///
+ /// ```rust
+ /// # use chrono::NaiveDateTime;
+ /// # use serde_derive::Deserialize;
+ /// use chrono::naive::serde::ts_milliseconds::deserialize as from_milli_ts;
+ /// #[derive(Deserialize)]
+ /// struct S {
+ /// #[serde(deserialize_with = "from_milli_ts")]
+ /// time: NaiveDateTime
+ /// }
+ ///
+ /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918 }"#)?;
+ /// # Ok::<(), serde_json::Error>(())
+ /// ```
+ pub fn deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ d.deserialize_i64(MilliSecondsTimestampVisitor)
+ }
+
+ pub(super) struct MilliSecondsTimestampVisitor;
+
+ impl<'de> de::Visitor<'de> for MilliSecondsTimestampVisitor {
+ type Value = NaiveDateTime;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a unix timestamp")
+ }
+
+ fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ NaiveDateTime::from_timestamp_opt(value / 1000, ((value % 1000) * 1_000_000) as u32)
+ .ok_or_else(|| E::custom(ne_timestamp(value)))
+ }
+
+ fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ NaiveDateTime::from_timestamp_opt(
+ (value / 1000) as i64,
+ ((value % 1000) * 1_000_000) as u32,
+ )
+ .ok_or_else(|| E::custom(ne_timestamp(value)))
+ }
+ }
+}
+
+/// Ser/de to/from optional timestamps in milliseconds
+///
+/// Intended for use with `serde`'s `with` attribute.
+///
+/// # Example:
+///
+/// ```rust
+/// # use chrono::naive::{NaiveDate, NaiveDateTime};
+/// # use serde_derive::{Deserialize, Serialize};
+/// use chrono::naive::serde::ts_milliseconds_option;
+/// #[derive(Deserialize, Serialize)]
+/// struct S {
+/// #[serde(with = "ts_milliseconds_option")]
+/// time: Option<NaiveDateTime>
+/// }
+///
+/// let time = Some(NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_milli_opt(02, 04, 59, 918).unwrap());
+/// let my_s = S {
+/// time: time.clone(),
+/// };
+///
+/// let as_string = serde_json::to_string(&my_s)?;
+/// assert_eq!(as_string, r#"{"time":1526522699918}"#);
+/// let my_s: S = serde_json::from_str(&as_string)?;
+/// assert_eq!(my_s.time, time);
+/// # Ok::<(), serde_json::Error>(())
+/// ```
+pub mod ts_milliseconds_option {
+ use core::fmt;
+ use serde::{de, ser};
+
+ use super::ts_milliseconds::MilliSecondsTimestampVisitor;
+ use crate::NaiveDateTime;
+
+ /// Serialize a datetime into an integer number of milliseconds since the epoch or none
+ ///
+ /// Intended for use with `serde`s `serialize_with` attribute.
+ ///
+ /// # Example:
+ ///
+ /// ```rust
+ /// # use chrono::naive::{NaiveDate, NaiveDateTime};
+ /// # use serde_derive::Serialize;
+ /// use chrono::naive::serde::ts_milliseconds_option::serialize as to_milli_tsopt;
+ /// #[derive(Serialize)]
+ /// struct S {
+ /// #[serde(serialize_with = "to_milli_tsopt")]
+ /// time: Option<NaiveDateTime>
+ /// }
+ ///
+ /// let my_s = S {
+ /// time: Some(NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_milli_opt(02, 04, 59, 918).unwrap()),
+ /// };
+ /// let as_string = serde_json::to_string(&my_s)?;
+ /// assert_eq!(as_string, r#"{"time":1526522699918}"#);
+ /// # Ok::<(), serde_json::Error>(())
+ /// ```
+ pub fn serialize<S>(opt: &Option<NaiveDateTime>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ match *opt {
+ Some(ref dt) => serializer.serialize_some(&dt.timestamp_millis()),
+ None => serializer.serialize_none(),
+ }
+ }
+
+ /// Deserialize a `NaiveDateTime` from a nanosecond timestamp or none
+ ///
+ /// Intended for use with `serde`s `deserialize_with` attribute.
+ ///
+ /// # Example:
+ ///
+ /// ```rust
+ /// # use chrono::naive::{NaiveDate, NaiveDateTime};
+ /// # use serde_derive::Deserialize;
+ /// use chrono::naive::serde::ts_milliseconds_option::deserialize as from_milli_tsopt;
+ /// #[derive(Deserialize)]
+ /// struct S {
+ /// #[serde(deserialize_with = "from_milli_tsopt")]
+ /// time: Option<NaiveDateTime>
+ /// }
+ ///
+ /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355 }"#)?;
+ /// # Ok::<(), serde_json::Error>(())
+ /// ```
+ pub fn deserialize<'de, D>(d: D) -> Result<Option<NaiveDateTime>, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ d.deserialize_option(OptionMilliSecondsTimestampVisitor)
+ }
+
+ struct OptionMilliSecondsTimestampVisitor;
+
+ impl<'de> de::Visitor<'de> for OptionMilliSecondsTimestampVisitor {
+ type Value = Option<NaiveDateTime>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a unix timestamp in milliseconds or none")
+ }
+
+ /// Deserialize a timestamp in milliseconds since the epoch
+ fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ d.deserialize_i64(MilliSecondsTimestampVisitor).map(Some)
+ }
+
+ /// Deserialize a timestamp in milliseconds since the epoch
+ fn visit_none<E>(self) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(None)
+ }
+
+ /// Deserialize a timestamp in milliseconds since the epoch
+ fn visit_unit<E>(self) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(None)
+ }
+ }
+}
+
+/// Used to serialize/deserialize from second-precision timestamps
+///
+/// # Example:
+///
+/// ```rust
+/// # use chrono::{NaiveDate, NaiveDateTime};
+/// # use serde_derive::{Deserialize, Serialize};
+/// use chrono::naive::serde::ts_seconds;
+/// #[derive(Deserialize, Serialize)]
+/// struct S {
+/// #[serde(with = "ts_seconds")]
+/// time: NaiveDateTime
+/// }
+///
+/// let time = NaiveDate::from_ymd_opt(2015, 5, 15).unwrap().and_hms_opt(10, 0, 0).unwrap();
+/// let my_s = S {
+/// time: time.clone(),
+/// };
+///
+/// let as_string = serde_json::to_string(&my_s)?;
+/// assert_eq!(as_string, r#"{"time":1431684000}"#);
+/// let my_s: S = serde_json::from_str(&as_string)?;
+/// assert_eq!(my_s.time, time);
+/// # Ok::<(), serde_json::Error>(())
+/// ```
+pub mod ts_seconds {
+ use core::fmt;
+ use serde::{de, ser};
+
+ use super::ne_timestamp;
+ use crate::NaiveDateTime;
+
+ /// Serialize a datetime into an integer number of seconds since the epoch
+ ///
+ /// Intended for use with `serde`s `serialize_with` attribute.
+ ///
+ /// # Example:
+ ///
+ /// ```rust
+ /// # use chrono::{NaiveDate, NaiveDateTime};
+ /// # use serde_derive::Serialize;
+ /// use chrono::naive::serde::ts_seconds::serialize as to_ts;
+ /// #[derive(Serialize)]
+ /// struct S {
+ /// #[serde(serialize_with = "to_ts")]
+ /// time: NaiveDateTime
+ /// }
+ ///
+ /// let my_s = S {
+ /// time: NaiveDate::from_ymd_opt(2015, 5, 15).unwrap().and_hms_opt(10, 0, 0).unwrap(),
+ /// };
+ /// let as_string = serde_json::to_string(&my_s)?;
+ /// assert_eq!(as_string, r#"{"time":1431684000}"#);
+ /// # Ok::<(), serde_json::Error>(())
+ /// ```
+ pub fn serialize<S>(dt: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ serializer.serialize_i64(dt.timestamp())
+ }
+
+ /// Deserialize a `NaiveDateTime` from a seconds timestamp
+ ///
+ /// Intended for use with `serde`s `deserialize_with` attribute.
+ ///
+ /// # Example:
+ ///
+ /// ```rust
+ /// # use chrono::NaiveDateTime;
+ /// # use serde_derive::Deserialize;
+ /// use chrono::naive::serde::ts_seconds::deserialize as from_ts;
+ /// #[derive(Deserialize)]
+ /// struct S {
+ /// #[serde(deserialize_with = "from_ts")]
+ /// time: NaiveDateTime
+ /// }
+ ///
+ /// let my_s: S = serde_json::from_str(r#"{ "time": 1431684000 }"#)?;
+ /// # Ok::<(), serde_json::Error>(())
+ /// ```
+ pub fn deserialize<'de, D>(d: D) -> Result<NaiveDateTime, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ d.deserialize_i64(SecondsTimestampVisitor)
+ }
+
+ pub(super) struct SecondsTimestampVisitor;
+
+ impl<'de> de::Visitor<'de> for SecondsTimestampVisitor {
+ type Value = NaiveDateTime;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a unix timestamp")
+ }
+
+ fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ NaiveDateTime::from_timestamp_opt(value, 0)
+ .ok_or_else(|| E::custom(ne_timestamp(value)))
+ }
+
+ fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ NaiveDateTime::from_timestamp_opt(value as i64, 0)
+ .ok_or_else(|| E::custom(ne_timestamp(value)))
+ }
+ }
+}
+
+/// Ser/de to/from optional timestamps in seconds
+///
+/// Intended for use with `serde`'s `with` attribute.
+///
+/// # Example:
+///
+/// ```rust
+/// # use chrono::naive::{NaiveDate, NaiveDateTime};
+/// # use serde_derive::{Deserialize, Serialize};
+/// use chrono::naive::serde::ts_seconds_option;
+/// #[derive(Deserialize, Serialize)]
+/// struct S {
+/// #[serde(with = "ts_seconds_option")]
+/// time: Option<NaiveDateTime>
+/// }
+///
+/// let time = Some(NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_opt(02, 04, 59).unwrap());
+/// let my_s = S {
+/// time: time.clone(),
+/// };
+///
+/// let as_string = serde_json::to_string(&my_s)?;
+/// assert_eq!(as_string, r#"{"time":1526522699}"#);
+/// let my_s: S = serde_json::from_str(&as_string)?;
+/// assert_eq!(my_s.time, time);
+/// # Ok::<(), serde_json::Error>(())
+/// ```
+pub mod ts_seconds_option {
+ use core::fmt;
+ use serde::{de, ser};
+
+ use super::ts_seconds::SecondsTimestampVisitor;
+ use crate::NaiveDateTime;
+
+ /// Serialize a datetime into an integer number of seconds since the epoch or none
+ ///
+ /// Intended for use with `serde`s `serialize_with` attribute.
+ ///
+ /// # Example:
+ ///
+ /// ```rust
+ /// # use chrono::naive::{NaiveDate, NaiveDateTime};
+ /// # use serde_derive::Serialize;
+ /// use chrono::naive::serde::ts_seconds_option::serialize as to_tsopt;
+ /// #[derive(Serialize)]
+ /// struct S {
+ /// #[serde(serialize_with = "to_tsopt")]
+ /// time: Option<NaiveDateTime>
+ /// }
+ ///
+ /// let my_s = S {
+ /// time: Some(NaiveDate::from_ymd_opt(2018, 5, 17).unwrap().and_hms_opt(02, 04, 59).unwrap()),
+ /// };
+ /// let as_string = serde_json::to_string(&my_s)?;
+ /// assert_eq!(as_string, r#"{"time":1526522699}"#);
+ /// # Ok::<(), serde_json::Error>(())
+ /// ```
+ pub fn serialize<S>(opt: &Option<NaiveDateTime>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ match *opt {
+ Some(ref dt) => serializer.serialize_some(&dt.timestamp()),
+ None => serializer.serialize_none(),
+ }
+ }
+
+ /// Deserialize a `NaiveDateTime` from a second timestamp or none
+ ///
+ /// Intended for use with `serde`s `deserialize_with` attribute.
+ ///
+ /// # Example:
+ ///
+ /// ```rust
+ /// # use chrono::naive::{NaiveDate, NaiveDateTime};
+ /// # use serde_derive::Deserialize;
+ /// use chrono::naive::serde::ts_seconds_option::deserialize as from_tsopt;
+ /// #[derive(Deserialize)]
+ /// struct S {
+ /// #[serde(deserialize_with = "from_tsopt")]
+ /// time: Option<NaiveDateTime>
+ /// }
+ ///
+ /// let my_s: S = serde_json::from_str(r#"{ "time": 1431684000 }"#)?;
+ /// # Ok::<(), serde_json::Error>(())
+ /// ```
+ pub fn deserialize<'de, D>(d: D) -> Result<Option<NaiveDateTime>, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ d.deserialize_option(OptionSecondsTimestampVisitor)
+ }
+
+ struct OptionSecondsTimestampVisitor;
+
+ impl<'de> de::Visitor<'de> for OptionSecondsTimestampVisitor {
+ type Value = Option<NaiveDateTime>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a unix timestamp in seconds or none")
+ }
+
+ /// Deserialize a timestamp in seconds since the epoch
+ fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ d.deserialize_i64(SecondsTimestampVisitor).map(Some)
+ }
+
+ /// Deserialize a timestamp in seconds since the epoch
+ fn visit_none<E>(self) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(None)
+ }
+
+ /// Deserialize a timestamp in seconds since the epoch
+ fn visit_unit<E>(self) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(None)
+ }
+ }
+}
+
+#[test]
+fn test_serde_serialize() {
+ super::test_encodable_json(serde_json::to_string);
+}
+
+#[test]
+fn test_serde_deserialize() {
+ super::test_decodable_json(|input| serde_json::from_str(input));
+}
+
+// Bincode is relevant to test separately from JSON because
+// it is not self-describing.
+#[test]
+fn test_serde_bincode() {
+ use crate::NaiveDate;
+ use bincode::{deserialize, serialize};
+
+ let dt = NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_milli_opt(9, 10, 48, 90).unwrap();
+ let encoded = serialize(&dt).unwrap();
+ let decoded: NaiveDateTime = deserialize(&encoded).unwrap();
+ assert_eq!(dt, decoded);
+}
+
+#[test]
+fn test_serde_bincode_optional() {
+ use crate::prelude::*;
+ use crate::serde::ts_nanoseconds_option;
+ use bincode::{deserialize, serialize};
+ use serde_derive::{Deserialize, Serialize};
+
+ #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
+ struct Test {
+ one: Option<i64>,
+ #[serde(with = "ts_nanoseconds_option")]
+ two: Option<DateTime<Utc>>,
+ }
+
+ let expected =
+ Test { one: Some(1), two: Some(Utc.with_ymd_and_hms(1970, 1, 1, 0, 1, 1).unwrap()) };
+ let bytes: Vec<u8> = serialize(&expected).unwrap();
+ let actual = deserialize::<Test>(&(bytes)).unwrap();
+
+ assert_eq!(expected, actual);
+}
+
+// lik? function to convert a LocalResult into a serde-ish Result
+pub(crate) fn serde_from<T, E, V>(me: LocalResult<T>, ts: &V) -> Result<T, E>
+where
+ E: de::Error,
+ V: fmt::Display,
+ T: fmt::Display,
+{
+ match me {
+ LocalResult::None => Err(E::custom(ne_timestamp(ts))),
+ LocalResult::Ambiguous(min, max) => {
+ Err(E::custom(SerdeError::Ambiguous { timestamp: ts, min, max }))
+ }
+ LocalResult::Single(val) => Ok(val),
+ }
+}
+
+enum SerdeError<V: fmt::Display, D: fmt::Display> {
+ NonExistent { timestamp: V },
+ Ambiguous { timestamp: V, min: D, max: D },
+}
+
+/// Construct a [`SerdeError::NonExistent`]
+fn ne_timestamp<T: fmt::Display>(ts: T) -> SerdeError<T, u8> {
+ SerdeError::NonExistent::<T, u8> { timestamp: ts }
+}
+
+impl<V: fmt::Display, D: fmt::Display> fmt::Debug for SerdeError<V, D> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "ChronoSerdeError({})", self)
+ }
+}
+
+// impl<V: fmt::Display, D: fmt::Debug> core::error::Error for SerdeError<V, D> {}
+impl<V: fmt::Display, D: fmt::Display> fmt::Display for SerdeError<V, D> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ SerdeError::NonExistent { timestamp } => {
+ write!(f, "value is not a legal timestamp: {}", timestamp)
+ }
+ SerdeError::Ambiguous { timestamp, min, max } => write!(
+ f,
+ "value is an ambiguous timestamp: {}, could be either of {}, {}",
+ timestamp, min, max
+ ),
+ }
+ }
+}
diff --git a/vendor/chrono/src/naive/datetime/tests.rs b/vendor/chrono/src/naive/datetime/tests.rs
new file mode 100644
index 000000000..202bdb34d
--- /dev/null
+++ b/vendor/chrono/src/naive/datetime/tests.rs
@@ -0,0 +1,343 @@
+use super::NaiveDateTime;
+use crate::oldtime::Duration;
+use crate::NaiveDate;
+use crate::{Datelike, FixedOffset, Utc};
+use std::i64;
+
+#[test]
+fn test_datetime_from_timestamp_millis() {
+ let valid_map = [
+ (1662921288000, "2022-09-11 18:34:48.000000000"),
+ (1662921288123, "2022-09-11 18:34:48.123000000"),
+ (1662921287890, "2022-09-11 18:34:47.890000000"),
+ (-2208936075000, "1900-01-01 14:38:45.000000000"),
+ (0, "1970-01-01 00:00:00.000000000"),
+ (119731017000, "1973-10-17 18:36:57.000000000"),
+ (1234567890000, "2009-02-13 23:31:30.000000000"),
+ (2034061609000, "2034-06-16 09:06:49.000000000"),
+ ];
+
+ for (timestamp_millis, formatted) in valid_map.iter().copied() {
+ let naive_datetime = NaiveDateTime::from_timestamp_millis(timestamp_millis);
+ assert_eq!(timestamp_millis, naive_datetime.unwrap().timestamp_millis());
+ assert_eq!(naive_datetime.unwrap().format("%F %T%.9f").to_string(), formatted);
+ }
+
+ let invalid = [i64::MAX, i64::MIN];
+
+ for timestamp_millis in invalid.iter().copied() {
+ let naive_datetime = NaiveDateTime::from_timestamp_millis(timestamp_millis);
+ assert!(naive_datetime.is_none());
+ }
+
+ // Test that the result of `from_timestamp_millis` compares equal to
+ // that of `from_timestamp_opt`.
+ let secs_test = [0, 1, 2, 1000, 1234, 12345678, -1, -2, -1000, -12345678];
+ for secs in secs_test.iter().cloned() {
+ assert_eq!(
+ NaiveDateTime::from_timestamp_millis(secs * 1000),
+ NaiveDateTime::from_timestamp_opt(secs, 0)
+ );
+ }
+}
+
+#[test]
+fn test_datetime_from_timestamp_micros() {
+ let valid_map = [
+ (1662921288000000, "2022-09-11 18:34:48.000000000"),
+ (1662921288123456, "2022-09-11 18:34:48.123456000"),
+ (1662921287890000, "2022-09-11 18:34:47.890000000"),
+ (-2208936075000000, "1900-01-01 14:38:45.000000000"),
+ (0, "1970-01-01 00:00:00.000000000"),
+ (119731017000000, "1973-10-17 18:36:57.000000000"),
+ (1234567890000000, "2009-02-13 23:31:30.000000000"),
+ (2034061609000000, "2034-06-16 09:06:49.000000000"),
+ ];
+
+ for (timestamp_micros, formatted) in valid_map.iter().copied() {
+ let naive_datetime = NaiveDateTime::from_timestamp_micros(timestamp_micros);
+ assert_eq!(timestamp_micros, naive_datetime.unwrap().timestamp_micros());
+ assert_eq!(naive_datetime.unwrap().format("%F %T%.9f").to_string(), formatted);
+ }
+
+ let invalid = [i64::MAX, i64::MIN];
+
+ for timestamp_micros in invalid.iter().copied() {
+ let naive_datetime = NaiveDateTime::from_timestamp_micros(timestamp_micros);
+ assert!(naive_datetime.is_none());
+ }
+
+ // Test that the result of `from_timestamp_micros` compares equal to
+ // that of `from_timestamp_opt`.
+ let secs_test = [0, 1, 2, 1000, 1234, 12345678, -1, -2, -1000, -12345678];
+ for secs in secs_test.iter().copied() {
+ assert_eq!(
+ NaiveDateTime::from_timestamp_micros(secs * 1_000_000),
+ NaiveDateTime::from_timestamp_opt(secs, 0)
+ );
+ }
+}
+
+#[test]
+fn test_datetime_from_timestamp() {
+ let from_timestamp = |secs| NaiveDateTime::from_timestamp_opt(secs, 0);
+ let ymdhms =
+ |y, m, d, h, n, s| NaiveDate::from_ymd_opt(y, m, d).unwrap().and_hms_opt(h, n, s).unwrap();
+ assert_eq!(from_timestamp(-1), Some(ymdhms(1969, 12, 31, 23, 59, 59)));
+ assert_eq!(from_timestamp(0), Some(ymdhms(1970, 1, 1, 0, 0, 0)));
+ assert_eq!(from_timestamp(1), Some(ymdhms(1970, 1, 1, 0, 0, 1)));
+ assert_eq!(from_timestamp(1_000_000_000), Some(ymdhms(2001, 9, 9, 1, 46, 40)));
+ assert_eq!(from_timestamp(0x7fffffff), Some(ymdhms(2038, 1, 19, 3, 14, 7)));
+ assert_eq!(from_timestamp(i64::MIN), None);
+ assert_eq!(from_timestamp(i64::MAX), None);
+}
+
+#[test]
+fn test_datetime_add() {
+ fn check(
+ (y, m, d, h, n, s): (i32, u32, u32, u32, u32, u32),
+ rhs: Duration,
+ result: Option<(i32, u32, u32, u32, u32, u32)>,
+ ) {
+ let lhs = NaiveDate::from_ymd_opt(y, m, d).unwrap().and_hms_opt(h, n, s).unwrap();
+ let sum = result.map(|(y, m, d, h, n, s)| {
+ NaiveDate::from_ymd_opt(y, m, d).unwrap().and_hms_opt(h, n, s).unwrap()
+ });
+ assert_eq!(lhs.checked_add_signed(rhs), sum);
+ assert_eq!(lhs.checked_sub_signed(-rhs), sum);
+ }
+
+ check((2014, 5, 6, 7, 8, 9), Duration::seconds(3600 + 60 + 1), Some((2014, 5, 6, 8, 9, 10)));
+ check((2014, 5, 6, 7, 8, 9), Duration::seconds(-(3600 + 60 + 1)), Some((2014, 5, 6, 6, 7, 8)));
+ check((2014, 5, 6, 7, 8, 9), Duration::seconds(86399), Some((2014, 5, 7, 7, 8, 8)));
+ check((2014, 5, 6, 7, 8, 9), Duration::seconds(86_400 * 10), Some((2014, 5, 16, 7, 8, 9)));
+ check((2014, 5, 6, 7, 8, 9), Duration::seconds(-86_400 * 10), Some((2014, 4, 26, 7, 8, 9)));
+ check((2014, 5, 6, 7, 8, 9), Duration::seconds(86_400 * 10), Some((2014, 5, 16, 7, 8, 9)));
+
+ // overflow check
+ // assumes that we have correct values for MAX/MIN_DAYS_FROM_YEAR_0 from `naive::date`.
+ // (they are private constants, but the equivalence is tested in that module.)
+ let max_days_from_year_0 =
+ NaiveDate::MAX.signed_duration_since(NaiveDate::from_ymd_opt(0, 1, 1).unwrap());
+ check((0, 1, 1, 0, 0, 0), max_days_from_year_0, Some((NaiveDate::MAX.year(), 12, 31, 0, 0, 0)));
+ check(
+ (0, 1, 1, 0, 0, 0),
+ max_days_from_year_0 + Duration::seconds(86399),
+ Some((NaiveDate::MAX.year(), 12, 31, 23, 59, 59)),
+ );
+ check((0, 1, 1, 0, 0, 0), max_days_from_year_0 + Duration::seconds(86_400), None);
+ check((0, 1, 1, 0, 0, 0), Duration::max_value(), None);
+
+ let min_days_from_year_0 =
+ NaiveDate::MIN.signed_duration_since(NaiveDate::from_ymd_opt(0, 1, 1).unwrap());
+ check((0, 1, 1, 0, 0, 0), min_days_from_year_0, Some((NaiveDate::MIN.year(), 1, 1, 0, 0, 0)));
+ check((0, 1, 1, 0, 0, 0), min_days_from_year_0 - Duration::seconds(1), None);
+ check((0, 1, 1, 0, 0, 0), Duration::min_value(), None);
+}
+
+#[test]
+fn test_datetime_sub() {
+ let ymdhms =
+ |y, m, d, h, n, s| NaiveDate::from_ymd_opt(y, m, d).unwrap().and_hms_opt(h, n, s).unwrap();
+ let since = NaiveDateTime::signed_duration_since;
+ assert_eq!(since(ymdhms(2014, 5, 6, 7, 8, 9), ymdhms(2014, 5, 6, 7, 8, 9)), Duration::zero());
+ assert_eq!(
+ since(ymdhms(2014, 5, 6, 7, 8, 10), ymdhms(2014, 5, 6, 7, 8, 9)),
+ Duration::seconds(1)
+ );
+ assert_eq!(
+ since(ymdhms(2014, 5, 6, 7, 8, 9), ymdhms(2014, 5, 6, 7, 8, 10)),
+ Duration::seconds(-1)
+ );
+ assert_eq!(
+ since(ymdhms(2014, 5, 7, 7, 8, 9), ymdhms(2014, 5, 6, 7, 8, 10)),
+ Duration::seconds(86399)
+ );
+ assert_eq!(
+ since(ymdhms(2001, 9, 9, 1, 46, 39), ymdhms(1970, 1, 1, 0, 0, 0)),
+ Duration::seconds(999_999_999)
+ );
+}
+
+#[test]
+fn test_datetime_addassignment() {
+ let ymdhms =
+ |y, m, d, h, n, s| NaiveDate::from_ymd_opt(y, m, d).unwrap().and_hms_opt(h, n, s).unwrap();
+ let mut date = ymdhms(2016, 10, 1, 10, 10, 10);
+ date += Duration::minutes(10_000_000);
+ assert_eq!(date, ymdhms(2035, 10, 6, 20, 50, 10));
+ date += Duration::days(10);
+ assert_eq!(date, ymdhms(2035, 10, 16, 20, 50, 10));
+}
+
+#[test]
+fn test_datetime_subassignment() {
+ let ymdhms =
+ |y, m, d, h, n, s| NaiveDate::from_ymd_opt(y, m, d).unwrap().and_hms_opt(h, n, s).unwrap();
+ let mut date = ymdhms(2016, 10, 1, 10, 10, 10);
+ date -= Duration::minutes(10_000_000);
+ assert_eq!(date, ymdhms(1997, 9, 26, 23, 30, 10));
+ date -= Duration::days(10);
+ assert_eq!(date, ymdhms(1997, 9, 16, 23, 30, 10));
+}
+
+#[test]
+fn test_datetime_timestamp() {
+ let to_timestamp = |y, m, d, h, n, s| {
+ NaiveDate::from_ymd_opt(y, m, d).unwrap().and_hms_opt(h, n, s).unwrap().timestamp()
+ };
+ assert_eq!(to_timestamp(1969, 12, 31, 23, 59, 59), -1);
+ assert_eq!(to_timestamp(1970, 1, 1, 0, 0, 0), 0);
+ assert_eq!(to_timestamp(1970, 1, 1, 0, 0, 1), 1);
+ assert_eq!(to_timestamp(2001, 9, 9, 1, 46, 40), 1_000_000_000);
+ assert_eq!(to_timestamp(2038, 1, 19, 3, 14, 7), 0x7fffffff);
+}
+
+#[test]
+fn test_datetime_from_str() {
+ // valid cases
+ let valid = [
+ "2015-2-18T23:16:9.15",
+ "-77-02-18T23:16:09",
+ " +82701 - 05 - 6 T 15 : 9 : 60.898989898989 ",
+ ];
+ for &s in &valid {
+ let d = match s.parse::<NaiveDateTime>() {
+ Ok(d) => d,
+ Err(e) => panic!("parsing `{}` has failed: {}", s, e),
+ };
+ let s_ = format!("{:?}", d);
+ // `s` and `s_` may differ, but `s.parse()` and `s_.parse()` must be same
+ let d_ = match s_.parse::<NaiveDateTime>() {
+ Ok(d) => d,
+ Err(e) => {
+ panic!("`{}` is parsed into `{:?}`, but reparsing that has failed: {}", s, d, e)
+ }
+ };
+ assert!(
+ d == d_,
+ "`{}` is parsed into `{:?}`, but reparsed result \
+ `{:?}` does not match",
+ s,
+ d,
+ d_
+ );
+ }
+
+ // some invalid cases
+ // since `ParseErrorKind` is private, all we can do is to check if there was an error
+ assert!("".parse::<NaiveDateTime>().is_err());
+ assert!("x".parse::<NaiveDateTime>().is_err());
+ assert!("15".parse::<NaiveDateTime>().is_err());
+ assert!("15:8:9".parse::<NaiveDateTime>().is_err());
+ assert!("15-8-9".parse::<NaiveDateTime>().is_err());
+ assert!("2015-15-15T15:15:15".parse::<NaiveDateTime>().is_err());
+ assert!("2012-12-12T12:12:12x".parse::<NaiveDateTime>().is_err());
+ assert!("2012-123-12T12:12:12".parse::<NaiveDateTime>().is_err());
+ assert!("+ 82701-123-12T12:12:12".parse::<NaiveDateTime>().is_err());
+ assert!("+802701-123-12T12:12:12".parse::<NaiveDateTime>().is_err()); // out-of-bound
+}
+
+#[test]
+fn test_datetime_parse_from_str() {
+ let ymdhms =
+ |y, m, d, h, n, s| NaiveDate::from_ymd_opt(y, m, d).unwrap().and_hms_opt(h, n, s).unwrap();
+ let ymdhmsn = |y, m, d, h, n, s, nano| {
+ NaiveDate::from_ymd_opt(y, m, d).unwrap().and_hms_nano_opt(h, n, s, nano).unwrap()
+ };
+ assert_eq!(
+ NaiveDateTime::parse_from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
+ Ok(ymdhms(2014, 5, 7, 12, 34, 56))
+ ); // ignore offset
+ assert_eq!(
+ NaiveDateTime::parse_from_str("2015-W06-1 000000", "%G-W%V-%u%H%M%S"),
+ Ok(ymdhms(2015, 2, 2, 0, 0, 0))
+ );
+ assert_eq!(
+ NaiveDateTime::parse_from_str("Fri, 09 Aug 2013 23:54:35 GMT", "%a, %d %b %Y %H:%M:%S GMT"),
+ Ok(ymdhms(2013, 8, 9, 23, 54, 35))
+ );
+ assert!(NaiveDateTime::parse_from_str(
+ "Sat, 09 Aug 2013 23:54:35 GMT",
+ "%a, %d %b %Y %H:%M:%S GMT"
+ )
+ .is_err());
+ assert!(NaiveDateTime::parse_from_str("2014-5-7 12:3456", "%Y-%m-%d %H:%M:%S").is_err());
+ assert!(NaiveDateTime::parse_from_str("12:34:56", "%H:%M:%S").is_err()); // insufficient
+ assert_eq!(
+ NaiveDateTime::parse_from_str("1441497364", "%s"),
+ Ok(ymdhms(2015, 9, 5, 23, 56, 4))
+ );
+ assert_eq!(
+ NaiveDateTime::parse_from_str("1283929614.1234", "%s.%f"),
+ Ok(ymdhmsn(2010, 9, 8, 7, 6, 54, 1234))
+ );
+ assert_eq!(
+ NaiveDateTime::parse_from_str("1441497364.649", "%s%.3f"),
+ Ok(ymdhmsn(2015, 9, 5, 23, 56, 4, 649000000))
+ );
+ assert_eq!(
+ NaiveDateTime::parse_from_str("1497854303.087654", "%s%.6f"),
+ Ok(ymdhmsn(2017, 6, 19, 6, 38, 23, 87654000))
+ );
+ assert_eq!(
+ NaiveDateTime::parse_from_str("1437742189.918273645", "%s%.9f"),
+ Ok(ymdhmsn(2015, 7, 24, 12, 49, 49, 918273645))
+ );
+}
+
+#[test]
+fn test_datetime_format() {
+ let dt = NaiveDate::from_ymd_opt(2010, 9, 8).unwrap().and_hms_milli_opt(7, 6, 54, 321).unwrap();
+ assert_eq!(dt.format("%c").to_string(), "Wed Sep 8 07:06:54 2010");
+ assert_eq!(dt.format("%s").to_string(), "1283929614");
+ assert_eq!(dt.format("%t%n%%%n%t").to_string(), "\t\n%\n\t");
+
+ // a horror of leap second: coming near to you.
+ let dt =
+ NaiveDate::from_ymd_opt(2012, 6, 30).unwrap().and_hms_milli_opt(23, 59, 59, 1_000).unwrap();
+ assert_eq!(dt.format("%c").to_string(), "Sat Jun 30 23:59:60 2012");
+ assert_eq!(dt.format("%s").to_string(), "1341100799"); // not 1341100800, it's intentional.
+}
+
+#[test]
+fn test_datetime_add_sub_invariant() {
+ // issue #37
+ let base = NaiveDate::from_ymd_opt(2000, 1, 1).unwrap().and_hms_opt(0, 0, 0).unwrap();
+ let t = -946684799990000;
+ let time = base + Duration::microseconds(t);
+ assert_eq!(t, time.signed_duration_since(base).num_microseconds().unwrap());
+}
+
+#[test]
+fn test_nanosecond_range() {
+ const A_BILLION: i64 = 1_000_000_000;
+ let maximum = "2262-04-11T23:47:16.854775804";
+ let parsed: NaiveDateTime = maximum.parse().unwrap();
+ let nanos = parsed.timestamp_nanos();
+ assert_eq!(
+ parsed,
+ NaiveDateTime::from_timestamp_opt(nanos / A_BILLION, (nanos % A_BILLION) as u32).unwrap()
+ );
+
+ let minimum = "1677-09-21T00:12:44.000000000";
+ let parsed: NaiveDateTime = minimum.parse().unwrap();
+ let nanos = parsed.timestamp_nanos();
+ assert_eq!(
+ parsed,
+ NaiveDateTime::from_timestamp_opt(nanos / A_BILLION, (nanos % A_BILLION) as u32).unwrap()
+ );
+}
+
+#[test]
+fn test_and_timezone() {
+ let ndt = NaiveDate::from_ymd_opt(2022, 6, 15).unwrap().and_hms_opt(18, 59, 36).unwrap();
+ let dt_utc = ndt.and_local_timezone(Utc).unwrap();
+ assert_eq!(dt_utc.naive_local(), ndt);
+ assert_eq!(dt_utc.timezone(), Utc);
+
+ let offset_tz = FixedOffset::west_opt(4 * 3600).unwrap();
+ let dt_offset = ndt.and_local_timezone(offset_tz).unwrap();
+ assert_eq!(dt_offset.naive_local(), ndt);
+ assert_eq!(dt_offset.timezone(), offset_tz);
+}
diff --git a/vendor/chrono/src/naive/internals.rs b/vendor/chrono/src/naive/internals.rs
index 346063c37..05305b506 100644
--- a/vendor/chrono/src/naive/internals.rs
+++ b/vendor/chrono/src/naive/internals.rs
@@ -13,19 +13,18 @@
//! but the conversion keeps the valid value valid and the invalid value invalid
//! so that the user-facing `NaiveDate` can validate the input as late as possible.
-#![allow(dead_code)] // some internal methods have been left for consistency
#![cfg_attr(feature = "__internal_bench", allow(missing_docs))]
+use crate::Weekday;
use core::{fmt, i32};
-use div::{div_rem, mod_floor};
+use num_integer::{div_rem, mod_floor};
use num_traits::FromPrimitive;
-use Weekday;
/// The internal date representation. This also includes the packed `Mdf` value.
-pub type DateImpl = i32;
+pub(super) type DateImpl = i32;
-pub const MAX_YEAR: DateImpl = i32::MAX >> 13;
-pub const MIN_YEAR: DateImpl = i32::MIN >> 13;
+pub(super) const MAX_YEAR: DateImpl = i32::MAX >> 13;
+pub(super) const MIN_YEAR: DateImpl = i32::MIN >> 13;
/// The year flags (aka the dominical letter).
///
@@ -35,23 +34,24 @@ pub const MIN_YEAR: DateImpl = i32::MIN >> 13;
/// where `a` is `1` for the common year (simplifies the `Of` validation)
/// and `bbb` is a non-zero `Weekday` (mapping `Mon` to 7) of the last day in the past year
/// (simplifies the day of week calculation from the 1-based ordinal).
-#[derive(PartialEq, Eq, Copy, Clone)]
-pub struct YearFlags(pub u8);
-
-pub const A: YearFlags = YearFlags(0o15);
-pub const AG: YearFlags = YearFlags(0o05);
-pub const B: YearFlags = YearFlags(0o14);
-pub const BA: YearFlags = YearFlags(0o04);
-pub const C: YearFlags = YearFlags(0o13);
-pub const CB: YearFlags = YearFlags(0o03);
-pub const D: YearFlags = YearFlags(0o12);
-pub const DC: YearFlags = YearFlags(0o02);
-pub const E: YearFlags = YearFlags(0o11);
-pub const ED: YearFlags = YearFlags(0o01);
-pub const F: YearFlags = YearFlags(0o17);
-pub const FE: YearFlags = YearFlags(0o07);
-pub const G: YearFlags = YearFlags(0o16);
-pub const GF: YearFlags = YearFlags(0o06);
+#[allow(unreachable_pub)] // public as an alias for benchmarks only
+#[derive(PartialEq, Eq, Copy, Clone, Hash)]
+pub struct YearFlags(pub(super) u8);
+
+pub(super) const A: YearFlags = YearFlags(0o15);
+pub(super) const AG: YearFlags = YearFlags(0o05);
+pub(super) const B: YearFlags = YearFlags(0o14);
+pub(super) const BA: YearFlags = YearFlags(0o04);
+pub(super) const C: YearFlags = YearFlags(0o13);
+pub(super) const CB: YearFlags = YearFlags(0o03);
+pub(super) const D: YearFlags = YearFlags(0o12);
+pub(super) const DC: YearFlags = YearFlags(0o02);
+pub(super) const E: YearFlags = YearFlags(0o11);
+pub(super) const ED: YearFlags = YearFlags(0o01);
+pub(super) const F: YearFlags = YearFlags(0o17);
+pub(super) const FE: YearFlags = YearFlags(0o07);
+pub(super) const G: YearFlags = YearFlags(0o16);
+pub(super) const GF: YearFlags = YearFlags(0o06);
static YEAR_TO_FLAGS: [YearFlags; 400] = [
BA, G, F, E, DC, B, A, G, FE, D, C, B, AG, F, E, D, CB, A, G, F, ED, C, B, A, GF, E, D, C, BA,
@@ -94,7 +94,7 @@ static YEAR_DELTAS: [u8; 401] = [
96, 97, 97, 97, 97, // 400+1
];
-pub fn cycle_to_yo(cycle: u32) -> (u32, u32) {
+pub(super) fn cycle_to_yo(cycle: u32) -> (u32, u32) {
let (mut year_mod_400, mut ordinal0) = div_rem(cycle, 365);
let delta = u32::from(YEAR_DELTAS[year_mod_400 as usize]);
if ordinal0 < delta {
@@ -106,11 +106,13 @@ pub fn cycle_to_yo(cycle: u32) -> (u32, u32) {
(year_mod_400, ordinal0 + 1)
}
-pub fn yo_to_cycle(year_mod_400: u32, ordinal: u32) -> u32 {
+pub(super) fn yo_to_cycle(year_mod_400: u32, ordinal: u32) -> u32 {
year_mod_400 * 365 + u32::from(YEAR_DELTAS[year_mod_400 as usize]) + ordinal - 1
}
impl YearFlags {
+ #[allow(unreachable_pub)] // public as an alias for benchmarks only
+ #[doc(hidden)] // for benchmarks only
#[inline]
pub fn from_year(year: i32) -> YearFlags {
let year = mod_floor(year, 400);
@@ -118,18 +120,18 @@ impl YearFlags {
}
#[inline]
- pub fn from_year_mod_400(year: i32) -> YearFlags {
+ pub(super) fn from_year_mod_400(year: i32) -> YearFlags {
YEAR_TO_FLAGS[year as usize]
}
#[inline]
- pub fn ndays(&self) -> u32 {
+ pub(super) fn ndays(&self) -> u32 {
let YearFlags(flags) = *self;
366 - u32::from(flags >> 3)
}
#[inline]
- pub fn isoweek_delta(&self) -> u32 {
+ pub(super) fn isoweek_delta(&self) -> u32 {
let YearFlags(flags) = *self;
let mut delta = u32::from(flags) & 0b0111;
if delta < 3 {
@@ -139,7 +141,7 @@ impl YearFlags {
}
#[inline]
- pub fn nisoweeks(&self) -> u32 {
+ pub(super) const fn nisoweeks(&self) -> u32 {
let YearFlags(flags) = *self;
52 + ((0b0000_0100_0000_0110 >> flags as usize) & 1)
}
@@ -170,10 +172,9 @@ impl fmt::Debug for YearFlags {
}
}
-pub const MIN_OL: u32 = 1 << 1;
-pub const MAX_OL: u32 = 366 << 1; // larger than the non-leap last day `(365 << 1) | 1`
-pub const MIN_MDL: u32 = (1 << 6) | (1 << 1);
-pub const MAX_MDL: u32 = (12 << 6) | (31 << 1) | 1;
+pub(super) const MIN_OL: u32 = 1 << 1;
+pub(super) const MAX_OL: u32 = 366 << 1; // larger than the non-leap last day `(365 << 1) | 1`
+pub(super) const MAX_MDL: u32 = (12 << 6) | (31 << 1) | 1;
const XX: i8 = -128;
static MDL_TO_OL: [i8; MAX_MDL as usize + 1] = [
@@ -265,26 +266,19 @@ static OL_TO_MDL: [u8; MAX_OL as usize + 1] = [
/// The whole bits except for the least 3 bits are referred as `Ol` (ordinal and leap flag),
/// which is an index to the `OL_TO_MDL` lookup table.
#[derive(PartialEq, PartialOrd, Copy, Clone)]
-pub struct Of(pub u32);
+pub(super) struct Of(pub(crate) u32);
impl Of {
#[inline]
- fn clamp_ordinal(ordinal: u32) -> u32 {
- if ordinal > 366 {
- 0
- } else {
- ordinal
+ pub(super) fn new(ordinal: u32, YearFlags(flags): YearFlags) -> Option<Of> {
+ match ordinal <= 366 {
+ true => Some(Of((ordinal << 4) | u32::from(flags))),
+ false => None,
}
}
#[inline]
- pub fn new(ordinal: u32, YearFlags(flags): YearFlags) -> Of {
- let ordinal = Of::clamp_ordinal(ordinal);
- Of((ordinal << 4) | u32::from(flags))
- }
-
- #[inline]
- pub fn from_mdf(Mdf(mdf): Mdf) -> Of {
+ pub(super) fn from_mdf(Mdf(mdf): Mdf) -> Of {
let mdl = mdf >> 3;
match MDL_TO_OL.get(mdl as usize) {
Some(&v) => Of(mdf.wrapping_sub((i32::from(v) as u32 & 0x3ff) << 3)),
@@ -293,64 +287,62 @@ impl Of {
}
#[inline]
- pub fn valid(&self) -> bool {
+ pub(super) fn valid(&self) -> bool {
let Of(of) = *self;
let ol = of >> 3;
- MIN_OL <= ol && ol <= MAX_OL
+ (MIN_OL..=MAX_OL).contains(&ol)
}
#[inline]
- pub fn ordinal(&self) -> u32 {
+ pub(super) const fn ordinal(&self) -> u32 {
let Of(of) = *self;
of >> 4
}
#[inline]
- pub fn with_ordinal(&self, ordinal: u32) -> Of {
- let ordinal = Of::clamp_ordinal(ordinal);
- let Of(of) = *self;
- Of((of & 0b1111) | (ordinal << 4))
- }
+ pub(super) fn with_ordinal(&self, ordinal: u32) -> Option<Of> {
+ if ordinal > 366 {
+ return None;
+ }
- #[inline]
- pub fn flags(&self) -> YearFlags {
let Of(of) = *self;
- YearFlags((of & 0b1111) as u8)
+ Some(Of((of & 0b1111) | (ordinal << 4)))
}
#[inline]
- pub fn with_flags(&self, YearFlags(flags): YearFlags) -> Of {
+ pub(super) const fn flags(&self) -> YearFlags {
let Of(of) = *self;
- Of((of & !0b1111) | u32::from(flags))
+ YearFlags((of & 0b1111) as u8)
}
#[inline]
- pub fn weekday(&self) -> Weekday {
+ pub(super) fn weekday(&self) -> Weekday {
let Of(of) = *self;
Weekday::from_u32(((of >> 4) + (of & 0b111)) % 7).unwrap()
}
#[inline]
- pub fn isoweekdate_raw(&self) -> (u32, Weekday) {
+ pub(super) fn isoweekdate_raw(&self) -> (u32, Weekday) {
// week ordinal = ordinal + delta
let Of(of) = *self;
let weekord = (of >> 4).wrapping_add(self.flags().isoweek_delta());
(weekord / 7, Weekday::from_u32(weekord % 7).unwrap())
}
+ #[cfg_attr(feature = "cargo-clippy", allow(clippy::wrong_self_convention))]
#[inline]
- pub fn to_mdf(&self) -> Mdf {
+ pub(super) fn to_mdf(&self) -> Mdf {
Mdf::from_of(*self)
}
#[inline]
- pub fn succ(&self) -> Of {
+ pub(super) const fn succ(&self) -> Of {
let Of(of) = *self;
Of(of + (1 << 4))
}
#[inline]
- pub fn pred(&self) -> Of {
+ pub(super) const fn pred(&self) -> Of {
let Of(of) = *self;
Of(of - (1 << 4))
}
@@ -375,36 +367,19 @@ impl fmt::Debug for Of {
/// (month, day of month and leap flag),
/// which is an index to the `MDL_TO_OL` lookup table.
#[derive(PartialEq, PartialOrd, Copy, Clone)]
-pub struct Mdf(pub u32);
+pub(super) struct Mdf(pub(super) u32);
impl Mdf {
#[inline]
- fn clamp_month(month: u32) -> u32 {
- if month > 12 {
- 0
- } else {
- month
- }
- }
-
- #[inline]
- fn clamp_day(day: u32) -> u32 {
- if day > 31 {
- 0
- } else {
- day
+ pub(super) fn new(month: u32, day: u32, YearFlags(flags): YearFlags) -> Option<Mdf> {
+ match month <= 12 && day <= 31 {
+ true => Some(Mdf((month << 9) | (day << 4) | u32::from(flags))),
+ false => None,
}
}
#[inline]
- pub fn new(month: u32, day: u32, YearFlags(flags): YearFlags) -> Mdf {
- let month = Mdf::clamp_month(month);
- let day = Mdf::clamp_day(day);
- Mdf((month << 9) | (day << 4) | u32::from(flags))
- }
-
- #[inline]
- pub fn from_of(Of(of): Of) -> Mdf {
+ pub(super) fn from_of(Of(of): Of) -> Mdf {
let ol = of >> 3;
match OL_TO_MDL.get(ol as usize) {
Some(&v) => Mdf(of + (u32::from(v) << 3)),
@@ -412,8 +387,8 @@ impl Mdf {
}
}
- #[inline]
- pub fn valid(&self) -> bool {
+ #[cfg(test)]
+ pub(super) fn valid(&self) -> bool {
let Mdf(mdf) = *self;
let mdl = mdf >> 3;
match MDL_TO_OL.get(mdl as usize) {
@@ -423,45 +398,46 @@ impl Mdf {
}
#[inline]
- pub fn month(&self) -> u32 {
+ pub(super) const fn month(&self) -> u32 {
let Mdf(mdf) = *self;
mdf >> 9
}
#[inline]
- pub fn with_month(&self, month: u32) -> Mdf {
- let month = Mdf::clamp_month(month);
+ pub(super) fn with_month(&self, month: u32) -> Option<Mdf> {
+ if month > 12 {
+ return None;
+ }
+
let Mdf(mdf) = *self;
- Mdf((mdf & 0b1_1111_1111) | (month << 9))
+ Some(Mdf((mdf & 0b1_1111_1111) | (month << 9)))
}
#[inline]
- pub fn day(&self) -> u32 {
+ pub(super) const fn day(&self) -> u32 {
let Mdf(mdf) = *self;
(mdf >> 4) & 0b1_1111
}
#[inline]
- pub fn with_day(&self, day: u32) -> Mdf {
- let day = Mdf::clamp_day(day);
- let Mdf(mdf) = *self;
- Mdf((mdf & !0b1_1111_0000) | (day << 4))
- }
+ pub(super) fn with_day(&self, day: u32) -> Option<Mdf> {
+ if day > 31 {
+ return None;
+ }
- #[inline]
- pub fn flags(&self) -> YearFlags {
let Mdf(mdf) = *self;
- YearFlags((mdf & 0b1111) as u8)
+ Some(Mdf((mdf & !0b1_1111_0000) | (day << 4)))
}
#[inline]
- pub fn with_flags(&self, YearFlags(flags): YearFlags) -> Mdf {
+ pub(super) fn with_flags(&self, YearFlags(flags): YearFlags) -> Mdf {
let Mdf(mdf) = *self;
Mdf((mdf & !0b1111) | u32::from(flags))
}
+ #[cfg_attr(feature = "cargo-clippy", allow(clippy::wrong_self_convention))]
#[inline]
- pub fn to_of(&self) -> Of {
+ pub(super) fn to_of(&self) -> Of {
Of::from_mdf(*self)
}
}
@@ -482,14 +458,12 @@ impl fmt::Debug for Mdf {
#[cfg(test)]
mod tests {
- #[cfg(test)]
- extern crate num_iter;
+ use num_iter::range_inclusive;
+ use std::u32;
- use self::num_iter::range_inclusive;
use super::{Mdf, Of};
use super::{YearFlags, A, AG, B, BA, C, CB, D, DC, E, ED, F, FE, G, GF};
- use std::u32;
- use Weekday;
+ use crate::Weekday;
const NONLEAP_FLAGS: [YearFlags; 7] = [A, B, C, D, E, F, G];
const LEAP_FLAGS: [YearFlags; 7] = [AG, BA, CB, DC, ED, FE, GF];
@@ -534,7 +508,12 @@ mod tests {
fn test_of() {
fn check(expected: bool, flags: YearFlags, ordinal1: u32, ordinal2: u32) {
for ordinal in range_inclusive(ordinal1, ordinal2) {
- let of = Of::new(ordinal, flags);
+ let of = match Of::new(ordinal, flags) {
+ Some(of) => of,
+ None if !expected => continue,
+ None => panic!("Of::new({}, {:?}) returned None", ordinal, flags),
+ };
+
assert!(
of.valid() == expected,
"ordinal {} = {:?} should be {} for dominical year {:?}",
@@ -566,7 +545,12 @@ mod tests {
fn check(expected: bool, flags: YearFlags, month1: u32, day1: u32, month2: u32, day2: u32) {
for month in range_inclusive(month1, month2) {
for day in range_inclusive(day1, day2) {
- let mdf = Mdf::new(month, day, flags);
+ let mdf = match Mdf::new(month, day, flags) {
+ Some(mdf) => mdf,
+ None if !expected => continue,
+ None => panic!("Mdf::new({}, {}, {:?}) returned None", month, day, flags),
+ };
+
assert!(
mdf.valid() == expected,
"month {} day {} = {:?} should be {} for dominical year {:?}",
@@ -651,7 +635,7 @@ mod tests {
fn test_of_fields() {
for &flags in FLAGS.iter() {
for ordinal in range_inclusive(1u32, 366) {
- let of = Of::new(ordinal, flags);
+ let of = Of::new(ordinal, flags).unwrap();
if of.valid() {
assert_eq!(of.ordinal(), ordinal);
}
@@ -662,11 +646,16 @@ mod tests {
#[test]
fn test_of_with_fields() {
fn check(flags: YearFlags, ordinal: u32) {
- let of = Of::new(ordinal, flags);
+ let of = Of::new(ordinal, flags).unwrap();
for ordinal in range_inclusive(0u32, 1024) {
- let of = of.with_ordinal(ordinal);
- assert_eq!(of.valid(), Of::new(ordinal, flags).valid());
+ let of = match of.with_ordinal(ordinal) {
+ Some(of) => of,
+ None if ordinal > 366 => continue,
+ None => panic!("failed to create Of with ordinal {}", ordinal),
+ };
+
+ assert_eq!(of.valid(), Of::new(ordinal, flags).unwrap().valid());
if of.valid() {
assert_eq!(of.ordinal(), ordinal);
}
@@ -685,25 +674,25 @@ mod tests {
#[test]
fn test_of_weekday() {
- assert_eq!(Of::new(1, A).weekday(), Weekday::Sun);
- assert_eq!(Of::new(1, B).weekday(), Weekday::Sat);
- assert_eq!(Of::new(1, C).weekday(), Weekday::Fri);
- assert_eq!(Of::new(1, D).weekday(), Weekday::Thu);
- assert_eq!(Of::new(1, E).weekday(), Weekday::Wed);
- assert_eq!(Of::new(1, F).weekday(), Weekday::Tue);
- assert_eq!(Of::new(1, G).weekday(), Weekday::Mon);
- assert_eq!(Of::new(1, AG).weekday(), Weekday::Sun);
- assert_eq!(Of::new(1, BA).weekday(), Weekday::Sat);
- assert_eq!(Of::new(1, CB).weekday(), Weekday::Fri);
- assert_eq!(Of::new(1, DC).weekday(), Weekday::Thu);
- assert_eq!(Of::new(1, ED).weekday(), Weekday::Wed);
- assert_eq!(Of::new(1, FE).weekday(), Weekday::Tue);
- assert_eq!(Of::new(1, GF).weekday(), Weekday::Mon);
+ assert_eq!(Of::new(1, A).unwrap().weekday(), Weekday::Sun);
+ assert_eq!(Of::new(1, B).unwrap().weekday(), Weekday::Sat);
+ assert_eq!(Of::new(1, C).unwrap().weekday(), Weekday::Fri);
+ assert_eq!(Of::new(1, D).unwrap().weekday(), Weekday::Thu);
+ assert_eq!(Of::new(1, E).unwrap().weekday(), Weekday::Wed);
+ assert_eq!(Of::new(1, F).unwrap().weekday(), Weekday::Tue);
+ assert_eq!(Of::new(1, G).unwrap().weekday(), Weekday::Mon);
+ assert_eq!(Of::new(1, AG).unwrap().weekday(), Weekday::Sun);
+ assert_eq!(Of::new(1, BA).unwrap().weekday(), Weekday::Sat);
+ assert_eq!(Of::new(1, CB).unwrap().weekday(), Weekday::Fri);
+ assert_eq!(Of::new(1, DC).unwrap().weekday(), Weekday::Thu);
+ assert_eq!(Of::new(1, ED).unwrap().weekday(), Weekday::Wed);
+ assert_eq!(Of::new(1, FE).unwrap().weekday(), Weekday::Tue);
+ assert_eq!(Of::new(1, GF).unwrap().weekday(), Weekday::Mon);
for &flags in FLAGS.iter() {
- let mut prev = Of::new(1, flags).weekday();
+ let mut prev = Of::new(1, flags).unwrap().weekday();
for ordinal in range_inclusive(2u32, flags.ndays()) {
- let of = Of::new(ordinal, flags);
+ let of = Of::new(ordinal, flags).unwrap();
let expected = prev.succ();
assert_eq!(of.weekday(), expected);
prev = expected;
@@ -716,7 +705,11 @@ mod tests {
for &flags in FLAGS.iter() {
for month in range_inclusive(1u32, 12) {
for day in range_inclusive(1u32, 31) {
- let mdf = Mdf::new(month, day, flags);
+ let mdf = match Mdf::new(month, day, flags) {
+ Some(mdf) => mdf,
+ None => continue,
+ };
+
if mdf.valid() {
assert_eq!(mdf.month(), month);
assert_eq!(mdf.day(), day);
@@ -729,11 +722,15 @@ mod tests {
#[test]
fn test_mdf_with_fields() {
fn check(flags: YearFlags, month: u32, day: u32) {
- let mdf = Mdf::new(month, day, flags);
+ let mdf = Mdf::new(month, day, flags).unwrap();
for month in range_inclusive(0u32, 16) {
- let mdf = mdf.with_month(month);
- assert_eq!(mdf.valid(), Mdf::new(month, day, flags).valid());
+ let mdf = match mdf.with_month(month) {
+ Some(mdf) => mdf,
+ None if month > 12 => continue,
+ None => panic!("failed to create Mdf with month {}", month),
+ };
+
if mdf.valid() {
assert_eq!(mdf.month(), month);
assert_eq!(mdf.day(), day);
@@ -741,8 +738,12 @@ mod tests {
}
for day in range_inclusive(0u32, 1024) {
- let mdf = mdf.with_day(day);
- assert_eq!(mdf.valid(), Mdf::new(month, day, flags).valid());
+ let mdf = match mdf.with_day(day) {
+ Some(mdf) => mdf,
+ None if day > 31 => continue,
+ None => panic!("failed to create Mdf with month {}", month),
+ };
+
if mdf.valid() {
assert_eq!(mdf.month(), month);
assert_eq!(mdf.day(), day);
@@ -772,7 +773,7 @@ mod tests {
fn test_of_isoweekdate_raw() {
for &flags in FLAGS.iter() {
// January 4 should be in the first week
- let (week, _) = Of::new(4 /* January 4 */, flags).isoweekdate_raw();
+ let (week, _) = Of::new(4 /* January 4 */, flags).unwrap().isoweekdate_raw();
assert_eq!(week, 1);
}
}
diff --git a/vendor/chrono/src/naive/isoweek.rs b/vendor/chrono/src/naive/isoweek.rs
index ece10f250..6a4fcfd11 100644
--- a/vendor/chrono/src/naive/isoweek.rs
+++ b/vendor/chrono/src/naive/isoweek.rs
@@ -7,13 +7,17 @@ use core::fmt;
use super::internals::{DateImpl, Of, YearFlags};
+#[cfg(feature = "rkyv")]
+use rkyv::{Archive, Deserialize, Serialize};
+
/// ISO 8601 week.
///
/// This type, combined with [`Weekday`](../enum.Weekday.html),
-/// constitues the ISO 8601 [week date](./struct.NaiveDate.html#week-date).
+/// constitutes the ISO 8601 [week date](./struct.NaiveDate.html#week-date).
/// One can retrieve this type from the existing [`Datelike`](../trait.Datelike.html) types
/// via the [`Datelike::iso_week`](../trait.Datelike.html#tymethod.iso_week) method.
-#[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
+#[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone, Hash)]
+#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
pub struct IsoWeek {
// note that this allows for larger year range than `NaiveDate`.
// this is crucial because we have an edge case for the first and last week supported,
@@ -27,7 +31,7 @@ pub struct IsoWeek {
// because the year range for the week date and the calendar date do not match and
// it is confusing to have a date that is out of range in one and not in another.
// currently we sidestep this issue by making `IsoWeek` fully dependent of `Datelike`.
-pub fn iso_week_from_yof(year: i32, of: Of) -> IsoWeek {
+pub(super) fn iso_week_from_yof(year: i32, of: Of) -> IsoWeek {
let (rawweek, _) = of.isoweekdate_raw();
let (year, week) = if rawweek < 1 {
// previous year
@@ -50,24 +54,24 @@ impl IsoWeek {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Datelike, Weekday};
///
/// let d = NaiveDate::from_isoywd(2015, 1, Weekday::Mon);
/// assert_eq!(d.iso_week().year(), 2015);
- /// ~~~~
+ /// ```
///
/// This year number might not match the calendar year number.
/// Continuing the example...
///
- /// ~~~~
+ /// ```
/// # use chrono::{NaiveDate, Datelike, Weekday};
/// # let d = NaiveDate::from_isoywd(2015, 1, Weekday::Mon);
/// assert_eq!(d.year(), 2014);
- /// assert_eq!(d, NaiveDate::from_ymd(2014, 12, 29));
- /// ~~~~
+ /// assert_eq!(d, NaiveDate::from_ymd_opt(2014, 12, 29).unwrap());
+ /// ```
#[inline]
- pub fn year(&self) -> i32 {
+ pub const fn year(&self) -> i32 {
self.ywf >> 10
}
@@ -77,14 +81,14 @@ impl IsoWeek {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Datelike, Weekday};
///
/// let d = NaiveDate::from_isoywd(2015, 15, Weekday::Mon);
/// assert_eq!(d.iso_week().week(), 15);
- /// ~~~~
+ /// ```
#[inline]
- pub fn week(&self) -> u32 {
+ pub const fn week(&self) -> u32 {
((self.ywf >> 4) & 0x3f) as u32
}
@@ -94,14 +98,14 @@ impl IsoWeek {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveDate, Datelike, Weekday};
///
/// let d = NaiveDate::from_isoywd(2015, 15, Weekday::Mon);
/// assert_eq!(d.iso_week().week0(), 14);
- /// ~~~~
+ /// ```
#[inline]
- pub fn week0(&self) -> u32 {
+ pub const fn week0(&self) -> u32 {
((self.ywf >> 4) & 0x3f) as u32 - 1
}
}
@@ -112,26 +116,26 @@ impl IsoWeek {
///
/// # Example
///
-/// ~~~~
+/// ```
/// use chrono::{NaiveDate, Datelike};
///
-/// assert_eq!(format!("{:?}", NaiveDate::from_ymd(2015, 9, 5).iso_week()), "2015-W36");
-/// assert_eq!(format!("{:?}", NaiveDate::from_ymd( 0, 1, 3).iso_week()), "0000-W01");
-/// assert_eq!(format!("{:?}", NaiveDate::from_ymd(9999, 12, 31).iso_week()), "9999-W52");
-/// ~~~~
+/// assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(2015, 9, 5).unwrap().iso_week()), "2015-W36");
+/// assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt( 0, 1, 3).unwrap().iso_week()), "0000-W01");
+/// assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(9999, 12, 31).unwrap().iso_week()), "9999-W52");
+/// ```
///
/// ISO 8601 requires an explicit sign for years before 1 BCE or after 9999 CE.
///
-/// ~~~~
+/// ```
/// # use chrono::{NaiveDate, Datelike};
-/// assert_eq!(format!("{:?}", NaiveDate::from_ymd( 0, 1, 2).iso_week()), "-0001-W52");
-/// assert_eq!(format!("{:?}", NaiveDate::from_ymd(10000, 12, 31).iso_week()), "+10000-W52");
-/// ~~~~
+/// assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt( 0, 1, 2).unwrap().iso_week()), "-0001-W52");
+/// assert_eq!(format!("{:?}", NaiveDate::from_ymd_opt(10000, 12, 31).unwrap().iso_week()), "+10000-W52");
+/// ```
impl fmt::Debug for IsoWeek {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let year = self.year();
let week = self.week();
- if 0 <= year && year <= 9999 {
+ if (0..=9999).contains(&year) {
write!(f, "{:04}-W{:02}", year, week)
} else {
// ISO 8601 requires the explicit sign for out-of-range years
@@ -142,22 +146,22 @@ impl fmt::Debug for IsoWeek {
#[cfg(test)]
mod tests {
- use naive::{internals, MAX_DATE, MIN_DATE};
- use Datelike;
+ use crate::naive::{internals, NaiveDate};
+ use crate::Datelike;
#[test]
fn test_iso_week_extremes() {
- let minweek = MIN_DATE.iso_week();
- let maxweek = MAX_DATE.iso_week();
+ let minweek = NaiveDate::MIN.iso_week();
+ let maxweek = NaiveDate::MAX.iso_week();
assert_eq!(minweek.year(), internals::MIN_YEAR);
assert_eq!(minweek.week(), 1);
assert_eq!(minweek.week0(), 0);
- assert_eq!(format!("{:?}", minweek), MIN_DATE.format("%G-W%V").to_string());
+ assert_eq!(format!("{:?}", minweek), NaiveDate::MIN.format("%G-W%V").to_string());
assert_eq!(maxweek.year(), internals::MAX_YEAR + 1);
assert_eq!(maxweek.week(), 1);
assert_eq!(maxweek.week0(), 0);
- assert_eq!(format!("{:?}", maxweek), MAX_DATE.format("%G-W%V").to_string());
+ assert_eq!(format!("{:?}", maxweek), NaiveDate::MAX.format("%G-W%V").to_string());
}
}
diff --git a/vendor/chrono/src/naive/mod.rs b/vendor/chrono/src/naive/mod.rs
new file mode 100644
index 000000000..c41acba8d
--- /dev/null
+++ b/vendor/chrono/src/naive/mod.rs
@@ -0,0 +1,39 @@
+//! Date and time types unconcerned with timezones.
+//!
+//! They are primarily building blocks for other types
+//! (e.g. [`TimeZone`](../offset/trait.TimeZone.html)),
+//! but can be also used for the simpler date and time handling.
+
+mod date;
+pub(crate) mod datetime;
+mod internals;
+mod isoweek;
+mod time;
+
+#[allow(deprecated)]
+pub use self::date::{Days, NaiveDate, NaiveWeek, MAX_DATE, MIN_DATE};
+#[cfg(feature = "rustc-serialize")]
+#[allow(deprecated)]
+pub use self::datetime::rustc_serialize::TsSeconds;
+#[allow(deprecated)]
+pub use self::datetime::{NaiveDateTime, MAX_DATETIME, MIN_DATETIME};
+pub use self::isoweek::IsoWeek;
+pub use self::time::NaiveTime;
+
+#[cfg(feature = "__internal_bench")]
+#[doc(hidden)]
+pub use self::internals::YearFlags as __BenchYearFlags;
+
+/// Serialization/Deserialization of naive types in alternate formats
+///
+/// The various modules in here are intended to be used with serde's [`with`
+/// annotation][1] to serialize as something other than the default [RFC
+/// 3339][2] format.
+///
+/// [1]: https://serde.rs/attributes.html#field-attributes
+/// [2]: https://tools.ietf.org/html/rfc3339
+#[cfg(feature = "serde")]
+#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
+pub mod serde {
+ pub use super::datetime::serde::*;
+}
diff --git a/vendor/chrono/src/naive/time.rs b/vendor/chrono/src/naive/time/mod.rs
index 1ddc9fbed..1d36583aa 100644
--- a/vendor/chrono/src/naive/time.rs
+++ b/vendor/chrono/src/naive/time/mod.rs
@@ -6,18 +6,27 @@
#[cfg(any(feature = "alloc", feature = "std", test))]
use core::borrow::Borrow;
use core::ops::{Add, AddAssign, Sub, SubAssign};
-use core::{fmt, hash, str};
-use oldtime::Duration as OldDuration;
+use core::{fmt, str};
+
+use num_integer::div_mod_floor;
+#[cfg(feature = "rkyv")]
+use rkyv::{Archive, Deserialize, Serialize};
-use div::div_mod_floor;
#[cfg(any(feature = "alloc", feature = "std", test))]
-use format::DelayedFormat;
-use format::{parse, ParseError, ParseResult, Parsed, StrftimeItems};
-use format::{Fixed, Item, Numeric, Pad};
-use Timelike;
+use crate::format::DelayedFormat;
+use crate::format::{parse, write_hundreds, ParseError, ParseResult, Parsed, StrftimeItems};
+use crate::format::{Fixed, Item, Numeric, Pad};
+use crate::oldtime::Duration as OldDuration;
+use crate::Timelike;
-pub const MIN_TIME: NaiveTime = NaiveTime { secs: 0, frac: 0 };
-pub const MAX_TIME: NaiveTime = NaiveTime { secs: 23 * 3600 + 59 * 60 + 59, frac: 999_999_999 };
+#[cfg(feature = "rustc-serialize")]
+mod rustc_serialize;
+
+#[cfg(feature = "serde")]
+mod serde;
+
+#[cfg(test)]
+mod tests;
/// ISO 8601 time without timezone.
/// Allows for the nanosecond precision and optional leap second representation.
@@ -64,16 +73,16 @@ pub const MAX_TIME: NaiveTime = NaiveTime { secs: 23 * 3600 + 59 * 60 + 59, frac
///
/// All methods accepting fractional seconds will accept such values.
///
-/// ~~~~
+/// ```
/// use chrono::{NaiveDate, NaiveTime, Utc, TimeZone};
///
-/// let t = NaiveTime::from_hms_milli(8, 59, 59, 1_000);
+/// let t = NaiveTime::from_hms_milli_opt(8, 59, 59, 1_000).unwrap();
///
-/// let dt1 = NaiveDate::from_ymd(2015, 7, 1).and_hms_micro(8, 59, 59, 1_000_000);
+/// let dt1 = NaiveDate::from_ymd_opt(2015, 7, 1).unwrap().and_hms_micro_opt(8, 59, 59, 1_000_000).unwrap();
///
-/// let dt2 = Utc.ymd(2015, 6, 30).and_hms_nano(23, 59, 59, 1_000_000_000);
+/// let dt2 = NaiveDate::from_ymd_opt(2015, 6, 30).unwrap().and_hms_nano_opt(23, 59, 59, 1_000_000_000).unwrap().and_local_timezone(Utc).unwrap();
/// # let _ = (t, dt1, dt2);
-/// ~~~~
+/// ```
///
/// Note that the leap second can happen anytime given an appropriate time zone;
/// 2015-07-01 01:23:60 would be a proper leap second if UTC+01:24 had existed.
@@ -151,12 +160,12 @@ pub const MAX_TIME: NaiveTime = NaiveTime { secs: 23 * 3600 + 59 * 60 + 59, frac
/// The leap second in the human-readable representation
/// will be represented as the second part being 60, as required by ISO 8601.
///
-/// ~~~~
-/// use chrono::{Utc, TimeZone};
+/// ```
+/// use chrono::{Utc, TimeZone, NaiveDate};
///
-/// let dt = Utc.ymd(2015, 6, 30).and_hms_milli(23, 59, 59, 1_000);
+/// let dt = NaiveDate::from_ymd_opt(2015, 6, 30).unwrap().and_hms_milli_opt(23, 59, 59, 1_000).unwrap().and_local_timezone(Utc).unwrap();
/// assert_eq!(format!("{:?}", dt), "2015-06-30T23:59:60Z");
-/// ~~~~
+/// ```
///
/// There are hypothetical leap seconds not on the minute boundary
/// nevertheless supported by Chrono.
@@ -165,25 +174,37 @@ pub const MAX_TIME: NaiveTime = NaiveTime { secs: 23 * 3600 + 59 * 60 + 59, frac
/// For such cases the human-readable representation is ambiguous
/// and would be read back to the next non-leap second.
///
-/// ~~~~
-/// use chrono::{DateTime, Utc, TimeZone};
+/// ```
+/// use chrono::{DateTime, Utc, TimeZone, NaiveDate};
///
-/// let dt = Utc.ymd(2015, 6, 30).and_hms_milli(23, 56, 4, 1_000);
+/// let dt = NaiveDate::from_ymd_opt(2015, 6, 30).unwrap().and_hms_milli_opt(23, 56, 4, 1_000).unwrap().and_local_timezone(Utc).unwrap();
/// assert_eq!(format!("{:?}", dt), "2015-06-30T23:56:05Z");
///
-/// let dt = Utc.ymd(2015, 6, 30).and_hms(23, 56, 5);
+/// let dt = Utc.with_ymd_and_hms(2015, 6, 30, 23, 56, 5).unwrap();
/// assert_eq!(format!("{:?}", dt), "2015-06-30T23:56:05Z");
/// assert_eq!(DateTime::parse_from_rfc3339("2015-06-30T23:56:05Z").unwrap(), dt);
-/// ~~~~
+/// ```
///
/// Since Chrono alone cannot determine any existence of leap seconds,
/// **there is absolutely no guarantee that the leap second read has actually happened**.
-#[derive(PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
+#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Copy, Clone)]
+#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
pub struct NaiveTime {
secs: u32,
frac: u32,
}
+#[cfg(feature = "arbitrary")]
+impl arbitrary::Arbitrary<'_> for NaiveTime {
+ fn arbitrary(u: &mut arbitrary::Unstructured) -> arbitrary::Result<NaiveTime> {
+ let secs = u.int_in_range(0..=86_399)?;
+ let nano = u.int_in_range(0..=1_999_999_999)?;
+ let time = NaiveTime::from_num_seconds_from_midnight_opt(secs, nano)
+ .expect("Could not generate a valid chrono::NaiveTime. It looks like implementation of Arbitrary for NaiveTime is erroneous.");
+ Ok(time)
+ }
+}
+
impl NaiveTime {
/// Makes a new `NaiveTime` from hour, minute and second.
///
@@ -191,18 +212,7 @@ impl NaiveTime {
/// use `NaiveTime::from_hms_*` methods with a subsecond parameter instead.
///
/// Panics on invalid hour, minute and/or second.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveTime, Timelike};
- ///
- /// let t = NaiveTime::from_hms(23, 56, 4);
- /// assert_eq!(t.hour(), 23);
- /// assert_eq!(t.minute(), 56);
- /// assert_eq!(t.second(), 4);
- /// assert_eq!(t.nanosecond(), 0);
- /// ~~~~
+ #[deprecated(since = "0.4.23", note = "use `from_hms_opt()` instead")]
#[inline]
pub fn from_hms(hour: u32, min: u32, sec: u32) -> NaiveTime {
NaiveTime::from_hms_opt(hour, min, sec).expect("invalid time")
@@ -217,7 +227,7 @@ impl NaiveTime {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::NaiveTime;
///
/// let from_hms_opt = NaiveTime::from_hms_opt;
@@ -227,7 +237,7 @@ impl NaiveTime {
/// assert!(from_hms_opt(24, 0, 0).is_none());
/// assert!(from_hms_opt(23, 60, 0).is_none());
/// assert!(from_hms_opt(23, 59, 60).is_none());
- /// ~~~~
+ /// ```
#[inline]
pub fn from_hms_opt(hour: u32, min: u32, sec: u32) -> Option<NaiveTime> {
NaiveTime::from_hms_nano_opt(hour, min, sec, 0)
@@ -239,18 +249,7 @@ impl NaiveTime {
/// in order to represent the [leap second](#leap-second-handling).
///
/// Panics on invalid hour, minute, second and/or millisecond.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveTime, Timelike};
- ///
- /// let t = NaiveTime::from_hms_milli(23, 56, 4, 12);
- /// assert_eq!(t.hour(), 23);
- /// assert_eq!(t.minute(), 56);
- /// assert_eq!(t.second(), 4);
- /// assert_eq!(t.nanosecond(), 12_000_000);
- /// ~~~~
+ #[deprecated(since = "0.4.23", note = "use `from_hms_milli_opt()` instead")]
#[inline]
pub fn from_hms_milli(hour: u32, min: u32, sec: u32, milli: u32) -> NaiveTime {
NaiveTime::from_hms_milli_opt(hour, min, sec, milli).expect("invalid time")
@@ -265,7 +264,7 @@ impl NaiveTime {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::NaiveTime;
///
/// let from_hmsm_opt = NaiveTime::from_hms_milli_opt;
@@ -277,7 +276,7 @@ impl NaiveTime {
/// assert!(from_hmsm_opt(23, 60, 0, 0).is_none());
/// assert!(from_hmsm_opt(23, 59, 60, 0).is_none());
/// assert!(from_hmsm_opt(23, 59, 59, 2_000).is_none());
- /// ~~~~
+ /// ```
#[inline]
pub fn from_hms_milli_opt(hour: u32, min: u32, sec: u32, milli: u32) -> Option<NaiveTime> {
milli
@@ -291,18 +290,7 @@ impl NaiveTime {
/// in order to represent the [leap second](#leap-second-handling).
///
/// Panics on invalid hour, minute, second and/or microsecond.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveTime, Timelike};
- ///
- /// let t = NaiveTime::from_hms_micro(23, 56, 4, 12_345);
- /// assert_eq!(t.hour(), 23);
- /// assert_eq!(t.minute(), 56);
- /// assert_eq!(t.second(), 4);
- /// assert_eq!(t.nanosecond(), 12_345_000);
- /// ~~~~
+ #[deprecated(since = "0.4.23", note = "use `from_hms_micro_opt()` instead")]
#[inline]
pub fn from_hms_micro(hour: u32, min: u32, sec: u32, micro: u32) -> NaiveTime {
NaiveTime::from_hms_micro_opt(hour, min, sec, micro).expect("invalid time")
@@ -317,7 +305,7 @@ impl NaiveTime {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::NaiveTime;
///
/// let from_hmsu_opt = NaiveTime::from_hms_micro_opt;
@@ -329,7 +317,7 @@ impl NaiveTime {
/// assert!(from_hmsu_opt(23, 60, 0, 0).is_none());
/// assert!(from_hmsu_opt(23, 59, 60, 0).is_none());
/// assert!(from_hmsu_opt(23, 59, 59, 2_000_000).is_none());
- /// ~~~~
+ /// ```
#[inline]
pub fn from_hms_micro_opt(hour: u32, min: u32, sec: u32, micro: u32) -> Option<NaiveTime> {
micro.checked_mul(1_000).and_then(|nano| NaiveTime::from_hms_nano_opt(hour, min, sec, nano))
@@ -341,18 +329,7 @@ impl NaiveTime {
/// in order to represent the [leap second](#leap-second-handling).
///
/// Panics on invalid hour, minute, second and/or nanosecond.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveTime, Timelike};
- ///
- /// let t = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
- /// assert_eq!(t.hour(), 23);
- /// assert_eq!(t.minute(), 56);
- /// assert_eq!(t.second(), 4);
- /// assert_eq!(t.nanosecond(), 12_345_678);
- /// ~~~~
+ #[deprecated(since = "0.4.23", note = "use `from_hms_nano_opt()` instead")]
#[inline]
pub fn from_hms_nano(hour: u32, min: u32, sec: u32, nano: u32) -> NaiveTime {
NaiveTime::from_hms_nano_opt(hour, min, sec, nano).expect("invalid time")
@@ -367,7 +344,7 @@ impl NaiveTime {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::NaiveTime;
///
/// let from_hmsn_opt = NaiveTime::from_hms_nano_opt;
@@ -379,14 +356,14 @@ impl NaiveTime {
/// assert!(from_hmsn_opt(23, 60, 0, 0).is_none());
/// assert!(from_hmsn_opt(23, 59, 60, 0).is_none());
/// assert!(from_hmsn_opt(23, 59, 59, 2_000_000_000).is_none());
- /// ~~~~
+ /// ```
#[inline]
pub fn from_hms_nano_opt(hour: u32, min: u32, sec: u32, nano: u32) -> Option<NaiveTime> {
if hour >= 24 || min >= 60 || sec >= 60 || nano >= 2_000_000_000 {
return None;
}
let secs = hour * 3600 + min * 60 + sec;
- Some(NaiveTime { secs: secs, frac: nano })
+ Some(NaiveTime { secs, frac: nano })
}
/// Makes a new `NaiveTime` from the number of seconds since midnight and nanosecond.
@@ -395,18 +372,7 @@ impl NaiveTime {
/// in order to represent the [leap second](#leap-second-handling).
///
/// Panics on invalid number of seconds and/or nanosecond.
- ///
- /// # Example
- ///
- /// ~~~~
- /// use chrono::{NaiveTime, Timelike};
- ///
- /// let t = NaiveTime::from_num_seconds_from_midnight(86164, 12_345_678);
- /// assert_eq!(t.hour(), 23);
- /// assert_eq!(t.minute(), 56);
- /// assert_eq!(t.second(), 4);
- /// assert_eq!(t.nanosecond(), 12_345_678);
- /// ~~~~
+ #[deprecated(since = "0.4.23", note = "use `from_num_seconds_from_midnight_opt()` instead")]
#[inline]
pub fn from_num_seconds_from_midnight(secs: u32, nano: u32) -> NaiveTime {
NaiveTime::from_num_seconds_from_midnight_opt(secs, nano).expect("invalid time")
@@ -421,7 +387,7 @@ impl NaiveTime {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::NaiveTime;
///
/// let from_nsecs_opt = NaiveTime::from_num_seconds_from_midnight_opt;
@@ -431,13 +397,13 @@ impl NaiveTime {
/// assert!(from_nsecs_opt(86399, 1_999_999_999).is_some()); // a leap second after 23:59:59
/// assert!(from_nsecs_opt(86_400, 0).is_none());
/// assert!(from_nsecs_opt(86399, 2_000_000_000).is_none());
- /// ~~~~
+ /// ```
#[inline]
pub fn from_num_seconds_from_midnight_opt(secs: u32, nano: u32) -> Option<NaiveTime> {
if secs >= 86_400 || nano >= 2_000_000_000 {
return None;
}
- Some(NaiveTime { secs: secs, frac: nano })
+ Some(NaiveTime { secs, frac: nano })
}
/// Parses a string with the specified format string and returns a new `NaiveTime`.
@@ -446,61 +412,61 @@ impl NaiveTime {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::NaiveTime;
///
/// let parse_from_str = NaiveTime::parse_from_str;
///
/// assert_eq!(parse_from_str("23:56:04", "%H:%M:%S"),
- /// Ok(NaiveTime::from_hms(23, 56, 4)));
+ /// Ok(NaiveTime::from_hms_opt(23, 56, 4).unwrap()));
/// assert_eq!(parse_from_str("pm012345.6789", "%p%I%M%S%.f"),
- /// Ok(NaiveTime::from_hms_micro(13, 23, 45, 678_900)));
- /// ~~~~
+ /// Ok(NaiveTime::from_hms_micro_opt(13, 23, 45, 678_900).unwrap()));
+ /// ```
///
/// Date and offset is ignored for the purpose of parsing.
///
- /// ~~~~
+ /// ```
/// # use chrono::NaiveTime;
/// # let parse_from_str = NaiveTime::parse_from_str;
/// assert_eq!(parse_from_str("2014-5-17T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
- /// Ok(NaiveTime::from_hms(12, 34, 56)));
- /// ~~~~
+ /// Ok(NaiveTime::from_hms_opt(12, 34, 56).unwrap()));
+ /// ```
///
/// [Leap seconds](#leap-second-handling) are correctly handled by
/// treating any time of the form `hh:mm:60` as a leap second.
/// (This equally applies to the formatting, so the round trip is possible.)
///
- /// ~~~~
+ /// ```
/// # use chrono::NaiveTime;
/// # let parse_from_str = NaiveTime::parse_from_str;
/// assert_eq!(parse_from_str("08:59:60.123", "%H:%M:%S%.f"),
- /// Ok(NaiveTime::from_hms_milli(8, 59, 59, 1_123)));
- /// ~~~~
+ /// Ok(NaiveTime::from_hms_milli_opt(8, 59, 59, 1_123).unwrap()));
+ /// ```
///
/// Missing seconds are assumed to be zero,
/// but out-of-bound times or insufficient fields are errors otherwise.
///
- /// ~~~~
+ /// ```
/// # use chrono::NaiveTime;
/// # let parse_from_str = NaiveTime::parse_from_str;
/// assert_eq!(parse_from_str("7:15", "%H:%M"),
- /// Ok(NaiveTime::from_hms(7, 15, 0)));
+ /// Ok(NaiveTime::from_hms_opt(7, 15, 0).unwrap()));
///
/// assert!(parse_from_str("04m33s", "%Mm%Ss").is_err());
/// assert!(parse_from_str("12", "%H").is_err());
/// assert!(parse_from_str("17:60", "%H:%M").is_err());
/// assert!(parse_from_str("24:00:00", "%H:%M:%S").is_err());
- /// ~~~~
+ /// ```
///
/// All parsed fields should be consistent to each other, otherwise it's an error.
/// Here `%H` is for 24-hour clocks, unlike `%I`,
/// and thus can be independently determined without AM/PM.
///
- /// ~~~~
+ /// ```
/// # use chrono::NaiveTime;
/// # let parse_from_str = NaiveTime::parse_from_str;
/// assert!(parse_from_str("13:07 AM", "%H:%M %p").is_err());
- /// ~~~~
+ /// ```
pub fn parse_from_str(s: &str, fmt: &str) -> ParseResult<NaiveTime> {
let mut parsed = Parsed::new();
parse(&mut parsed, s, StrftimeItems::new(fmt))?;
@@ -514,8 +480,7 @@ impl NaiveTime {
///
/// # Example
///
- /// ~~~~
- /// # extern crate chrono; fn main() {
+ /// ```
/// use chrono::{Duration, NaiveTime};
///
/// let from_hms = NaiveTime::from_hms;
@@ -526,9 +491,7 @@ impl NaiveTime {
/// (from_hms(2, 4, 5), 86_400));
/// assert_eq!(from_hms(3, 4, 5).overflowing_add_signed(Duration::hours(-7)),
/// (from_hms(20, 4, 5), -86_400));
- /// # }
- /// ~~~~
- #[cfg_attr(feature = "cargo-clippy", allow(cyclomatic_complexity))]
+ /// ```
pub fn overflowing_add_signed(&self, mut rhs: OldDuration) -> (NaiveTime, i64) {
let mut secs = self.secs;
let mut frac = self.frac;
@@ -548,7 +511,7 @@ impl NaiveTime {
} else {
frac = (i64::from(frac) + rhs.num_nanoseconds().unwrap()) as u32;
debug_assert!(frac < 2_000_000_000);
- return (NaiveTime { secs: secs, frac: frac }, 0);
+ return (NaiveTime { secs, frac }, 0);
}
}
debug_assert!(secs <= 86_400);
@@ -577,8 +540,8 @@ impl NaiveTime {
frac -= 1_000_000_000;
secs += 1;
}
- debug_assert!(-86_400 <= secs && secs < 2 * 86_400);
- debug_assert!(0 <= frac && frac < 1_000_000_000);
+ debug_assert!((-86_400..2 * 86_400).contains(&secs));
+ debug_assert!((0..1_000_000_000).contains(&frac));
if secs < 0 {
secs += 86_400;
@@ -587,7 +550,7 @@ impl NaiveTime {
secs -= 86_400;
morerhssecs += 86_400;
}
- debug_assert!(0 <= secs && secs < 86_400);
+ debug_assert!((0..86_400).contains(&secs));
(NaiveTime { secs: secs as u32, frac: frac as u32 }, morerhssecs)
}
@@ -599,8 +562,7 @@ impl NaiveTime {
///
/// # Example
///
- /// ~~~~
- /// # extern crate chrono; fn main() {
+ /// ```
/// use chrono::{Duration, NaiveTime};
///
/// let from_hms = NaiveTime::from_hms;
@@ -611,8 +573,7 @@ impl NaiveTime {
/// (from_hms(10, 4, 5), 86_400));
/// assert_eq!(from_hms(3, 4, 5).overflowing_sub_signed(Duration::hours(-22)),
/// (from_hms(1, 4, 5), -86_400));
- /// # }
- /// ~~~~
+ /// ```
#[inline]
pub fn overflowing_sub_signed(&self, rhs: OldDuration) -> (NaiveTime, i64) {
let (time, rhs) = self.overflowing_add_signed(-rhs);
@@ -631,8 +592,7 @@ impl NaiveTime {
///
/// # Example
///
- /// ~~~~
- /// # extern crate chrono; fn main() {
+ /// ```
/// use chrono::{Duration, NaiveTime};
///
/// let from_hmsm = NaiveTime::from_hms_milli;
@@ -654,14 +614,12 @@ impl NaiveTime {
/// Duration::seconds(-3600));
/// assert_eq!(since(from_hmsm(3, 5, 7, 900), from_hmsm(2, 4, 6, 800)),
/// Duration::seconds(3600 + 60 + 1) + Duration::milliseconds(100));
- /// # }
- /// ~~~~
+ /// ```
///
/// Leap seconds are handled, but the subtraction assumes that
/// there were no other leap seconds happened.
///
- /// ~~~~
- /// # extern crate chrono; fn main() {
+ /// ```
/// # use chrono::{Duration, NaiveTime};
/// # let from_hmsm = NaiveTime::from_hms_milli;
/// # let since = NaiveTime::signed_duration_since;
@@ -675,8 +633,7 @@ impl NaiveTime {
/// Duration::seconds(1));
/// assert_eq!(since(from_hmsm(3, 0, 59, 1_000), from_hmsm(2, 59, 59, 1_000)),
/// Duration::seconds(61));
- /// # }
- /// ~~~~
+ /// ```
pub fn signed_duration_since(self, rhs: NaiveTime) -> OldDuration {
// | | :leap| | | | | | | :leap| |
// | | : | | | | | | | : | |
@@ -695,13 +652,7 @@ impl NaiveTime {
// `secs` may contain a leap second yet to be counted
let adjust = match self.secs.cmp(&rhs.secs) {
- Ordering::Greater => {
- if rhs.frac >= 1_000_000_000 {
- 1
- } else {
- 0
- }
- }
+ Ordering::Greater => i64::from(rhs.frac >= 1_000_000_000),
Ordering::Equal => 0,
Ordering::Less => {
if self.frac >= 1_000_000_000 {
@@ -723,26 +674,27 @@ impl NaiveTime {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::NaiveTime;
/// use chrono::format::strftime::StrftimeItems;
///
/// let fmt = StrftimeItems::new("%H:%M:%S");
- /// let t = NaiveTime::from_hms(23, 56, 4);
+ /// let t = NaiveTime::from_hms_opt(23, 56, 4).unwrap();
/// assert_eq!(t.format_with_items(fmt.clone()).to_string(), "23:56:04");
/// assert_eq!(t.format("%H:%M:%S").to_string(), "23:56:04");
- /// ~~~~
+ /// ```
///
/// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
///
- /// ~~~~
+ /// ```
/// # use chrono::NaiveTime;
/// # use chrono::format::strftime::StrftimeItems;
/// # let fmt = StrftimeItems::new("%H:%M:%S").clone();
- /// # let t = NaiveTime::from_hms(23, 56, 4);
+ /// # let t = NaiveTime::from_hms_opt(23, 56, 4).unwrap();
/// assert_eq!(format!("{}", t.format_with_items(fmt)), "23:56:04");
- /// ~~~~
+ /// ```
#[cfg(any(feature = "alloc", feature = "std", test))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
#[inline]
pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat<I>
where
@@ -768,25 +720,26 @@ impl NaiveTime {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::NaiveTime;
///
- /// let t = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
+ /// let t = NaiveTime::from_hms_nano_opt(23, 56, 4, 12_345_678).unwrap();
/// assert_eq!(t.format("%H:%M:%S").to_string(), "23:56:04");
/// assert_eq!(t.format("%H:%M:%S%.6f").to_string(), "23:56:04.012345");
/// assert_eq!(t.format("%-I:%M %p").to_string(), "11:56 PM");
- /// ~~~~
+ /// ```
///
/// The resulting `DelayedFormat` can be formatted directly via the `Display` trait.
///
- /// ~~~~
+ /// ```
/// # use chrono::NaiveTime;
- /// # let t = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
+ /// # let t = NaiveTime::from_hms_nano_opt(23, 56, 4, 12_345_678).unwrap();
/// assert_eq!(format!("{}", t.format("%H:%M:%S")), "23:56:04");
/// assert_eq!(format!("{}", t.format("%H:%M:%S%.6f")), "23:56:04.012345");
/// assert_eq!(format!("{}", t.format("%-I:%M %p")), "11:56 PM");
- /// ~~~~
+ /// ```
#[cfg(any(feature = "alloc", feature = "std", test))]
+ #[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "std"))))]
#[inline]
pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>> {
self.format_with_items(StrftimeItems::new(fmt))
@@ -798,6 +751,10 @@ impl NaiveTime {
let (hour, min) = div_mod_floor(mins, 60);
(hour, min, sec)
}
+
+ /// The earliest possible `NaiveTime`
+ pub const MIN: Self = Self { secs: 0, frac: 0 };
+ pub(super) const MAX: Self = Self { secs: 23 * 3600 + 59 * 60 + 59, frac: 999_999_999 };
}
impl Timelike for NaiveTime {
@@ -805,12 +762,12 @@ impl Timelike for NaiveTime {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveTime, Timelike};
///
- /// assert_eq!(NaiveTime::from_hms(0, 0, 0).hour(), 0);
- /// assert_eq!(NaiveTime::from_hms_nano(23, 56, 4, 12_345_678).hour(), 23);
- /// ~~~~
+ /// assert_eq!(NaiveTime::from_hms_opt(0, 0, 0).unwrap().hour(), 0);
+ /// assert_eq!(NaiveTime::from_hms_nano_opt(23, 56, 4, 12_345_678).unwrap().hour(), 23);
+ /// ```
#[inline]
fn hour(&self) -> u32 {
self.hms().0
@@ -820,12 +777,12 @@ impl Timelike for NaiveTime {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveTime, Timelike};
///
- /// assert_eq!(NaiveTime::from_hms(0, 0, 0).minute(), 0);
- /// assert_eq!(NaiveTime::from_hms_nano(23, 56, 4, 12_345_678).minute(), 56);
- /// ~~~~
+ /// assert_eq!(NaiveTime::from_hms_opt(0, 0, 0).unwrap().minute(), 0);
+ /// assert_eq!(NaiveTime::from_hms_nano_opt(23, 56, 4, 12_345_678).unwrap().minute(), 56);
+ /// ```
#[inline]
fn minute(&self) -> u32 {
self.hms().1
@@ -835,23 +792,23 @@ impl Timelike for NaiveTime {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveTime, Timelike};
///
- /// assert_eq!(NaiveTime::from_hms(0, 0, 0).second(), 0);
- /// assert_eq!(NaiveTime::from_hms_nano(23, 56, 4, 12_345_678).second(), 4);
- /// ~~~~
+ /// assert_eq!(NaiveTime::from_hms_opt(0, 0, 0).unwrap().second(), 0);
+ /// assert_eq!(NaiveTime::from_hms_nano_opt(23, 56, 4, 12_345_678).unwrap().second(), 4);
+ /// ```
///
/// This method never returns 60 even when it is a leap second.
/// ([Why?](#leap-second-handling))
/// Use the proper [formatting method](#method.format) to get a human-readable representation.
///
- /// ~~~~
+ /// ```
/// # use chrono::{NaiveTime, Timelike};
- /// let leap = NaiveTime::from_hms_milli(23, 59, 59, 1_000);
+ /// let leap = NaiveTime::from_hms_milli_opt(23, 59, 59, 1_000).unwrap();
/// assert_eq!(leap.second(), 59);
/// assert_eq!(leap.format("%H:%M:%S").to_string(), "23:59:60");
- /// ~~~~
+ /// ```
#[inline]
fn second(&self) -> u32 {
self.hms().2
@@ -863,23 +820,23 @@ impl Timelike for NaiveTime {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveTime, Timelike};
///
- /// assert_eq!(NaiveTime::from_hms(0, 0, 0).nanosecond(), 0);
- /// assert_eq!(NaiveTime::from_hms_nano(23, 56, 4, 12_345_678).nanosecond(), 12_345_678);
- /// ~~~~
+ /// assert_eq!(NaiveTime::from_hms_opt(0, 0, 0).unwrap().nanosecond(), 0);
+ /// assert_eq!(NaiveTime::from_hms_nano_opt(23, 56, 4, 12_345_678).unwrap().nanosecond(), 12_345_678);
+ /// ```
///
/// Leap seconds may have seemingly out-of-range return values.
/// You can reduce the range with `time.nanosecond() % 1_000_000_000`, or
/// use the proper [formatting method](#method.format) to get a human-readable representation.
///
- /// ~~~~
+ /// ```
/// # use chrono::{NaiveTime, Timelike};
- /// let leap = NaiveTime::from_hms_milli(23, 59, 59, 1_000);
+ /// let leap = NaiveTime::from_hms_milli_opt(23, 59, 59, 1_000).unwrap();
/// assert_eq!(leap.nanosecond(), 1_000_000_000);
/// assert_eq!(leap.format("%H:%M:%S%.9f").to_string(), "23:59:60.000000000");
- /// ~~~~
+ /// ```
#[inline]
fn nanosecond(&self) -> u32 {
self.frac
@@ -891,20 +848,20 @@ impl Timelike for NaiveTime {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveTime, Timelike};
///
- /// let dt = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
- /// assert_eq!(dt.with_hour(7), Some(NaiveTime::from_hms_nano(7, 56, 4, 12_345_678)));
+ /// let dt = NaiveTime::from_hms_nano_opt(23, 56, 4, 12_345_678).unwrap();
+ /// assert_eq!(dt.with_hour(7), Some(NaiveTime::from_hms_nano_opt(7, 56, 4, 12_345_678).unwrap()));
/// assert_eq!(dt.with_hour(24), None);
- /// ~~~~
+ /// ```
#[inline]
fn with_hour(&self, hour: u32) -> Option<NaiveTime> {
if hour >= 24 {
return None;
}
let secs = hour * 3600 + self.secs % 3600;
- Some(NaiveTime { secs: secs, ..*self })
+ Some(NaiveTime { secs, ..*self })
}
/// Makes a new `NaiveTime` with the minute number changed.
@@ -913,20 +870,20 @@ impl Timelike for NaiveTime {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveTime, Timelike};
///
- /// let dt = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
- /// assert_eq!(dt.with_minute(45), Some(NaiveTime::from_hms_nano(23, 45, 4, 12_345_678)));
+ /// let dt = NaiveTime::from_hms_nano_opt(23, 56, 4, 12_345_678).unwrap();
+ /// assert_eq!(dt.with_minute(45), Some(NaiveTime::from_hms_nano_opt(23, 45, 4, 12_345_678).unwrap()));
/// assert_eq!(dt.with_minute(60), None);
- /// ~~~~
+ /// ```
#[inline]
fn with_minute(&self, min: u32) -> Option<NaiveTime> {
if min >= 60 {
return None;
}
let secs = self.secs / 3600 * 3600 + min * 60 + self.secs % 60;
- Some(NaiveTime { secs: secs, ..*self })
+ Some(NaiveTime { secs, ..*self })
}
/// Makes a new `NaiveTime` with the second number changed.
@@ -937,20 +894,20 @@ impl Timelike for NaiveTime {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveTime, Timelike};
///
- /// let dt = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
- /// assert_eq!(dt.with_second(17), Some(NaiveTime::from_hms_nano(23, 56, 17, 12_345_678)));
+ /// let dt = NaiveTime::from_hms_nano_opt(23, 56, 4, 12_345_678).unwrap();
+ /// assert_eq!(dt.with_second(17), Some(NaiveTime::from_hms_nano_opt(23, 56, 17, 12_345_678).unwrap()));
/// assert_eq!(dt.with_second(60), None);
- /// ~~~~
+ /// ```
#[inline]
fn with_second(&self, sec: u32) -> Option<NaiveTime> {
if sec >= 60 {
return None;
}
let secs = self.secs / 60 * 60 + sec;
- Some(NaiveTime { secs: secs, ..*self })
+ Some(NaiveTime { secs, ..*self })
}
/// Makes a new `NaiveTime` with nanoseconds since the whole non-leap second changed.
@@ -961,26 +918,26 @@ impl Timelike for NaiveTime {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveTime, Timelike};
///
- /// let dt = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
+ /// let dt = NaiveTime::from_hms_nano_opt(23, 56, 4, 12_345_678).unwrap();
/// assert_eq!(dt.with_nanosecond(333_333_333),
- /// Some(NaiveTime::from_hms_nano(23, 56, 4, 333_333_333)));
+ /// Some(NaiveTime::from_hms_nano_opt(23, 56, 4, 333_333_333).unwrap()));
/// assert_eq!(dt.with_nanosecond(2_000_000_000), None);
- /// ~~~~
+ /// ```
///
/// Leap seconds can theoretically follow *any* whole second.
/// The following would be a proper leap second at the time zone offset of UTC-00:03:57
/// (there are several historical examples comparable to this "non-sense" offset),
/// and therefore is allowed.
///
- /// ~~~~
+ /// ```
/// # use chrono::{NaiveTime, Timelike};
- /// # let dt = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
+ /// # let dt = NaiveTime::from_hms_nano_opt(23, 56, 4, 12_345_678).unwrap();
/// assert_eq!(dt.with_nanosecond(1_333_333_333),
- /// Some(NaiveTime::from_hms_nano(23, 56, 4, 1_333_333_333)));
- /// ~~~~
+ /// Some(NaiveTime::from_hms_nano_opt(23, 56, 4, 1_333_333_333).unwrap()));
+ /// ```
#[inline]
fn with_nanosecond(&self, nano: u32) -> Option<NaiveTime> {
if nano >= 2_000_000_000 {
@@ -993,33 +950,22 @@ impl Timelike for NaiveTime {
///
/// # Example
///
- /// ~~~~
+ /// ```
/// use chrono::{NaiveTime, Timelike};
///
- /// assert_eq!(NaiveTime::from_hms(1, 2, 3).num_seconds_from_midnight(),
+ /// assert_eq!(NaiveTime::from_hms_opt(1, 2, 3).unwrap().num_seconds_from_midnight(),
/// 3723);
- /// assert_eq!(NaiveTime::from_hms_nano(23, 56, 4, 12_345_678).num_seconds_from_midnight(),
+ /// assert_eq!(NaiveTime::from_hms_nano_opt(23, 56, 4, 12_345_678).unwrap().num_seconds_from_midnight(),
/// 86164);
- /// assert_eq!(NaiveTime::from_hms_milli(23, 59, 59, 1_000).num_seconds_from_midnight(),
+ /// assert_eq!(NaiveTime::from_hms_milli_opt(23, 59, 59, 1_000).unwrap().num_seconds_from_midnight(),
/// 86399);
- /// ~~~~
+ /// ```
#[inline]
fn num_seconds_from_midnight(&self) -> u32 {
self.secs // do not repeat the calculation!
}
}
-/// `NaiveTime` can be used as a key to the hash maps (in principle).
-///
-/// Practically this also takes account of fractional seconds, so it is not recommended.
-/// (For the obvious reason this also distinguishes leap seconds from non-leap seconds.)
-impl hash::Hash for NaiveTime {
- fn hash<H: hash::Hasher>(&self, state: &mut H) {
- self.secs.hash(state);
- self.frac.hash(state);
- }
-}
-
/// An addition of `Duration` to `NaiveTime` wraps around and never overflows or underflows.
/// In particular the addition ignores integral number of days.
///
@@ -1030,8 +976,7 @@ impl hash::Hash for NaiveTime {
///
/// # Example
///
-/// ~~~~
-/// # extern crate chrono; fn main() {
+/// ```
/// use chrono::{Duration, NaiveTime};
///
/// let from_hmsm = NaiveTime::from_hms_milli;
@@ -1044,25 +989,21 @@ impl hash::Hash for NaiveTime {
/// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::milliseconds(80), from_hmsm(3, 5, 7, 80));
/// assert_eq!(from_hmsm(3, 5, 7, 950) + Duration::milliseconds(280), from_hmsm(3, 5, 8, 230));
/// assert_eq!(from_hmsm(3, 5, 7, 950) + Duration::milliseconds(-980), from_hmsm(3, 5, 6, 970));
-/// # }
-/// ~~~~
+/// ```
///
/// The addition wraps around.
///
-/// ~~~~
-/// # extern crate chrono; fn main() {
+/// ```
/// # use chrono::{Duration, NaiveTime};
/// # let from_hmsm = NaiveTime::from_hms_milli;
/// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(22*60*60), from_hmsm(1, 5, 7, 0));
/// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::seconds(-8*60*60), from_hmsm(19, 5, 7, 0));
/// assert_eq!(from_hmsm(3, 5, 7, 0) + Duration::days(800), from_hmsm(3, 5, 7, 0));
-/// # }
-/// ~~~~
+/// ```
///
/// Leap seconds are handled, but the addition assumes that it is the only leap second happened.
///
-/// ~~~~
-/// # extern crate chrono; fn main() {
+/// ```
/// # use chrono::{Duration, NaiveTime};
/// # let from_hmsm = NaiveTime::from_hms_milli;
/// let leap = from_hmsm(3, 5, 59, 1_300);
@@ -1073,8 +1014,7 @@ impl hash::Hash for NaiveTime {
/// assert_eq!(leap + Duration::seconds(10), from_hmsm(3, 6, 9, 300));
/// assert_eq!(leap + Duration::seconds(-10), from_hmsm(3, 5, 50, 300));
/// assert_eq!(leap + Duration::days(1), from_hmsm(3, 5, 59, 300));
-/// # }
-/// ~~~~
+/// ```
impl Add<OldDuration> for NaiveTime {
type Output = NaiveTime;
@@ -1102,8 +1042,7 @@ impl AddAssign<OldDuration> for NaiveTime {
///
/// # Example
///
-/// ~~~~
-/// # extern crate chrono; fn main() {
+/// ```
/// use chrono::{Duration, NaiveTime};
///
/// let from_hmsm = NaiveTime::from_hms_milli;
@@ -1114,24 +1053,20 @@ impl AddAssign<OldDuration> for NaiveTime {
/// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::seconds(2*60*60 + 6*60), from_hmsm(0, 59, 7, 0));
/// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::milliseconds(80), from_hmsm(3, 5, 6, 920));
/// assert_eq!(from_hmsm(3, 5, 7, 950) - Duration::milliseconds(280), from_hmsm(3, 5, 7, 670));
-/// # }
-/// ~~~~
+/// ```
///
/// The subtraction wraps around.
///
-/// ~~~~
-/// # extern crate chrono; fn main() {
+/// ```
/// # use chrono::{Duration, NaiveTime};
/// # let from_hmsm = NaiveTime::from_hms_milli;
/// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::seconds(8*60*60), from_hmsm(19, 5, 7, 0));
/// assert_eq!(from_hmsm(3, 5, 7, 0) - Duration::days(800), from_hmsm(3, 5, 7, 0));
-/// # }
-/// ~~~~
+/// ```
///
/// Leap seconds are handled, but the subtraction assumes that it is the only leap second happened.
///
-/// ~~~~
-/// # extern crate chrono; fn main() {
+/// ```
/// # use chrono::{Duration, NaiveTime};
/// # let from_hmsm = NaiveTime::from_hms_milli;
/// let leap = from_hmsm(3, 5, 59, 1_300);
@@ -1140,8 +1075,7 @@ impl AddAssign<OldDuration> for NaiveTime {
/// assert_eq!(leap - Duration::milliseconds(500), from_hmsm(3, 5, 59, 800));
/// assert_eq!(leap - Duration::seconds(60), from_hmsm(3, 5, 0, 300));
/// assert_eq!(leap - Duration::days(1), from_hmsm(3, 6, 0, 300));
-/// # }
-/// ~~~~
+/// ```
impl Sub<OldDuration> for NaiveTime {
type Output = NaiveTime;
@@ -1173,8 +1107,7 @@ impl SubAssign<OldDuration> for NaiveTime {
///
/// # Example
///
-/// ~~~~
-/// # extern crate chrono; fn main() {
+/// ```
/// use chrono::{Duration, NaiveTime};
///
/// let from_hmsm = NaiveTime::from_hms_milli;
@@ -1188,14 +1121,12 @@ impl SubAssign<OldDuration> for NaiveTime {
/// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(4, 5, 7, 900), Duration::seconds(-3600));
/// assert_eq!(from_hmsm(3, 5, 7, 900) - from_hmsm(2, 4, 6, 800),
/// Duration::seconds(3600 + 60 + 1) + Duration::milliseconds(100));
-/// # }
-/// ~~~~
+/// ```
///
/// Leap seconds are handled, but the subtraction assumes that
/// there were no other leap seconds happened.
///
-/// ~~~~
-/// # extern crate chrono; fn main() {
+/// ```
/// # use chrono::{Duration, NaiveTime};
/// # let from_hmsm = NaiveTime::from_hms_milli;
/// assert_eq!(from_hmsm(3, 0, 59, 1_000) - from_hmsm(3, 0, 59, 0), Duration::seconds(1));
@@ -1205,8 +1136,7 @@ impl SubAssign<OldDuration> for NaiveTime {
/// assert_eq!(from_hmsm(3, 0, 0, 0) - from_hmsm(2, 59, 59, 1_000), Duration::seconds(1));
/// assert_eq!(from_hmsm(3, 0, 59, 1_000) - from_hmsm(2, 59, 59, 1_000),
/// Duration::seconds(61));
-/// # }
-/// ~~~~
+/// ```
impl Sub<NaiveTime> for NaiveTime {
type Output = OldDuration;
@@ -1229,21 +1159,21 @@ impl Sub<NaiveTime> for NaiveTime {
///
/// # Example
///
-/// ~~~~
+/// ```
/// use chrono::NaiveTime;
///
-/// assert_eq!(format!("{:?}", NaiveTime::from_hms(23, 56, 4)), "23:56:04");
-/// assert_eq!(format!("{:?}", NaiveTime::from_hms_milli(23, 56, 4, 12)), "23:56:04.012");
-/// assert_eq!(format!("{:?}", NaiveTime::from_hms_micro(23, 56, 4, 1234)), "23:56:04.001234");
-/// assert_eq!(format!("{:?}", NaiveTime::from_hms_nano(23, 56, 4, 123456)), "23:56:04.000123456");
-/// ~~~~
+/// assert_eq!(format!("{:?}", NaiveTime::from_hms_opt(23, 56, 4).unwrap()), "23:56:04");
+/// assert_eq!(format!("{:?}", NaiveTime::from_hms_milli_opt(23, 56, 4, 12).unwrap()), "23:56:04.012");
+/// assert_eq!(format!("{:?}", NaiveTime::from_hms_micro_opt(23, 56, 4, 1234).unwrap()), "23:56:04.001234");
+/// assert_eq!(format!("{:?}", NaiveTime::from_hms_nano_opt(23, 56, 4, 123456).unwrap()), "23:56:04.000123456");
+/// ```
///
/// Leap seconds may also be used.
///
-/// ~~~~
+/// ```
/// # use chrono::NaiveTime;
-/// assert_eq!(format!("{:?}", NaiveTime::from_hms_milli(6, 59, 59, 1_500)), "06:59:60.500");
-/// ~~~~
+/// assert_eq!(format!("{:?}", NaiveTime::from_hms_milli_opt(6, 59, 59, 1_500).unwrap()), "06:59:60.500");
+/// ```
impl fmt::Debug for NaiveTime {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let (hour, min, sec) = self.hms();
@@ -1253,7 +1183,13 @@ impl fmt::Debug for NaiveTime {
(sec, self.frac)
};
- write!(f, "{:02}:{:02}:{:02}", hour, min, sec)?;
+ use core::fmt::Write;
+ write_hundreds(f, hour as u8)?;
+ f.write_char(':')?;
+ write_hundreds(f, min as u8)?;
+ f.write_char(':')?;
+ write_hundreds(f, sec as u8)?;
+
if nano == 0 {
Ok(())
} else if nano % 1_000_000 == 0 {
@@ -1279,21 +1215,21 @@ impl fmt::Debug for NaiveTime {
///
/// # Example
///
-/// ~~~~
+/// ```
/// use chrono::NaiveTime;
///
-/// assert_eq!(format!("{}", NaiveTime::from_hms(23, 56, 4)), "23:56:04");
-/// assert_eq!(format!("{}", NaiveTime::from_hms_milli(23, 56, 4, 12)), "23:56:04.012");
-/// assert_eq!(format!("{}", NaiveTime::from_hms_micro(23, 56, 4, 1234)), "23:56:04.001234");
-/// assert_eq!(format!("{}", NaiveTime::from_hms_nano(23, 56, 4, 123456)), "23:56:04.000123456");
-/// ~~~~
+/// assert_eq!(format!("{}", NaiveTime::from_hms_opt(23, 56, 4).unwrap()), "23:56:04");
+/// assert_eq!(format!("{}", NaiveTime::from_hms_milli_opt(23, 56, 4, 12).unwrap()), "23:56:04.012");
+/// assert_eq!(format!("{}", NaiveTime::from_hms_micro_opt(23, 56, 4, 1234).unwrap()), "23:56:04.001234");
+/// assert_eq!(format!("{}", NaiveTime::from_hms_nano_opt(23, 56, 4, 123456).unwrap()), "23:56:04.000123456");
+/// ```
///
/// Leap seconds may also be used.
///
-/// ~~~~
+/// ```
/// # use chrono::NaiveTime;
-/// assert_eq!(format!("{}", NaiveTime::from_hms_milli(6, 59, 59, 1_500)), "06:59:60.500");
-/// ~~~~
+/// assert_eq!(format!("{}", NaiveTime::from_hms_milli_opt(6, 59, 59, 1_500).unwrap()), "06:59:60.500");
+/// ```
impl fmt::Display for NaiveTime {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(self, f)
@@ -1305,25 +1241,25 @@ impl fmt::Display for NaiveTime {
///
/// # Example
///
-/// ~~~~
+/// ```
/// use chrono::NaiveTime;
///
-/// let t = NaiveTime::from_hms(23, 56, 4);
+/// let t = NaiveTime::from_hms_opt(23, 56, 4).unwrap();
/// assert_eq!("23:56:04".parse::<NaiveTime>(), Ok(t));
///
-/// let t = NaiveTime::from_hms_nano(23, 56, 4, 12_345_678);
+/// let t = NaiveTime::from_hms_nano_opt(23, 56, 4, 12_345_678).unwrap();
/// assert_eq!("23:56:4.012345678".parse::<NaiveTime>(), Ok(t));
///
-/// let t = NaiveTime::from_hms_nano(23, 59, 59, 1_234_567_890); // leap second
+/// let t = NaiveTime::from_hms_nano_opt(23, 59, 59, 1_234_567_890).unwrap(); // leap second
/// assert_eq!("23:59:60.23456789".parse::<NaiveTime>(), Ok(t));
///
/// assert!("foo".parse::<NaiveTime>().is_err());
-/// ~~~~
+/// ```
impl str::FromStr for NaiveTime {
type Err = ParseError;
fn from_str(s: &str) -> ParseResult<NaiveTime> {
- const ITEMS: &'static [Item<'static>] = &[
+ const ITEMS: &[Item<'static>] = &[
Item::Numeric(Numeric::Hour, Pad::Zero),
Item::Space(""),
Item::Literal(":"),
@@ -1341,33 +1277,58 @@ impl str::FromStr for NaiveTime {
}
}
+/// The default value for a NaiveTime is midnight, 00:00:00 exactly.
+///
+/// # Example
+///
+/// ```rust
+/// use chrono::NaiveTime;
+///
+/// let default_time = NaiveTime::default();
+/// assert_eq!(default_time, NaiveTime::from_hms_opt(0, 0, 0).unwrap());
+/// ```
+impl Default for NaiveTime {
+ fn default() -> Self {
+ NaiveTime::from_hms_opt(0, 0, 0).unwrap()
+ }
+}
+
#[cfg(all(test, any(feature = "rustc-serialize", feature = "serde")))]
fn test_encodable_json<F, E>(to_string: F)
where
F: Fn(&NaiveTime) -> Result<String, E>,
E: ::std::fmt::Debug,
{
- assert_eq!(to_string(&NaiveTime::from_hms(0, 0, 0)).ok(), Some(r#""00:00:00""#.into()));
assert_eq!(
- to_string(&NaiveTime::from_hms_milli(0, 0, 0, 950)).ok(),
+ to_string(&NaiveTime::from_hms_opt(0, 0, 0).unwrap()).ok(),
+ Some(r#""00:00:00""#.into())
+ );
+ assert_eq!(
+ to_string(&NaiveTime::from_hms_milli_opt(0, 0, 0, 950).unwrap()).ok(),
Some(r#""00:00:00.950""#.into())
);
assert_eq!(
- to_string(&NaiveTime::from_hms_milli(0, 0, 59, 1_000)).ok(),
+ to_string(&NaiveTime::from_hms_milli_opt(0, 0, 59, 1_000).unwrap()).ok(),
Some(r#""00:00:60""#.into())
);
- assert_eq!(to_string(&NaiveTime::from_hms(0, 1, 2)).ok(), Some(r#""00:01:02""#.into()));
assert_eq!(
- to_string(&NaiveTime::from_hms_nano(3, 5, 7, 98765432)).ok(),
+ to_string(&NaiveTime::from_hms_opt(0, 1, 2).unwrap()).ok(),
+ Some(r#""00:01:02""#.into())
+ );
+ assert_eq!(
+ to_string(&NaiveTime::from_hms_nano_opt(3, 5, 7, 98765432).unwrap()).ok(),
Some(r#""03:05:07.098765432""#.into())
);
- assert_eq!(to_string(&NaiveTime::from_hms(7, 8, 9)).ok(), Some(r#""07:08:09""#.into()));
assert_eq!(
- to_string(&NaiveTime::from_hms_micro(12, 34, 56, 789)).ok(),
+ to_string(&NaiveTime::from_hms_opt(7, 8, 9).unwrap()).ok(),
+ Some(r#""07:08:09""#.into())
+ );
+ assert_eq!(
+ to_string(&NaiveTime::from_hms_micro_opt(12, 34, 56, 789).unwrap()).ok(),
Some(r#""12:34:56.000789""#.into())
);
assert_eq!(
- to_string(&NaiveTime::from_hms_nano(23, 59, 59, 1_999_999_999)).ok(),
+ to_string(&NaiveTime::from_hms_nano_opt(23, 59, 59, 1_999_999_999).unwrap()).ok(),
Some(r#""23:59:60.999999999""#.into())
);
}
@@ -1378,28 +1339,37 @@ where
F: Fn(&str) -> Result<NaiveTime, E>,
E: ::std::fmt::Debug,
{
- assert_eq!(from_str(r#""00:00:00""#).ok(), Some(NaiveTime::from_hms(0, 0, 0)));
- assert_eq!(from_str(r#""0:0:0""#).ok(), Some(NaiveTime::from_hms(0, 0, 0)));
- assert_eq!(from_str(r#""00:00:00.950""#).ok(), Some(NaiveTime::from_hms_milli(0, 0, 0, 950)));
- assert_eq!(from_str(r#""0:0:0.95""#).ok(), Some(NaiveTime::from_hms_milli(0, 0, 0, 950)));
- assert_eq!(from_str(r#""00:00:60""#).ok(), Some(NaiveTime::from_hms_milli(0, 0, 59, 1_000)));
- assert_eq!(from_str(r#""00:01:02""#).ok(), Some(NaiveTime::from_hms(0, 1, 2)));
+ assert_eq!(from_str(r#""00:00:00""#).ok(), Some(NaiveTime::from_hms_opt(0, 0, 0).unwrap()));
+ assert_eq!(from_str(r#""0:0:0""#).ok(), Some(NaiveTime::from_hms_opt(0, 0, 0).unwrap()));
+ assert_eq!(
+ from_str(r#""00:00:00.950""#).ok(),
+ Some(NaiveTime::from_hms_milli_opt(0, 0, 0, 950).unwrap())
+ );
+ assert_eq!(
+ from_str(r#""0:0:0.95""#).ok(),
+ Some(NaiveTime::from_hms_milli_opt(0, 0, 0, 950).unwrap())
+ );
+ assert_eq!(
+ from_str(r#""00:00:60""#).ok(),
+ Some(NaiveTime::from_hms_milli_opt(0, 0, 59, 1_000).unwrap())
+ );
+ assert_eq!(from_str(r#""00:01:02""#).ok(), Some(NaiveTime::from_hms_opt(0, 1, 2).unwrap()));
assert_eq!(
from_str(r#""03:05:07.098765432""#).ok(),
- Some(NaiveTime::from_hms_nano(3, 5, 7, 98765432))
+ Some(NaiveTime::from_hms_nano_opt(3, 5, 7, 98765432).unwrap())
);
- assert_eq!(from_str(r#""07:08:09""#).ok(), Some(NaiveTime::from_hms(7, 8, 9)));
+ assert_eq!(from_str(r#""07:08:09""#).ok(), Some(NaiveTime::from_hms_opt(7, 8, 9).unwrap()));
assert_eq!(
from_str(r#""12:34:56.000789""#).ok(),
- Some(NaiveTime::from_hms_micro(12, 34, 56, 789))
+ Some(NaiveTime::from_hms_micro_opt(12, 34, 56, 789).unwrap())
);
assert_eq!(
from_str(r#""23:59:60.999999999""#).ok(),
- Some(NaiveTime::from_hms_nano(23, 59, 59, 1_999_999_999))
+ Some(NaiveTime::from_hms_nano_opt(23, 59, 59, 1_999_999_999).unwrap())
);
assert_eq!(
from_str(r#""23:59:60.9999999999997""#).ok(), // excess digits are ignored
- Some(NaiveTime::from_hms_nano(23, 59, 59, 1_999_999_999))
+ Some(NaiveTime::from_hms_nano_opt(23, 59, 59, 1_999_999_999).unwrap())
);
// bad formats
@@ -1418,397 +1388,3 @@ where
assert!(from_str(r#"{"secs":0,"frac":0}"#).is_err());
assert!(from_str(r#"null"#).is_err());
}
-
-#[cfg(feature = "rustc-serialize")]
-mod rustc_serialize {
- use super::NaiveTime;
- use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
-
- impl Encodable for NaiveTime {
- fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
- format!("{:?}", self).encode(s)
- }
- }
-
- impl Decodable for NaiveTime {
- fn decode<D: Decoder>(d: &mut D) -> Result<NaiveTime, D::Error> {
- d.read_str()?.parse().map_err(|_| d.error("invalid time"))
- }
- }
-
- #[cfg(test)]
- use rustc_serialize::json;
-
- #[test]
- fn test_encodable() {
- super::test_encodable_json(json::encode);
- }
-
- #[test]
- fn test_decodable() {
- super::test_decodable_json(json::decode);
- }
-}
-
-#[cfg(feature = "serde")]
-mod serde {
- use super::NaiveTime;
- use core::fmt;
- use serdelib::{de, ser};
-
- // TODO not very optimized for space (binary formats would want something better)
- // TODO round-trip for general leap seconds (not just those with second = 60)
-
- impl ser::Serialize for NaiveTime {
- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- where
- S: ser::Serializer,
- {
- serializer.collect_str(&self)
- }
- }
-
- struct NaiveTimeVisitor;
-
- impl<'de> de::Visitor<'de> for NaiveTimeVisitor {
- type Value = NaiveTime;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- write!(formatter, "a formatted time string")
- }
-
- fn visit_str<E>(self, value: &str) -> Result<NaiveTime, E>
- where
- E: de::Error,
- {
- value.parse().map_err(E::custom)
- }
- }
-
- impl<'de> de::Deserialize<'de> for NaiveTime {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: de::Deserializer<'de>,
- {
- deserializer.deserialize_str(NaiveTimeVisitor)
- }
- }
-
- #[cfg(test)]
- extern crate bincode;
- #[cfg(test)]
- extern crate serde_json;
-
- #[test]
- fn test_serde_serialize() {
- super::test_encodable_json(self::serde_json::to_string);
- }
-
- #[test]
- fn test_serde_deserialize() {
- super::test_decodable_json(|input| self::serde_json::from_str(&input));
- }
-
- #[test]
- fn test_serde_bincode() {
- // Bincode is relevant to test separately from JSON because
- // it is not self-describing.
- use self::bincode::{deserialize, serialize, Infinite};
-
- let t = NaiveTime::from_hms_nano(3, 5, 7, 98765432);
- let encoded = serialize(&t, Infinite).unwrap();
- let decoded: NaiveTime = deserialize(&encoded).unwrap();
- assert_eq!(t, decoded);
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::NaiveTime;
- use oldtime::Duration;
- use std::u32;
- use Timelike;
-
- #[test]
- fn test_time_from_hms_milli() {
- assert_eq!(
- NaiveTime::from_hms_milli_opt(3, 5, 7, 0),
- Some(NaiveTime::from_hms_nano(3, 5, 7, 0))
- );
- assert_eq!(
- NaiveTime::from_hms_milli_opt(3, 5, 7, 777),
- Some(NaiveTime::from_hms_nano(3, 5, 7, 777_000_000))
- );
- assert_eq!(
- NaiveTime::from_hms_milli_opt(3, 5, 7, 1_999),
- Some(NaiveTime::from_hms_nano(3, 5, 7, 1_999_000_000))
- );
- assert_eq!(NaiveTime::from_hms_milli_opt(3, 5, 7, 2_000), None);
- assert_eq!(NaiveTime::from_hms_milli_opt(3, 5, 7, 5_000), None); // overflow check
- assert_eq!(NaiveTime::from_hms_milli_opt(3, 5, 7, u32::MAX), None);
- }
-
- #[test]
- fn test_time_from_hms_micro() {
- assert_eq!(
- NaiveTime::from_hms_micro_opt(3, 5, 7, 0),
- Some(NaiveTime::from_hms_nano(3, 5, 7, 0))
- );
- assert_eq!(
- NaiveTime::from_hms_micro_opt(3, 5, 7, 333),
- Some(NaiveTime::from_hms_nano(3, 5, 7, 333_000))
- );
- assert_eq!(
- NaiveTime::from_hms_micro_opt(3, 5, 7, 777_777),
- Some(NaiveTime::from_hms_nano(3, 5, 7, 777_777_000))
- );
- assert_eq!(
- NaiveTime::from_hms_micro_opt(3, 5, 7, 1_999_999),
- Some(NaiveTime::from_hms_nano(3, 5, 7, 1_999_999_000))
- );
- assert_eq!(NaiveTime::from_hms_micro_opt(3, 5, 7, 2_000_000), None);
- assert_eq!(NaiveTime::from_hms_micro_opt(3, 5, 7, 5_000_000), None); // overflow check
- assert_eq!(NaiveTime::from_hms_micro_opt(3, 5, 7, u32::MAX), None);
- }
-
- #[test]
- fn test_time_hms() {
- assert_eq!(NaiveTime::from_hms(3, 5, 7).hour(), 3);
- assert_eq!(NaiveTime::from_hms(3, 5, 7).with_hour(0), Some(NaiveTime::from_hms(0, 5, 7)));
- assert_eq!(NaiveTime::from_hms(3, 5, 7).with_hour(23), Some(NaiveTime::from_hms(23, 5, 7)));
- assert_eq!(NaiveTime::from_hms(3, 5, 7).with_hour(24), None);
- assert_eq!(NaiveTime::from_hms(3, 5, 7).with_hour(u32::MAX), None);
-
- assert_eq!(NaiveTime::from_hms(3, 5, 7).minute(), 5);
- assert_eq!(NaiveTime::from_hms(3, 5, 7).with_minute(0), Some(NaiveTime::from_hms(3, 0, 7)));
- assert_eq!(
- NaiveTime::from_hms(3, 5, 7).with_minute(59),
- Some(NaiveTime::from_hms(3, 59, 7))
- );
- assert_eq!(NaiveTime::from_hms(3, 5, 7).with_minute(60), None);
- assert_eq!(NaiveTime::from_hms(3, 5, 7).with_minute(u32::MAX), None);
-
- assert_eq!(NaiveTime::from_hms(3, 5, 7).second(), 7);
- assert_eq!(NaiveTime::from_hms(3, 5, 7).with_second(0), Some(NaiveTime::from_hms(3, 5, 0)));
- assert_eq!(
- NaiveTime::from_hms(3, 5, 7).with_second(59),
- Some(NaiveTime::from_hms(3, 5, 59))
- );
- assert_eq!(NaiveTime::from_hms(3, 5, 7).with_second(60), None);
- assert_eq!(NaiveTime::from_hms(3, 5, 7).with_second(u32::MAX), None);
- }
-
- #[test]
- fn test_time_add() {
- macro_rules! check {
- ($lhs:expr, $rhs:expr, $sum:expr) => {{
- assert_eq!($lhs + $rhs, $sum);
- //assert_eq!($rhs + $lhs, $sum);
- }};
- }
-
- let hmsm = |h, m, s, mi| NaiveTime::from_hms_milli(h, m, s, mi);
-
- check!(hmsm(3, 5, 7, 900), Duration::zero(), hmsm(3, 5, 7, 900));
- check!(hmsm(3, 5, 7, 900), Duration::milliseconds(100), hmsm(3, 5, 8, 0));
- check!(hmsm(3, 5, 7, 1_300), Duration::milliseconds(-1800), hmsm(3, 5, 6, 500));
- check!(hmsm(3, 5, 7, 1_300), Duration::milliseconds(-800), hmsm(3, 5, 7, 500));
- check!(hmsm(3, 5, 7, 1_300), Duration::milliseconds(-100), hmsm(3, 5, 7, 1_200));
- check!(hmsm(3, 5, 7, 1_300), Duration::milliseconds(100), hmsm(3, 5, 7, 1_400));
- check!(hmsm(3, 5, 7, 1_300), Duration::milliseconds(800), hmsm(3, 5, 8, 100));
- check!(hmsm(3, 5, 7, 1_300), Duration::milliseconds(1800), hmsm(3, 5, 9, 100));
- check!(hmsm(3, 5, 7, 900), Duration::seconds(86399), hmsm(3, 5, 6, 900)); // overwrap
- check!(hmsm(3, 5, 7, 900), Duration::seconds(-86399), hmsm(3, 5, 8, 900));
- check!(hmsm(3, 5, 7, 900), Duration::days(12345), hmsm(3, 5, 7, 900));
- check!(hmsm(3, 5, 7, 1_300), Duration::days(1), hmsm(3, 5, 7, 300));
- check!(hmsm(3, 5, 7, 1_300), Duration::days(-1), hmsm(3, 5, 8, 300));
-
- // regression tests for #37
- check!(hmsm(0, 0, 0, 0), Duration::milliseconds(-990), hmsm(23, 59, 59, 10));
- check!(hmsm(0, 0, 0, 0), Duration::milliseconds(-9990), hmsm(23, 59, 50, 10));
- }
-
- #[test]
- fn test_time_overflowing_add() {
- let hmsm = NaiveTime::from_hms_milli;
-
- assert_eq!(
- hmsm(3, 4, 5, 678).overflowing_add_signed(Duration::hours(11)),
- (hmsm(14, 4, 5, 678), 0)
- );
- assert_eq!(
- hmsm(3, 4, 5, 678).overflowing_add_signed(Duration::hours(23)),
- (hmsm(2, 4, 5, 678), 86_400)
- );
- assert_eq!(
- hmsm(3, 4, 5, 678).overflowing_add_signed(Duration::hours(-7)),
- (hmsm(20, 4, 5, 678), -86_400)
- );
-
- // overflowing_add_signed with leap seconds may be counter-intuitive
- assert_eq!(
- hmsm(3, 4, 5, 1_678).overflowing_add_signed(Duration::days(1)),
- (hmsm(3, 4, 5, 678), 86_400)
- );
- assert_eq!(
- hmsm(3, 4, 5, 1_678).overflowing_add_signed(Duration::days(-1)),
- (hmsm(3, 4, 6, 678), -86_400)
- );
- }
-
- #[test]
- fn test_time_addassignment() {
- let hms = NaiveTime::from_hms;
- let mut time = hms(12, 12, 12);
- time += Duration::hours(10);
- assert_eq!(time, hms(22, 12, 12));
- time += Duration::hours(10);
- assert_eq!(time, hms(8, 12, 12));
- }
-
- #[test]
- fn test_time_subassignment() {
- let hms = NaiveTime::from_hms;
- let mut time = hms(12, 12, 12);
- time -= Duration::hours(10);
- assert_eq!(time, hms(2, 12, 12));
- time -= Duration::hours(10);
- assert_eq!(time, hms(16, 12, 12));
- }
-
- #[test]
- fn test_time_sub() {
- macro_rules! check {
- ($lhs:expr, $rhs:expr, $diff:expr) => {{
- // `time1 - time2 = duration` is equivalent to `time2 - time1 = -duration`
- assert_eq!($lhs.signed_duration_since($rhs), $diff);
- assert_eq!($rhs.signed_duration_since($lhs), -$diff);
- }};
- }
-
- let hmsm = |h, m, s, mi| NaiveTime::from_hms_milli(h, m, s, mi);
-
- check!(hmsm(3, 5, 7, 900), hmsm(3, 5, 7, 900), Duration::zero());
- check!(hmsm(3, 5, 7, 900), hmsm(3, 5, 7, 600), Duration::milliseconds(300));
- check!(hmsm(3, 5, 7, 200), hmsm(2, 4, 6, 200), Duration::seconds(3600 + 60 + 1));
- check!(
- hmsm(3, 5, 7, 200),
- hmsm(2, 4, 6, 300),
- Duration::seconds(3600 + 60) + Duration::milliseconds(900)
- );
-
- // treats the leap second as if it coincides with the prior non-leap second,
- // as required by `time1 - time2 = duration` and `time2 - time1 = -duration` equivalence.
- check!(hmsm(3, 5, 7, 200), hmsm(3, 5, 6, 1_800), Duration::milliseconds(400));
- check!(hmsm(3, 5, 7, 1_200), hmsm(3, 5, 6, 1_800), Duration::milliseconds(1400));
- check!(hmsm(3, 5, 7, 1_200), hmsm(3, 5, 6, 800), Duration::milliseconds(1400));
-
- // additional equality: `time1 + duration = time2` is equivalent to
- // `time2 - time1 = duration` IF AND ONLY IF `time2` represents a non-leap second.
- assert_eq!(hmsm(3, 5, 6, 800) + Duration::milliseconds(400), hmsm(3, 5, 7, 200));
- assert_eq!(hmsm(3, 5, 6, 1_800) + Duration::milliseconds(400), hmsm(3, 5, 7, 200));
- }
-
- #[test]
- fn test_time_fmt() {
- assert_eq!(format!("{}", NaiveTime::from_hms_milli(23, 59, 59, 999)), "23:59:59.999");
- assert_eq!(format!("{}", NaiveTime::from_hms_milli(23, 59, 59, 1_000)), "23:59:60");
- assert_eq!(format!("{}", NaiveTime::from_hms_milli(23, 59, 59, 1_001)), "23:59:60.001");
- assert_eq!(format!("{}", NaiveTime::from_hms_micro(0, 0, 0, 43210)), "00:00:00.043210");
- assert_eq!(format!("{}", NaiveTime::from_hms_nano(0, 0, 0, 6543210)), "00:00:00.006543210");
-
- // the format specifier should have no effect on `NaiveTime`
- assert_eq!(format!("{:30}", NaiveTime::from_hms_milli(3, 5, 7, 9)), "03:05:07.009");
- }
-
- #[test]
- fn test_date_from_str() {
- // valid cases
- let valid = [
- "0:0:0",
- "0:0:0.0000000",
- "0:0:0.0000003",
- " 4 : 3 : 2.1 ",
- " 09:08:07 ",
- " 9:8:07 ",
- "23:59:60.373929310237",
- ];
- for &s in &valid {
- let d = match s.parse::<NaiveTime>() {
- Ok(d) => d,
- Err(e) => panic!("parsing `{}` has failed: {}", s, e),
- };
- let s_ = format!("{:?}", d);
- // `s` and `s_` may differ, but `s.parse()` and `s_.parse()` must be same
- let d_ = match s_.parse::<NaiveTime>() {
- Ok(d) => d,
- Err(e) => {
- panic!("`{}` is parsed into `{:?}`, but reparsing that has failed: {}", s, d, e)
- }
- };
- assert!(
- d == d_,
- "`{}` is parsed into `{:?}`, but reparsed result \
- `{:?}` does not match",
- s,
- d,
- d_
- );
- }
-
- // some invalid cases
- // since `ParseErrorKind` is private, all we can do is to check if there was an error
- assert!("".parse::<NaiveTime>().is_err());
- assert!("x".parse::<NaiveTime>().is_err());
- assert!("15".parse::<NaiveTime>().is_err());
- assert!("15:8".parse::<NaiveTime>().is_err());
- assert!("15:8:x".parse::<NaiveTime>().is_err());
- assert!("15:8:9x".parse::<NaiveTime>().is_err());
- assert!("23:59:61".parse::<NaiveTime>().is_err());
- assert!("12:34:56.x".parse::<NaiveTime>().is_err());
- assert!("12:34:56. 0".parse::<NaiveTime>().is_err());
- }
-
- #[test]
- fn test_time_parse_from_str() {
- let hms = |h, m, s| NaiveTime::from_hms(h, m, s);
- assert_eq!(
- NaiveTime::parse_from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
- Ok(hms(12, 34, 56))
- ); // ignore date and offset
- assert_eq!(NaiveTime::parse_from_str("PM 12:59", "%P %H:%M"), Ok(hms(12, 59, 0)));
- assert!(NaiveTime::parse_from_str("12:3456", "%H:%M:%S").is_err());
- }
-
- #[test]
- fn test_time_format() {
- let t = NaiveTime::from_hms_nano(3, 5, 7, 98765432);
- assert_eq!(t.format("%H,%k,%I,%l,%P,%p").to_string(), "03, 3,03, 3,am,AM");
- assert_eq!(t.format("%M").to_string(), "05");
- assert_eq!(t.format("%S,%f,%.f").to_string(), "07,098765432,.098765432");
- assert_eq!(t.format("%.3f,%.6f,%.9f").to_string(), ".098,.098765,.098765432");
- assert_eq!(t.format("%R").to_string(), "03:05");
- assert_eq!(t.format("%T,%X").to_string(), "03:05:07,03:05:07");
- assert_eq!(t.format("%r").to_string(), "03:05:07 AM");
- assert_eq!(t.format("%t%n%%%n%t").to_string(), "\t\n%\n\t");
-
- let t = NaiveTime::from_hms_micro(3, 5, 7, 432100);
- assert_eq!(t.format("%S,%f,%.f").to_string(), "07,432100000,.432100");
- assert_eq!(t.format("%.3f,%.6f,%.9f").to_string(), ".432,.432100,.432100000");
-
- let t = NaiveTime::from_hms_milli(3, 5, 7, 210);
- assert_eq!(t.format("%S,%f,%.f").to_string(), "07,210000000,.210");
- assert_eq!(t.format("%.3f,%.6f,%.9f").to_string(), ".210,.210000,.210000000");
-
- let t = NaiveTime::from_hms(3, 5, 7);
- assert_eq!(t.format("%S,%f,%.f").to_string(), "07,000000000,");
- assert_eq!(t.format("%.3f,%.6f,%.9f").to_string(), ".000,.000000,.000000000");
-
- // corner cases
- assert_eq!(NaiveTime::from_hms(13, 57, 9).format("%r").to_string(), "01:57:09 PM");
- assert_eq!(
- NaiveTime::from_hms_milli(23, 59, 59, 1_000).format("%X").to_string(),
- "23:59:60"
- );
- }
-}
diff --git a/vendor/chrono/src/naive/time/rustc_serialize.rs b/vendor/chrono/src/naive/time/rustc_serialize.rs
new file mode 100644
index 000000000..9eaf68219
--- /dev/null
+++ b/vendor/chrono/src/naive/time/rustc_serialize.rs
@@ -0,0 +1,29 @@
+#![cfg_attr(docsrs, doc(cfg(feature = "rustc-serialize")))]
+
+use super::NaiveTime;
+use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
+
+impl Encodable for NaiveTime {
+ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+ format!("{:?}", self).encode(s)
+ }
+}
+
+impl Decodable for NaiveTime {
+ fn decode<D: Decoder>(d: &mut D) -> Result<NaiveTime, D::Error> {
+ d.read_str()?.parse().map_err(|_| d.error("invalid time"))
+ }
+}
+
+#[cfg(test)]
+use rustc_serialize::json;
+
+#[test]
+fn test_encodable() {
+ super::test_encodable_json(json::encode);
+}
+
+#[test]
+fn test_decodable() {
+ super::test_decodable_json(json::decode);
+}
diff --git a/vendor/chrono/src/naive/time/serde.rs b/vendor/chrono/src/naive/time/serde.rs
new file mode 100644
index 000000000..c7394fb57
--- /dev/null
+++ b/vendor/chrono/src/naive/time/serde.rs
@@ -0,0 +1,65 @@
+#![cfg_attr(docsrs, doc(cfg(feature = "serde")))]
+
+use super::NaiveTime;
+use core::fmt;
+use serde::{de, ser};
+
+// TODO not very optimized for space (binary formats would want something better)
+// TODO round-trip for general leap seconds (not just those with second = 60)
+
+impl ser::Serialize for NaiveTime {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ serializer.collect_str(&self)
+ }
+}
+
+struct NaiveTimeVisitor;
+
+impl<'de> de::Visitor<'de> for NaiveTimeVisitor {
+ type Value = NaiveTime;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a formatted time string")
+ }
+
+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ value.parse().map_err(E::custom)
+ }
+}
+
+impl<'de> de::Deserialize<'de> for NaiveTime {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ deserializer.deserialize_str(NaiveTimeVisitor)
+ }
+}
+
+#[test]
+fn test_serde_serialize() {
+ super::test_encodable_json(serde_json::to_string);
+}
+
+#[test]
+fn test_serde_deserialize() {
+ super::test_decodable_json(|input| serde_json::from_str(input));
+}
+
+#[test]
+fn test_serde_bincode() {
+ // Bincode is relevant to test separately from JSON because
+ // it is not self-describing.
+ use bincode::{deserialize, serialize};
+
+ let t = NaiveTime::from_hms_nano_opt(3, 5, 7, 98765432).unwrap();
+ let encoded = serialize(&t).unwrap();
+ let decoded: NaiveTime = deserialize(&encoded).unwrap();
+ assert_eq!(t, decoded);
+}
diff --git a/vendor/chrono/src/naive/time/tests.rs b/vendor/chrono/src/naive/time/tests.rs
new file mode 100644
index 000000000..62c46a247
--- /dev/null
+++ b/vendor/chrono/src/naive/time/tests.rs
@@ -0,0 +1,317 @@
+use super::NaiveTime;
+use crate::oldtime::Duration;
+use crate::Timelike;
+use std::u32;
+
+#[test]
+fn test_time_from_hms_milli() {
+ assert_eq!(
+ NaiveTime::from_hms_milli_opt(3, 5, 7, 0),
+ Some(NaiveTime::from_hms_nano_opt(3, 5, 7, 0).unwrap())
+ );
+ assert_eq!(
+ NaiveTime::from_hms_milli_opt(3, 5, 7, 777),
+ Some(NaiveTime::from_hms_nano_opt(3, 5, 7, 777_000_000).unwrap())
+ );
+ assert_eq!(
+ NaiveTime::from_hms_milli_opt(3, 5, 7, 1_999),
+ Some(NaiveTime::from_hms_nano_opt(3, 5, 7, 1_999_000_000).unwrap())
+ );
+ assert_eq!(NaiveTime::from_hms_milli_opt(3, 5, 7, 2_000), None);
+ assert_eq!(NaiveTime::from_hms_milli_opt(3, 5, 7, 5_000), None); // overflow check
+ assert_eq!(NaiveTime::from_hms_milli_opt(3, 5, 7, u32::MAX), None);
+}
+
+#[test]
+fn test_time_from_hms_micro() {
+ assert_eq!(
+ NaiveTime::from_hms_micro_opt(3, 5, 7, 0),
+ Some(NaiveTime::from_hms_nano_opt(3, 5, 7, 0).unwrap())
+ );
+ assert_eq!(
+ NaiveTime::from_hms_micro_opt(3, 5, 7, 333),
+ Some(NaiveTime::from_hms_nano_opt(3, 5, 7, 333_000).unwrap())
+ );
+ assert_eq!(
+ NaiveTime::from_hms_micro_opt(3, 5, 7, 777_777),
+ Some(NaiveTime::from_hms_nano_opt(3, 5, 7, 777_777_000).unwrap())
+ );
+ assert_eq!(
+ NaiveTime::from_hms_micro_opt(3, 5, 7, 1_999_999),
+ Some(NaiveTime::from_hms_nano_opt(3, 5, 7, 1_999_999_000).unwrap())
+ );
+ assert_eq!(NaiveTime::from_hms_micro_opt(3, 5, 7, 2_000_000), None);
+ assert_eq!(NaiveTime::from_hms_micro_opt(3, 5, 7, 5_000_000), None); // overflow check
+ assert_eq!(NaiveTime::from_hms_micro_opt(3, 5, 7, u32::MAX), None);
+}
+
+#[test]
+fn test_time_hms() {
+ assert_eq!(NaiveTime::from_hms_opt(3, 5, 7).unwrap().hour(), 3);
+ assert_eq!(
+ NaiveTime::from_hms_opt(3, 5, 7).unwrap().with_hour(0),
+ Some(NaiveTime::from_hms_opt(0, 5, 7).unwrap())
+ );
+ assert_eq!(
+ NaiveTime::from_hms_opt(3, 5, 7).unwrap().with_hour(23),
+ Some(NaiveTime::from_hms_opt(23, 5, 7).unwrap())
+ );
+ assert_eq!(NaiveTime::from_hms_opt(3, 5, 7).unwrap().with_hour(24), None);
+ assert_eq!(NaiveTime::from_hms_opt(3, 5, 7).unwrap().with_hour(u32::MAX), None);
+
+ assert_eq!(NaiveTime::from_hms_opt(3, 5, 7).unwrap().minute(), 5);
+ assert_eq!(
+ NaiveTime::from_hms_opt(3, 5, 7).unwrap().with_minute(0),
+ Some(NaiveTime::from_hms_opt(3, 0, 7).unwrap())
+ );
+ assert_eq!(
+ NaiveTime::from_hms_opt(3, 5, 7).unwrap().with_minute(59),
+ Some(NaiveTime::from_hms_opt(3, 59, 7).unwrap())
+ );
+ assert_eq!(NaiveTime::from_hms_opt(3, 5, 7).unwrap().with_minute(60), None);
+ assert_eq!(NaiveTime::from_hms_opt(3, 5, 7).unwrap().with_minute(u32::MAX), None);
+
+ assert_eq!(NaiveTime::from_hms_opt(3, 5, 7).unwrap().second(), 7);
+ assert_eq!(
+ NaiveTime::from_hms_opt(3, 5, 7).unwrap().with_second(0),
+ Some(NaiveTime::from_hms_opt(3, 5, 0).unwrap())
+ );
+ assert_eq!(
+ NaiveTime::from_hms_opt(3, 5, 7).unwrap().with_second(59),
+ Some(NaiveTime::from_hms_opt(3, 5, 59).unwrap())
+ );
+ assert_eq!(NaiveTime::from_hms_opt(3, 5, 7).unwrap().with_second(60), None);
+ assert_eq!(NaiveTime::from_hms_opt(3, 5, 7).unwrap().with_second(u32::MAX), None);
+}
+
+#[test]
+fn test_time_add() {
+ macro_rules! check {
+ ($lhs:expr, $rhs:expr, $sum:expr) => {{
+ assert_eq!($lhs + $rhs, $sum);
+ //assert_eq!($rhs + $lhs, $sum);
+ }};
+ }
+
+ let hmsm = |h, m, s, ms| NaiveTime::from_hms_milli_opt(h, m, s, ms).unwrap();
+
+ check!(hmsm(3, 5, 7, 900), Duration::zero(), hmsm(3, 5, 7, 900));
+ check!(hmsm(3, 5, 7, 900), Duration::milliseconds(100), hmsm(3, 5, 8, 0));
+ check!(hmsm(3, 5, 7, 1_300), Duration::milliseconds(-1800), hmsm(3, 5, 6, 500));
+ check!(hmsm(3, 5, 7, 1_300), Duration::milliseconds(-800), hmsm(3, 5, 7, 500));
+ check!(hmsm(3, 5, 7, 1_300), Duration::milliseconds(-100), hmsm(3, 5, 7, 1_200));
+ check!(hmsm(3, 5, 7, 1_300), Duration::milliseconds(100), hmsm(3, 5, 7, 1_400));
+ check!(hmsm(3, 5, 7, 1_300), Duration::milliseconds(800), hmsm(3, 5, 8, 100));
+ check!(hmsm(3, 5, 7, 1_300), Duration::milliseconds(1800), hmsm(3, 5, 9, 100));
+ check!(hmsm(3, 5, 7, 900), Duration::seconds(86399), hmsm(3, 5, 6, 900)); // overwrap
+ check!(hmsm(3, 5, 7, 900), Duration::seconds(-86399), hmsm(3, 5, 8, 900));
+ check!(hmsm(3, 5, 7, 900), Duration::days(12345), hmsm(3, 5, 7, 900));
+ check!(hmsm(3, 5, 7, 1_300), Duration::days(1), hmsm(3, 5, 7, 300));
+ check!(hmsm(3, 5, 7, 1_300), Duration::days(-1), hmsm(3, 5, 8, 300));
+
+ // regression tests for #37
+ check!(hmsm(0, 0, 0, 0), Duration::milliseconds(-990), hmsm(23, 59, 59, 10));
+ check!(hmsm(0, 0, 0, 0), Duration::milliseconds(-9990), hmsm(23, 59, 50, 10));
+}
+
+#[test]
+fn test_time_overflowing_add() {
+ let hmsm = |h, m, s, ms| NaiveTime::from_hms_milli_opt(h, m, s, ms).unwrap();
+
+ assert_eq!(
+ hmsm(3, 4, 5, 678).overflowing_add_signed(Duration::hours(11)),
+ (hmsm(14, 4, 5, 678), 0)
+ );
+ assert_eq!(
+ hmsm(3, 4, 5, 678).overflowing_add_signed(Duration::hours(23)),
+ (hmsm(2, 4, 5, 678), 86_400)
+ );
+ assert_eq!(
+ hmsm(3, 4, 5, 678).overflowing_add_signed(Duration::hours(-7)),
+ (hmsm(20, 4, 5, 678), -86_400)
+ );
+
+ // overflowing_add_signed with leap seconds may be counter-intuitive
+ assert_eq!(
+ hmsm(3, 4, 5, 1_678).overflowing_add_signed(Duration::days(1)),
+ (hmsm(3, 4, 5, 678), 86_400)
+ );
+ assert_eq!(
+ hmsm(3, 4, 5, 1_678).overflowing_add_signed(Duration::days(-1)),
+ (hmsm(3, 4, 6, 678), -86_400)
+ );
+}
+
+#[test]
+fn test_time_addassignment() {
+ let hms = |h, m, s| NaiveTime::from_hms_opt(h, m, s).unwrap();
+ let mut time = hms(12, 12, 12);
+ time += Duration::hours(10);
+ assert_eq!(time, hms(22, 12, 12));
+ time += Duration::hours(10);
+ assert_eq!(time, hms(8, 12, 12));
+}
+
+#[test]
+fn test_time_subassignment() {
+ let hms = |h, m, s| NaiveTime::from_hms_opt(h, m, s).unwrap();
+ let mut time = hms(12, 12, 12);
+ time -= Duration::hours(10);
+ assert_eq!(time, hms(2, 12, 12));
+ time -= Duration::hours(10);
+ assert_eq!(time, hms(16, 12, 12));
+}
+
+#[test]
+fn test_time_sub() {
+ macro_rules! check {
+ ($lhs:expr, $rhs:expr, $diff:expr) => {{
+ // `time1 - time2 = duration` is equivalent to `time2 - time1 = -duration`
+ assert_eq!($lhs.signed_duration_since($rhs), $diff);
+ assert_eq!($rhs.signed_duration_since($lhs), -$diff);
+ }};
+ }
+
+ let hmsm = |h, m, s, ms| NaiveTime::from_hms_milli_opt(h, m, s, ms).unwrap();
+
+ check!(hmsm(3, 5, 7, 900), hmsm(3, 5, 7, 900), Duration::zero());
+ check!(hmsm(3, 5, 7, 900), hmsm(3, 5, 7, 600), Duration::milliseconds(300));
+ check!(hmsm(3, 5, 7, 200), hmsm(2, 4, 6, 200), Duration::seconds(3600 + 60 + 1));
+ check!(
+ hmsm(3, 5, 7, 200),
+ hmsm(2, 4, 6, 300),
+ Duration::seconds(3600 + 60) + Duration::milliseconds(900)
+ );
+
+ // treats the leap second as if it coincides with the prior non-leap second,
+ // as required by `time1 - time2 = duration` and `time2 - time1 = -duration` equivalence.
+ check!(hmsm(3, 5, 7, 200), hmsm(3, 5, 6, 1_800), Duration::milliseconds(400));
+ check!(hmsm(3, 5, 7, 1_200), hmsm(3, 5, 6, 1_800), Duration::milliseconds(1400));
+ check!(hmsm(3, 5, 7, 1_200), hmsm(3, 5, 6, 800), Duration::milliseconds(1400));
+
+ // additional equality: `time1 + duration = time2` is equivalent to
+ // `time2 - time1 = duration` IF AND ONLY IF `time2` represents a non-leap second.
+ assert_eq!(hmsm(3, 5, 6, 800) + Duration::milliseconds(400), hmsm(3, 5, 7, 200));
+ assert_eq!(hmsm(3, 5, 6, 1_800) + Duration::milliseconds(400), hmsm(3, 5, 7, 200));
+}
+
+#[test]
+fn test_time_fmt() {
+ assert_eq!(
+ format!("{}", NaiveTime::from_hms_milli_opt(23, 59, 59, 999).unwrap()),
+ "23:59:59.999"
+ );
+ assert_eq!(
+ format!("{}", NaiveTime::from_hms_milli_opt(23, 59, 59, 1_000).unwrap()),
+ "23:59:60"
+ );
+ assert_eq!(
+ format!("{}", NaiveTime::from_hms_milli_opt(23, 59, 59, 1_001).unwrap()),
+ "23:59:60.001"
+ );
+ assert_eq!(
+ format!("{}", NaiveTime::from_hms_micro_opt(0, 0, 0, 43210).unwrap()),
+ "00:00:00.043210"
+ );
+ assert_eq!(
+ format!("{}", NaiveTime::from_hms_nano_opt(0, 0, 0, 6543210).unwrap()),
+ "00:00:00.006543210"
+ );
+
+ // the format specifier should have no effect on `NaiveTime`
+ assert_eq!(
+ format!("{:30}", NaiveTime::from_hms_milli_opt(3, 5, 7, 9).unwrap()),
+ "03:05:07.009"
+ );
+}
+
+#[test]
+fn test_date_from_str() {
+ // valid cases
+ let valid = [
+ "0:0:0",
+ "0:0:0.0000000",
+ "0:0:0.0000003",
+ " 4 : 3 : 2.1 ",
+ " 09:08:07 ",
+ " 9:8:07 ",
+ "23:59:60.373929310237",
+ ];
+ for &s in &valid {
+ let d = match s.parse::<NaiveTime>() {
+ Ok(d) => d,
+ Err(e) => panic!("parsing `{}` has failed: {}", s, e),
+ };
+ let s_ = format!("{:?}", d);
+ // `s` and `s_` may differ, but `s.parse()` and `s_.parse()` must be same
+ let d_ = match s_.parse::<NaiveTime>() {
+ Ok(d) => d,
+ Err(e) => {
+ panic!("`{}` is parsed into `{:?}`, but reparsing that has failed: {}", s, d, e)
+ }
+ };
+ assert!(
+ d == d_,
+ "`{}` is parsed into `{:?}`, but reparsed result \
+ `{:?}` does not match",
+ s,
+ d,
+ d_
+ );
+ }
+
+ // some invalid cases
+ // since `ParseErrorKind` is private, all we can do is to check if there was an error
+ assert!("".parse::<NaiveTime>().is_err());
+ assert!("x".parse::<NaiveTime>().is_err());
+ assert!("15".parse::<NaiveTime>().is_err());
+ assert!("15:8".parse::<NaiveTime>().is_err());
+ assert!("15:8:x".parse::<NaiveTime>().is_err());
+ assert!("15:8:9x".parse::<NaiveTime>().is_err());
+ assert!("23:59:61".parse::<NaiveTime>().is_err());
+ assert!("12:34:56.x".parse::<NaiveTime>().is_err());
+ assert!("12:34:56. 0".parse::<NaiveTime>().is_err());
+}
+
+#[test]
+fn test_time_parse_from_str() {
+ let hms = |h, m, s| NaiveTime::from_hms_opt(h, m, s).unwrap();
+ assert_eq!(
+ NaiveTime::parse_from_str("2014-5-7T12:34:56+09:30", "%Y-%m-%dT%H:%M:%S%z"),
+ Ok(hms(12, 34, 56))
+ ); // ignore date and offset
+ assert_eq!(NaiveTime::parse_from_str("PM 12:59", "%P %H:%M"), Ok(hms(12, 59, 0)));
+ assert!(NaiveTime::parse_from_str("12:3456", "%H:%M:%S").is_err());
+}
+
+#[test]
+fn test_time_format() {
+ let t = NaiveTime::from_hms_nano_opt(3, 5, 7, 98765432).unwrap();
+ assert_eq!(t.format("%H,%k,%I,%l,%P,%p").to_string(), "03, 3,03, 3,am,AM");
+ assert_eq!(t.format("%M").to_string(), "05");
+ assert_eq!(t.format("%S,%f,%.f").to_string(), "07,098765432,.098765432");
+ assert_eq!(t.format("%.3f,%.6f,%.9f").to_string(), ".098,.098765,.098765432");
+ assert_eq!(t.format("%R").to_string(), "03:05");
+ assert_eq!(t.format("%T,%X").to_string(), "03:05:07,03:05:07");
+ assert_eq!(t.format("%r").to_string(), "03:05:07 AM");
+ assert_eq!(t.format("%t%n%%%n%t").to_string(), "\t\n%\n\t");
+
+ let t = NaiveTime::from_hms_micro_opt(3, 5, 7, 432100).unwrap();
+ assert_eq!(t.format("%S,%f,%.f").to_string(), "07,432100000,.432100");
+ assert_eq!(t.format("%.3f,%.6f,%.9f").to_string(), ".432,.432100,.432100000");
+
+ let t = NaiveTime::from_hms_milli_opt(3, 5, 7, 210).unwrap();
+ assert_eq!(t.format("%S,%f,%.f").to_string(), "07,210000000,.210");
+ assert_eq!(t.format("%.3f,%.6f,%.9f").to_string(), ".210,.210000,.210000000");
+
+ let t = NaiveTime::from_hms_opt(3, 5, 7).unwrap();
+ assert_eq!(t.format("%S,%f,%.f").to_string(), "07,000000000,");
+ assert_eq!(t.format("%.3f,%.6f,%.9f").to_string(), ".000,.000000,.000000000");
+
+ // corner cases
+ assert_eq!(NaiveTime::from_hms_opt(13, 57, 9).unwrap().format("%r").to_string(), "01:57:09 PM");
+ assert_eq!(
+ NaiveTime::from_hms_milli_opt(23, 59, 59, 1_000).unwrap().format("%X").to_string(),
+ "23:59:60"
+ );
+}