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),
|
||||
);
|
||||
}
|
||||
|
||||
BIN
xlsx/tests/calc_tests/DATE.xlsx
Normal file
BIN
xlsx/tests/calc_tests/DATE.xlsx
Normal file
Binary file not shown.
Reference in New Issue
Block a user