Use macOS API to retrieve the local timezone

The `time` crate currently doesn't have a reliable way to get that.
In the future, `NSSystemTimeZoneDidChangeNotification` could be
used to keep the cached timezone up-to-date.

Co-Authored-By: Max Brunsfeld <max@zed.dev>
This commit is contained in:
Antonio Scandurra 2021-09-02 19:15:05 +02:00
parent 3d4ff43f9e
commit f59e02cf25
7 changed files with 30 additions and 6 deletions

1
Cargo.lock generated
View file

@ -2187,6 +2187,7 @@ dependencies = [
"simplelog", "simplelog",
"smallvec", "smallvec",
"smol", "smol",
"time 0.3.2",
"tiny-skia", "tiny-skia",
"tree-sitter", "tree-sitter",
"usvg", "usvg",

View file

@ -27,6 +27,7 @@ serde = { version = "1.0.125", features = ["derive"] }
serde_json = "1.0.64" serde_json = "1.0.64"
smallvec = { version = "1.6", features = ["union"] } smallvec = { version = "1.6", features = ["union"] }
smol = "1.2" smol = "1.2"
time = { version = "0.3" }
tiny-skia = "0.5" tiny-skia = "0.5"
tree-sitter = "0.19" tree-sitter = "0.19"
usvg = "0.14" usvg = "0.14"

View file

@ -26,6 +26,7 @@ use std::{
rc::Rc, rc::Rc,
sync::Arc, sync::Arc,
}; };
use time::UtcOffset;
pub trait Platform: Send + Sync { pub trait Platform: Send + Sync {
fn dispatcher(&self) -> Arc<dyn Dispatcher>; fn dispatcher(&self) -> Arc<dyn Dispatcher>;
@ -49,6 +50,8 @@ pub trait Platform: Send + Sync {
fn read_credentials(&self, url: &str) -> Option<(String, Vec<u8>)>; fn read_credentials(&self, url: &str) -> Option<(String, Vec<u8>)>;
fn set_cursor_style(&self, style: CursorStyle); fn set_cursor_style(&self, style: CursorStyle);
fn local_timezone(&self) -> UtcOffset;
} }
pub(crate) trait ForegroundPlatform { pub(crate) trait ForegroundPlatform {

View file

@ -42,6 +42,7 @@ use std::{
slice, str, slice, str,
sync::Arc, sync::Arc,
}; };
use time::UtcOffset;
const MAC_PLATFORM_IVAR: &'static str = "platform"; const MAC_PLATFORM_IVAR: &'static str = "platform";
static mut APP_CLASS: *const Class = ptr::null(); static mut APP_CLASS: *const Class = ptr::null();
@ -558,6 +559,14 @@ impl platform::Platform for MacPlatform {
let _: () = msg_send![cursor, set]; let _: () = msg_send![cursor, set];
} }
} }
fn local_timezone(&self) -> UtcOffset {
unsafe {
let local_timezone: id = msg_send![class!(NSTimeZone), localTimeZone];
let seconds_from_gmt: NSInteger = msg_send![local_timezone, secondsFromGMT];
UtcOffset::from_whole_seconds(seconds_from_gmt.try_into().unwrap()).unwrap()
}
}
} }
unsafe fn get_foreground_platform(object: &mut Object) -> &MacForegroundPlatform { unsafe fn get_foreground_platform(object: &mut Object) -> &MacForegroundPlatform {

View file

@ -9,6 +9,7 @@ use std::{
rc::Rc, rc::Rc,
sync::Arc, sync::Arc,
}; };
use time::UtcOffset;
pub struct Platform { pub struct Platform {
dispatcher: Arc<dyn super::Dispatcher>, dispatcher: Arc<dyn super::Dispatcher>,
@ -136,6 +137,10 @@ impl super::Platform for Platform {
fn set_cursor_style(&self, style: CursorStyle) { fn set_cursor_style(&self, style: CursorStyle) {
*self.cursor.lock() = style; *self.cursor.lock() = style;
} }
fn local_timezone(&self) -> UtcOffset {
UtcOffset::UTC
}
} }
impl Window { impl Window {

View file

@ -49,7 +49,7 @@ smallvec = { version = "1.6", features = ["union"] }
smol = "1.2.5" smol = "1.2.5"
surf = "2.2" surf = "2.2"
tempdir = { version = "0.3.7", optional = true } tempdir = { version = "0.3.7", optional = true }
time = { version = "0.3", features = ["local-offset"] } time = { version = "0.3" }
tiny_http = "0.8" tiny_http = "0.8"
toml = "0.5" toml = "0.5"
tree-sitter = "0.19.5" tree-sitter = "0.19.5"

View file

@ -25,6 +25,7 @@ pub struct ChatPanel {
input_editor: ViewHandle<Editor>, input_editor: ViewHandle<Editor>,
channel_select: ViewHandle<Select>, channel_select: ViewHandle<Select>,
settings: watch::Receiver<Settings>, settings: watch::Receiver<Settings>,
local_timezone: UtcOffset,
} }
pub enum Event {} pub enum Event {}
@ -94,6 +95,7 @@ impl ChatPanel {
input_editor, input_editor,
channel_select, channel_select,
settings, settings,
local_timezone: cx.platform().local_timezone(),
}; };
this.init_active_channel(cx); this.init_active_channel(cx);
@ -204,7 +206,7 @@ impl ChatPanel {
.with_child( .with_child(
Container::new( Container::new(
Label::new( Label::new(
format_timestamp(message.timestamp, now), format_timestamp(message.timestamp, now, self.local_timezone),
theme.timestamp.text.clone(), theme.timestamp.text.clone(),
) )
.boxed(), .boxed(),
@ -314,10 +316,13 @@ impl View for ChatPanel {
} }
} }
fn format_timestamp(mut timestamp: OffsetDateTime, mut now: OffsetDateTime) -> String { fn format_timestamp(
let local_offset = UtcOffset::current_local_offset().unwrap_or(UtcOffset::UTC); mut timestamp: OffsetDateTime,
timestamp = timestamp.to_offset(local_offset); mut now: OffsetDateTime,
now = now.to_offset(local_offset); local_timezone: UtcOffset,
) -> String {
timestamp = timestamp.to_offset(local_timezone);
now = now.to_offset(local_timezone);
let today = now.date(); let today = now.date();
let date = timestamp.date(); let date = timestamp.date();