From 3632a2ced45f37808df00b8129c0e07b18b7f5a8 Mon Sep 17 00:00:00 2001 From: Gavin Mendel-Gleason Date: Thu, 23 Nov 2023 17:48:06 +0100 Subject: [PATCH 1/2] Fix for bug in before epoch dates --- src/structure/tfc/datetime.rs | 61 +++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/src/structure/tfc/datetime.rs b/src/structure/tfc/datetime.rs index 91ee1a47..56615adb 100644 --- a/src/structure/tfc/datetime.rs +++ b/src/structure/tfc/datetime.rs @@ -11,10 +11,8 @@ pub fn datetime_to_parts(datetime: &NaiveDateTime) -> (bool, Integer, u32) { let mut seconds = Integer::from(datetime.timestamp()); let is_neg = seconds < 0; let mut nanos = datetime.timestamp_subsec_nanos(); - if is_neg { - if nanos != 0 { - seconds += 1; - } + if is_neg && nanos != 0 { + seconds += 1; nanos = 1_000_000_000 - nanos; } (is_neg, seconds, nanos) @@ -31,7 +29,6 @@ pub fn datetime_to_storage(datetime: &NaiveDateTime) -> Vec { } else { Some(format!("{nanos:09}")) }; - integer_and_fraction_to_storage(is_neg, seconds, fraction.as_ref().map(|b| b.as_ref())) } @@ -42,11 +39,7 @@ pub fn storage_to_datetime(bytes: &mut B) -> NaiveDateTime { .to_i64() .expect("This is a surprisingly large number of seconds!"); if fraction.is_empty() { - if is_pos { - NaiveDateTime::from_timestamp_opt(seconds, 0).unwrap() - } else { - NaiveDateTime::from_timestamp_opt(-seconds, 0).unwrap() - } + NaiveDateTime::from_timestamp_opt(seconds, 0).unwrap() } else { let zeros = "0".repeat(9 - fraction.len()); let fraction = format!("{fraction}{zeros}"); @@ -113,4 +106,52 @@ mod tests { let dt_storage = storage_to_datetime(&mut storage.as_slice()); assert_eq!(dt, dt_storage) } + + /* + #[test] + fn integer_and_fraction() { + let vec = integer_and_fraction_to_storage(true, Integer::from(-322704000), None); + let (int, is_pos) = storage_to_bigint_and_sign(vec.to_bytes()); + let fract = decode_fraction(vec); + }*/ + + #[test] + fn no_time_ns() { + let year: i32 = 1959; + let month: u32 = 10; + let day: u32 = 11; + let hour: u32 = 0; + let minute: u32 = 0; + let second: u32 = 0; + let nano: u32 = 0; + let dt = NaiveDate::from_ymd_opt(year, month, day) + .unwrap() + .and_hms_nano_opt(hour, minute, second, nano) + .unwrap(); + let result = datetime_to_parts(&dt); + assert_eq!((true, Integer::from(-322704000), 0_u32), result); + let storage = datetime_to_storage(&dt); + let dt_storage = storage_to_datetime(&mut storage.as_slice()); + assert_eq!(dt, dt_storage) + } + + #[test] + fn a_bit_of_ns() { + let year: i32 = 1959; + let month: u32 = 10; + let day: u32 = 11; + let hour: u32 = 0; + let minute: u32 = 0; + let second: u32 = 0; + let nano: u32 = 3; + let dt = NaiveDate::from_ymd_opt(year, month, day) + .unwrap() + .and_hms_nano_opt(hour, minute, second, nano) + .unwrap(); + let result = datetime_to_parts(&dt); + assert_eq!((true, Integer::from(-322703999), 999999997_u32), result); + let storage = datetime_to_storage(&dt); + let dt_storage = storage_to_datetime(&mut storage.as_slice()); + assert_eq!(dt, dt_storage) + } } From 80f3955c3053cb7ed314714fd2de7f511ee0da18 Mon Sep 17 00:00:00 2001 From: Gavin Mendel-Gleason Date: Thu, 23 Nov 2023 20:17:41 +0100 Subject: [PATCH 2/2] Remove commented test --- src/structure/tfc/datetime.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/structure/tfc/datetime.rs b/src/structure/tfc/datetime.rs index 56615adb..00994fe6 100644 --- a/src/structure/tfc/datetime.rs +++ b/src/structure/tfc/datetime.rs @@ -107,14 +107,6 @@ mod tests { assert_eq!(dt, dt_storage) } - /* - #[test] - fn integer_and_fraction() { - let vec = integer_and_fraction_to_storage(true, Integer::from(-322704000), None); - let (int, is_pos) = storage_to_bigint_and_sign(vec.to_bytes()); - let fract = decode_fraction(vec); - }*/ - #[test] fn no_time_ns() { let year: i32 = 1959;