From 5360dc150467473356a71de79c753575ddcb2b86 Mon Sep 17 00:00:00 2001 From: Viraj Bhartiya Date: Thu, 6 Nov 2025 09:53:22 +0530 Subject: [PATCH] Refactor timestamp formatting in Git UI components to use `chrono` for local time calculations (#41005) - Updated `blame_ui.rs`, `branch_picker.rs`, `commit_tooltip.rs`, and `commit_view.rs` to replace the previous timestamp formatting with `chrono` for better accuracy in local time representation. - Introduced `chrono::Local::now().offset().local_minus_utc()` to obtain the local offset for timestamp formatting. Closes #40878 Release Notes: - Improved timestamp handling in various Git UI components for enhanced user experience. --- Cargo.lock | 1 - Cargo.toml | 1 + crates/git_ui/Cargo.toml | 1 - crates/git_ui/src/blame_ui.rs | 10 ++++++---- crates/git_ui/src/branch_picker.rs | 6 ++++-- crates/git_ui/src/commit_tooltip.rs | 9 +++++---- crates/git_ui/src/commit_view.rs | 4 +++- crates/git_ui/src/stash_picker.rs | 5 +---- 8 files changed, 20 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 03a710c6dd02aa12c3cbf2a2a7e158962c4d49c8..e12fb7ecc7e07699ef2a5de10f2ed039cf5ce6e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7091,7 +7091,6 @@ dependencies = [ "askpass", "buffer_diff", "call", - "chrono", "cloud_llm_client", "collections", "command_palette_hooks", diff --git a/Cargo.toml b/Cargo.toml index ac6e310fe7d899486c5b5287f4ac07762751d9a1..2ba91915a51a5fa4ca38f7d3194af0e6070c2068 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -663,6 +663,7 @@ time = { version = "0.3", features = [ "serde", "serde-well-known", "formatting", + "local-offset", ] } tiny_http = "0.8" tokio = { version = "1" } diff --git a/crates/git_ui/Cargo.toml b/crates/git_ui/Cargo.toml index 29b52e7b79e1b659d43f70d431ae5e2b1d631a1b..326424f28d46c9802439293165eae9708d63b064 100644 --- a/crates/git_ui/Cargo.toml +++ b/crates/git_ui/Cargo.toml @@ -22,7 +22,6 @@ anyhow.workspace = true askpass.workspace = true buffer_diff.workspace = true call.workspace = true -chrono.workspace = true cloud_llm_client.workspace = true collections.workspace = true command_palette_hooks.workspace = true diff --git a/crates/git_ui/src/blame_ui.rs b/crates/git_ui/src/blame_ui.rs index 6059bc9e83b63e710815891165fe6e530a0efa1a..fc26f4608a38027e6abd4db122e713cc9ff4dc56 100644 --- a/crates/git_ui/src/blame_ui.rs +++ b/crates/git_ui/src/blame_ui.rs @@ -16,7 +16,6 @@ use project::{git_store::Repository, project_settings::ProjectSettings}; use settings::Settings as _; use theme::ThemeSettings; use time::OffsetDateTime; -use time_format::format_local_timestamp; use ui::{ContextMenu, Divider, prelude::*, tooltip_container}; use workspace::Workspace; @@ -188,9 +187,11 @@ impl BlameRenderer for GitBlameRenderer { .get(..8) .map(|sha| sha.to_string().into()) .unwrap_or_else(|| sha.clone()); - let absolute_timestamp = format_local_timestamp( + let local_offset = time::UtcOffset::current_local_offset().unwrap_or(time::UtcOffset::UTC); + let absolute_timestamp = time_format::format_localized_timestamp( commit_time, OffsetDateTime::now_utc(), + local_offset, time_format::TimestampFormat::MediumAbsolute, ); let link_color = cx.theme().colors().text_accent; @@ -403,11 +404,12 @@ fn deploy_blame_entry_context_menu( fn blame_entry_relative_timestamp(blame_entry: &BlameEntry) -> String { match blame_entry.author_offset_date_time() { Ok(timestamp) => { - let local = chrono::Local::now().offset().local_minus_utc(); + let local_offset = + time::UtcOffset::current_local_offset().unwrap_or(time::UtcOffset::UTC); time_format::format_localized_timestamp( timestamp, time::OffsetDateTime::now_utc(), - time::UtcOffset::from_whole_seconds(local).unwrap(), + local_offset, time_format::TimestampFormat::Relative, ) } diff --git a/crates/git_ui/src/branch_picker.rs b/crates/git_ui/src/branch_picker.rs index 662e1cc1d712757eb2f31b11a0d6340576c29317..e10568ff37aaa47924632558228294feca84ac61 100644 --- a/crates/git_ui/src/branch_picker.rs +++ b/crates/git_ui/src/branch_picker.rs @@ -14,7 +14,6 @@ use project::project_settings::ProjectSettings; use settings::Settings; use std::sync::Arc; use time::OffsetDateTime; -use time_format::format_local_timestamp; use ui::{HighlightedLabel, ListItem, ListItemSpacing, Tooltip, prelude::*}; use util::ResultExt; use workspace::notifications::DetachAndPromptErr; @@ -447,9 +446,12 @@ impl PickerDelegate for BranchListDelegate { let subject = commit.subject.clone(); let commit_time = OffsetDateTime::from_unix_timestamp(commit.commit_timestamp) .unwrap_or_else(|_| OffsetDateTime::now_utc()); - let formatted_time = format_local_timestamp( + let local_offset = + time::UtcOffset::current_local_offset().unwrap_or(time::UtcOffset::UTC); + let formatted_time = time_format::format_localized_timestamp( commit_time, OffsetDateTime::now_utc(), + local_offset, time_format::TimestampFormat::Relative, ); let author = commit.author_name.clone(); diff --git a/crates/git_ui/src/commit_tooltip.rs b/crates/git_ui/src/commit_tooltip.rs index 97224840debcc4cfd8dcc74a56d448ef0d2826c1..7646d1d64f58c24d112eb929646efec983b8e69b 100644 --- a/crates/git_ui/src/commit_tooltip.rs +++ b/crates/git_ui/src/commit_tooltip.rs @@ -14,7 +14,6 @@ use settings::Settings; use std::hash::Hash; use theme::ThemeSettings; use time::{OffsetDateTime, UtcOffset}; -use time_format::format_local_timestamp; use ui::{Avatar, Divider, IconButtonShape, prelude::*, tooltip_container}; use workspace::Workspace; @@ -190,9 +189,11 @@ impl Render for CommitTooltip { .map(|sha| sha.to_string().into()) .unwrap_or_else(|| self.commit.sha.clone()); let full_sha = self.commit.sha.to_string(); - let absolute_timestamp = format_local_timestamp( + let local_offset = UtcOffset::current_local_offset().unwrap_or(UtcOffset::UTC); + let absolute_timestamp = time_format::format_localized_timestamp( self.commit.commit_time, OffsetDateTime::now_utc(), + local_offset, time_format::TimestampFormat::MediumAbsolute, ); let markdown_style = { @@ -351,11 +352,11 @@ impl Render for CommitTooltip { fn blame_entry_timestamp(blame_entry: &BlameEntry, format: time_format::TimestampFormat) -> String { match blame_entry.author_offset_date_time() { Ok(timestamp) => { - let local = chrono::Local::now().offset().local_minus_utc(); + let local_offset = UtcOffset::current_local_offset().unwrap_or(UtcOffset::UTC); time_format::format_localized_timestamp( timestamp, time::OffsetDateTime::now_utc(), - UtcOffset::from_whole_seconds(local).unwrap(), + local_offset, format, ) } diff --git a/crates/git_ui/src/commit_view.rs b/crates/git_ui/src/commit_view.rs index 0a0c4c18e1f528a9ebaad9a8d9862982632dd04f..4608397c0a6f2462bcc4bc50e06de99d1749af30 100644 --- a/crates/git_ui/src/commit_view.rs +++ b/crates/git_ui/src/commit_view.rs @@ -415,12 +415,14 @@ fn format_commit(commit: &CommitDetails, is_stash: bool) -> String { commit.author_name, commit.author_email ) .unwrap(); + let local_offset = time::UtcOffset::current_local_offset().unwrap_or(time::UtcOffset::UTC); writeln!( &mut result, "Date: {}", - time_format::format_local_timestamp( + time_format::format_localized_timestamp( time::OffsetDateTime::from_unix_timestamp(commit.commit_timestamp).unwrap(), time::OffsetDateTime::now_utc(), + local_offset, time_format::TimestampFormat::MediumAbsolute, ), ) diff --git a/crates/git_ui/src/stash_picker.rs b/crates/git_ui/src/stash_picker.rs index aa958ab62da6793c7e6fc7fd7b9f51d4ab3c33aa..d25117e3806ff0bdf73985eb60ee1d8f5b373752 100644 --- a/crates/git_ui/src/stash_picker.rs +++ b/crates/git_ui/src/stash_picker.rs @@ -1,6 +1,5 @@ use fuzzy::StringMatchCandidate; -use chrono; use git::stash::StashEntry; use gpui::{ Action, AnyElement, App, Context, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, @@ -207,9 +206,7 @@ impl StashListDelegate { _window: &mut Window, cx: &mut Context, ) -> Self { - let timezone = - UtcOffset::from_whole_seconds(chrono::Local::now().offset().local_minus_utc()) - .unwrap_or(UtcOffset::UTC); + let timezone = UtcOffset::current_local_offset().unwrap_or(UtcOffset::UTC); Self { matches: vec![],