You've already forked parse_datetime
mirror of
https://github.com/uutils/parse_datetime.git
synced 2026-06-10 16:13:15 -07:00
parse_datetime: Fix relative date adjustments for months using the actual days
This commit is contained in:
committed by
Sylvestre Ledru
parent
642bbbf214
commit
62cb7d9687
+21
-4
@@ -1,7 +1,7 @@
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
|
||||
use jiff::{civil, Span, Zoned};
|
||||
use jiff::{civil, Span, ToSpan, Zoned};
|
||||
|
||||
use super::{date, epoch, error, offset, relative, time, weekday, year, Item};
|
||||
|
||||
@@ -281,9 +281,26 @@ impl DateTimeBuilder {
|
||||
// 4d. Apply relative adjustments.
|
||||
for rel in self.relative {
|
||||
dt = dt.checked_add::<Span>(if let relative::Relative::Months(x) = rel {
|
||||
// *NOTE* This is done in this way to conform to GNU behavior.
|
||||
let days = dt.date().last_of_month().day() as i32;
|
||||
Span::new().try_days(days.checked_mul(x).ok_or("multiplication overflow")?)?
|
||||
let mut temp = dt.clone();
|
||||
let mut days = 0;
|
||||
if x < 0 {
|
||||
for _ in 0..x.unsigned_abs() as usize {
|
||||
// going backwards we first change the month to last month as last months
|
||||
// days are important to calculate the day delta from now to now -1 month
|
||||
temp = temp.checked_sub(1.month())?;
|
||||
days += temp.date().last_of_month().day();
|
||||
}
|
||||
days *= -1;
|
||||
} else {
|
||||
for _ in 0..x {
|
||||
// going forward we take the days of this month and then change the month to
|
||||
// the next month as going forward the current month is important for the
|
||||
// day delta from now to +1 month
|
||||
days += temp.date().last_of_month().day();
|
||||
temp = temp.checked_add(1.month())?;
|
||||
}
|
||||
}
|
||||
Span::new().try_days(days)?
|
||||
} else {
|
||||
rel.try_into()?
|
||||
})?;
|
||||
|
||||
Reference in New Issue
Block a user