diff --git a/src/info/utils/mod.rs b/src/info/utils/mod.rs index 0595580df..13975beb3 100644 --- a/src/info/utils/mod.rs +++ b/src/info/utils/mod.rs @@ -24,20 +24,26 @@ where } fn to_human_time(time: Time) -> String { - let since_epoch_duration = SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH) - .unwrap(); + let duration = match diff_gix_time(SystemTime::now(), time) { + Ok(d) => d, + Err(s) => return s, + }; + let ht = HumanTime::from(-(duration.as_secs() as i64)); + ht.to_string() +} - let ts = Duration::from_secs(match time.seconds.try_into() { +/// Gets the duration between `now` and `time`. Returns `Err` if this cannot be calculated. +fn diff_gix_time(now: SystemTime, time: Time) -> Result { + let since_epoch_duration = now.duration_since(SystemTime::UNIX_EPOCH).unwrap(); + let ts = Duration::from_secs(match (time.seconds + i64::from(time.offset)).try_into() { Ok(s) => s, - Err(_) => return "".into(), + Err(_) => return Err("".into()), }); let duration = since_epoch_duration.checked_sub(ts).expect( "Achievement unlocked: time travel! \ Check your system clock and commit dates.", ); - let ht = HumanTime::from(-(duration.as_secs() as i64)); - ht.to_string() + Ok(duration) } pub fn format_number( @@ -120,6 +126,20 @@ mod tests { format_time(time, false); } + #[test] + fn test_timezone_awareness() { + let now = SystemTime::now(); + let current_time = now.duration_since(SystemTime::UNIX_EPOCH).unwrap(); + let hour_offset: i32 = 1; + let offset = 60 * 60 * hour_offset; + let also_now = Time::new( + (current_time.as_secs() as gix::date::SecondsSinceUnixEpoch) + i64::from(offset), + -offset, + ); + let diff = diff_gix_time(now, also_now).unwrap(); + assert_eq!(diff.as_secs(), 0); + } + #[test] fn display_time_before_epoch() { let time = Time::new(gix::date::SecondsSinceUnixEpoch::MIN, 0);