diff --git a/src/datetime/mod.rs b/src/datetime/mod.rs index 8f8b8f3561..5ade1fca34 100644 --- a/src/datetime/mod.rs +++ b/src/datetime/mod.rs @@ -1099,12 +1099,15 @@ impl Datelike for DateTime { /// # Errors /// /// Returns `None` if: - /// - The resulting date does not exist. - /// - When the `NaiveDateTime` would be out of range. /// - The local time at the resulting date does not exist or is ambiguous, for example during a /// daylight saving time transition. + /// - The resulting UTC datetime would be out of range. + /// - The resulting local datetime would be out of range (unless the year remains the same). fn with_year(&self, year: i32) -> Option> { - map_local(self, |datetime| datetime.with_year(year)) + map_local(self, |dt| match dt.year() == year { + true => Some(dt), + false => dt.with_year(year), + }) } /// Makes a new `DateTime` with the month number (starting from 1) changed. diff --git a/src/datetime/tests.rs b/src/datetime/tests.rs index d465797329..425618de04 100644 --- a/src/datetime/tests.rs +++ b/src/datetime/tests.rs @@ -1421,6 +1421,7 @@ fn test_min_max_setters() { let beyond_max = offset_max.from_utc_datetime(&NaiveDateTime::MAX); assert_eq!(beyond_min.with_year(2020).unwrap().year(), 2020); + assert_eq!(beyond_min.with_year(beyond_min.year()), Some(beyond_min)); assert_eq!(beyond_min.with_month(beyond_min.month()), Some(beyond_min)); assert_eq!(beyond_min.with_month(3), None); assert_eq!(beyond_min.with_month0(beyond_min.month0()), Some(beyond_min)); @@ -1441,6 +1442,7 @@ fn test_min_max_setters() { assert_eq!(beyond_min.with_nanosecond(0), Some(beyond_min)); assert_eq!(beyond_max.with_year(2020).unwrap().year(), 2020); + assert_eq!(beyond_max.with_year(beyond_max.year()), Some(beyond_max)); assert_eq!(beyond_max.with_month(beyond_max.month()), Some(beyond_max)); assert_eq!(beyond_max.with_month(3), None); assert_eq!(beyond_max.with_month0(beyond_max.month0()), Some(beyond_max));