Skip to content

Commit

Permalink
Fix for bug in before epoch dates (#146)
Browse files Browse the repository at this point in the history
* Fix for bug in before epoch dates

* Remove commented test
  • Loading branch information
GavinMendelGleason authored Nov 24, 2023
1 parent d0b7fad commit e78fe02
Showing 1 changed file with 43 additions and 10 deletions.
53 changes: 43 additions & 10 deletions src/structure/tfc/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -31,7 +29,6 @@ pub fn datetime_to_storage(datetime: &NaiveDateTime) -> Vec<u8> {
} else {
Some(format!("{nanos:09}"))
};

integer_and_fraction_to_storage(is_neg, seconds, fraction.as_ref().map(|b| b.as_ref()))
}

Expand All @@ -42,11 +39,7 @@ pub fn storage_to_datetime<B: Buf>(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}");
Expand Down Expand Up @@ -113,4 +106,44 @@ mod tests {
let dt_storage = storage_to_datetime(&mut storage.as_slice());
assert_eq!(dt, dt_storage)
}

#[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)
}
}

0 comments on commit e78fe02

Please sign in to comment.