Skip to content

Commit

Permalink
feat(time): time display use /etc/timezone
Browse files Browse the repository at this point in the history
When a file timestamp is updated under daylight saving time, and
displayed when it is not, the wrong time offset is displayed (and vice
versa).

Fixes issue eza-community#653.
  • Loading branch information
erwinvaneijk committed Dec 12, 2023
1 parent 8c50812 commit d18c007
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 15 deletions.
55 changes: 49 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ name = "eza"
[dependencies]
ansiterm = { version = "0.12.2", features = ["ansi_colours"] }
chrono = { version = "0.4.31", default-features = false, features = ["clock"] }
chrono-tz = "0.8.4"
iana-time-zone = "0.1.58"
glob = "0.3"
libc = "0.2"
locale = "0.2"
Expand Down
7 changes: 5 additions & 2 deletions src/output/render/times.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ use ansiterm::Style;
use chrono::prelude::*;

pub trait Render {
fn render(self, style: Style, time_offset: FixedOffset, time_format: TimeFormat) -> TextCell;
fn render(self, style: Style, time_format: TimeFormat) -> TextCell;
}

impl Render for Option<NaiveDateTime> {
fn render(self, style: Style, time_offset: FixedOffset, time_format: TimeFormat) -> TextCell {
fn render(self, style: Style, time_format: TimeFormat) -> TextCell {
let timezone_str = iana_time_zone::get_timezone().unwrap();
let timezone: chrono_tz::Tz = timezone_str.parse().unwrap();
let datestamp = if let Some(time) = self {
let time_offset = timezone.offset_from_utc_datetime(&time).fix();
time_format.format(&DateTime::<FixedOffset>::from_naive_utc_and_offset(
time,
time_offset,
Expand Down
7 changes: 0 additions & 7 deletions src/output/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,9 +330,6 @@ impl Default for TimeTypes {
///
/// Any environment field should be able to be mocked up for test runs.
pub struct Environment {
/// The computer’s current time offset, determined from time zone.
time_offset: FixedOffset,

/// Localisation rules for formatting numbers.
numeric: locale::Numeric,

Expand All @@ -348,16 +345,13 @@ impl Environment {
}

fn load_all() -> Self {
let time_offset = *Local::now().offset();

let numeric =
locale::Numeric::load_user_locale().unwrap_or_else(|_| locale::Numeric::english());

#[cfg(unix)]
let users = Mutex::new(UsersCache::new());

Self {
time_offset,
numeric,
#[cfg(unix)]
users,
Expand Down Expand Up @@ -528,7 +522,6 @@ impl<'a> Table<'a> {
} else {
self.theme.ui.date
},
self.env.time_offset,
self.time_format.clone(),
),
}
Expand Down
30 changes: 30 additions & 0 deletions src/output/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,34 @@ mod test {
.all(|string| UnicodeWidthStr::width(string.as_str()) == max_month_width)
);
}

#[test]
fn display_timestamp_correctly_in_timezone_with_dst() {
let timezone_str = "Europe/Berlin";
let timezone: chrono_tz::Tz = timezone_str.parse().unwrap();
let time = DateTime::<Utc>::from_timestamp(1685867700, 0)
.unwrap()
.naive_utc();

let fixed_offset = timezone.offset_from_utc_datetime(&time).fix();
let real_converted = DateTime::<FixedOffset>::from_naive_utc_and_offset(time, fixed_offset);
let formatted = full(&real_converted);
let expected = "2023-06-04 10:35:00.000000000 +0200";
assert_eq!(expected, formatted);
}

#[test]
fn display_timestamp_correctly_in_timezone_without_dst() {
let timezone_str = "Europe/Berlin";
let timezone: chrono_tz::Tz = timezone_str.parse().unwrap();
let time = DateTime::<Utc>::from_timestamp(1699090500, 0)
.unwrap()
.naive_utc();

let fixed_offset = timezone.offset_from_utc_datetime(&time).fix();
let real_converted = DateTime::<FixedOffset>::from_naive_utc_and_offset(time, fixed_offset);
let formatted = full(&real_converted);
let expected = "2023-11-04 10:35:00.000000000 +0100";
assert_eq!(expected, formatted);
}
}

0 comments on commit d18c007

Please sign in to comment.