Skip to content

Commit ec60b5a

Browse files
committed
Make DateTime::with_year always return Some when valid
1 parent e990df3 commit ec60b5a

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

src/datetime/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1001,7 +1001,9 @@ impl<Tz: TimeZone> Datelike for DateTime<Tz> {
10011001
/// - The local time at the resulting date does not exist or is ambiguous, for example during a
10021002
/// daylight saving time transition.
10031003
fn with_year(&self, year: i32) -> Option<DateTime<Tz>> {
1004-
map_local(self, |datetime| datetime.with_year(year))
1004+
map_local(self, |dt| {
1005+
dt.date().overflowing_with_year(year).map(|d| NaiveDateTime::new(d, dt.time()))
1006+
})
10051007
}
10061008

10071009
/// Makes a new `DateTime` with the month number (starting from 1) changed.

src/naive/date.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,6 +1460,19 @@ impl NaiveDate {
14601460
self.of().weekday()
14611461
}
14621462

1463+
// Similar to `Datelike::with_year()`, but allows creating a `NaiveDate` beyond `MIN` or `MAX`.
1464+
// Only used by `DateTime::with_year`.
1465+
pub(crate) fn overflowing_with_year(&self, year: i32) -> Option<NaiveDate> {
1466+
// we need to operate with `mdf` since we should keep the month and day number as is
1467+
let mdf = self.mdf();
1468+
1469+
// adjust the flags as needed
1470+
let flags = YearFlags::from_year(year);
1471+
let mdf = mdf.with_flags(flags);
1472+
1473+
mdf.to_of().map(|of| NaiveDate { ymdf: (year << 13) | (of.inner() as DateImpl) })
1474+
}
1475+
14631476
/// The minimum possible `NaiveDate` (January 1, 262144 BCE).
14641477
pub const MIN: NaiveDate = NaiveDate { ymdf: (MIN_YEAR << 13) | (1 << 4) | 0o12 /*D*/ };
14651478
/// The maximum possible `NaiveDate` (December 31, 262142 CE).

0 commit comments

Comments
 (0)