refactor(dates): adjust date handling logic for improved accuracy
Updated the logic for handling months and days to improve date calculations. Also modified the constants for Excel date ranges to align with supported dates.
This commit is contained in:
committed by
Nicolás Hatcher Andrés
parent
7c32088480
commit
d04691b790
@@ -18,6 +18,10 @@ pub(crate) const LAST_ROW: i32 = 1_048_576;
|
||||
pub(crate) const EXCEL_DATE_BASE: i32 = 693_594;
|
||||
|
||||
// Excel can handle dates until the year 0000-01-01
|
||||
pub(crate) const EXCEL_DATE_MIN: i32 = -693_959;
|
||||
// However, it uses a different numbering scheme for dates
|
||||
// that are before 1900-01-01.
|
||||
// So for now we will simply not support dates before 1900-01-01.
|
||||
pub(crate) const EXCEL_DATE_MIN: i32 = 2;
|
||||
|
||||
// Excel can handle dates until the year 9999-12-31
|
||||
pub(crate) const EXCEL_DATE_MAX: i32 = 2958465;
|
||||
pub(crate) const EXCEL_DATE_MAX: i32 = 2_958_465;
|
||||
|
||||
@@ -58,11 +58,12 @@ pub fn permissive_date_to_serial_number(day: i32, month: i32, year: i32) -> Resu
|
||||
}
|
||||
|
||||
date = {
|
||||
let abs_month = month.unsigned_abs();
|
||||
if month <= 0 {
|
||||
date = date - Months::new(abs_month + 1);
|
||||
let month_diff = month - 1;
|
||||
let abs_month = month_diff.unsigned_abs();
|
||||
if month_diff <= 0 {
|
||||
date = date - Months::new(abs_month);
|
||||
} else {
|
||||
date = date + Months::new(abs_month - 1);
|
||||
date = date + Months::new(abs_month);
|
||||
}
|
||||
if !is_date_within_range(date) {
|
||||
return Err("Out of range parameters for date".to_string());
|
||||
@@ -71,11 +72,12 @@ pub fn permissive_date_to_serial_number(day: i32, month: i32, year: i32) -> Resu
|
||||
};
|
||||
|
||||
date = {
|
||||
let abs_day = day.unsigned_abs() as u64;
|
||||
if day <= 0 {
|
||||
date = date - Days::new(abs_day + 1);
|
||||
let day_diff = day - 1;
|
||||
let abs_day = day_diff.unsigned_abs() as u64;
|
||||
if day_diff <= 0 {
|
||||
date = date - Days::new(abs_day);
|
||||
} else {
|
||||
date = date + Days::new(abs_day - 1);
|
||||
date = date + Days::new(abs_day);
|
||||
}
|
||||
if !is_date_within_range(date) {
|
||||
return Err("Out of range parameters for date".to_string());
|
||||
@@ -108,6 +110,10 @@ mod tests {
|
||||
permissive_date_to_serial_number(1, 49, 2000),
|
||||
date_to_serial_number(1, 1, 2004)
|
||||
);
|
||||
assert_eq!(
|
||||
permissive_date_to_serial_number(1, 49, 2000),
|
||||
date_to_serial_number(1, 1, 2004)
|
||||
);
|
||||
assert_eq!(
|
||||
permissive_date_to_serial_number(31, 49, 2000),
|
||||
date_to_serial_number(31, 1, 2004)
|
||||
@@ -129,7 +135,7 @@ mod tests {
|
||||
Ok(EXCEL_DATE_MAX),
|
||||
);
|
||||
assert_eq!(
|
||||
permissive_date_to_serial_number(1, 1, 0),
|
||||
permissive_date_to_serial_number(1, 1, 1900),
|
||||
Ok(EXCEL_DATE_MIN),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ fn test_date_early_dates() {
|
||||
);
|
||||
|
||||
// This does not agree with Excel, instead of mistakenly allowing
|
||||
// for Feb 29, it will auto-wrap to the next day after Feb 28.
|
||||
// for Feb 29, it will auto-wrap to the next day after Feb 28.
|
||||
assert_eq!(model._get_text("B2"), *"01/03/1900");
|
||||
|
||||
// This agrees with Excel from he onward
|
||||
|
||||
Reference in New Issue
Block a user