diff --git a/Cargo.lock b/Cargo.lock index c676027b..b1a4a474 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -858,6 +858,27 @@ dependencies = [ "windows-link", ] +[[package]] +name = "chrono-tz" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c6ac4f2c0bf0f44e9161aec9675e1050aa4a530663c4a9e37e108fa948bca9f" +dependencies = [ + "chrono", + "chrono-tz-build", + "phf", +] + +[[package]] +name = "chrono-tz-build" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94fea34d77a245229e7746bd2beb786cd2a896f306ff491fb8cecb3074b10a7" +dependencies = [ + "parse-zoneinfo", + "phf_codegen", +] + [[package]] name = "clap" version = "4.5.31" @@ -2695,6 +2716,7 @@ name = "komorebi-bar" version = "0.1.35" dependencies = [ "chrono", + "chrono-tz", "clap", "color-eyre", "crossbeam-channel", @@ -3863,6 +3885,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "parse-zoneinfo" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24" +dependencies = [ + "regex", +] + [[package]] name = "paste" version = "1.0.15" @@ -3885,6 +3916,44 @@ dependencies = [ "indexmap", ] +[[package]] +name = "phf" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project" version = "1.1.10" @@ -4730,6 +4799,12 @@ dependencies = [ "quote", ] +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + [[package]] name = "slab" version = "0.4.9" diff --git a/Cargo.toml b/Cargo.toml index 56c8f67c..88556d27 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ members = [ [workspace.dependencies] clap = { version = "4", features = ["derive", "wrap_help"] } +chrono-tz = "0.10" chrono = "0.4" crossbeam-channel = "0.5" crossbeam-utils = "0.8" diff --git a/komorebi-bar/Cargo.toml b/komorebi-bar/Cargo.toml index 1bd1ad8c..bb9c9abd 100644 --- a/komorebi-bar/Cargo.toml +++ b/komorebi-bar/Cargo.toml @@ -9,6 +9,7 @@ edition = "2021" komorebi-client = { path = "../komorebi-client" } komorebi-themes = { path = "../komorebi-themes" } +chrono-tz = { workspace = true } chrono = { workspace = true } clap = { workspace = true } color-eyre = { workspace = true } diff --git a/komorebi-bar/src/date.rs b/komorebi-bar/src/date.rs index 4a748cca..e1259eb1 100644 --- a/komorebi-bar/src/date.rs +++ b/komorebi-bar/src/date.rs @@ -2,6 +2,7 @@ use crate::config::LabelPrefix; use crate::render::RenderConfig; use crate::selected_frame::SelectableFrame; use crate::widget::BarWidget; +use chrono_tz::Tz; use eframe::egui::text::LayoutJob; use eframe::egui::Align; use eframe::egui::Context; @@ -64,6 +65,19 @@ pub struct DateConfig { pub format: DateFormat, /// Display label prefix pub label_prefix: Option, + /// TimeZone (https://docs.rs/chrono-tz/latest/chrono_tz/enum.Tz.html) + /// + /// Use a custom format to display additional information, i.e.: + /// ```json + /// { + /// "Date": { + /// "enable": true, + /// "format": { "Custom": "%D %Z (Tokyo)" }, + /// "timezone": "Asia/Tokyo" + /// } + ///} + /// ``` + pub timezone: Option, } impl From for Date { @@ -72,6 +86,7 @@ impl From for Date { enable: value.enable, format: value.format, label_prefix: value.label_prefix.unwrap_or(LabelPrefix::Icon), + timezone: value.timezone, } } } @@ -121,13 +136,27 @@ pub struct Date { pub enable: bool, pub format: DateFormat, label_prefix: LabelPrefix, + timezone: Option, } impl Date { fn output(&mut self) -> String { - let formatted = chrono::Local::now() - .format(&self.format.fmt_string()) - .to_string(); + let formatted = match &self.timezone { + Some(timezone) => match timezone.parse::() { + Ok(tz) => chrono::Local::now() + .with_timezone(&tz) + .format(&self.format.fmt_string()) + .to_string() + .trim() + .to_string(), + Err(_) => format!("Invalid timezone: {}", timezone), + }, + None => chrono::Local::now() + .format(&self.format.fmt_string()) + .to_string() + .trim() + .to_string(), + }; // if custom modifiers are used, apply them match &self.format { diff --git a/komorebi-bar/src/time.rs b/komorebi-bar/src/time.rs index 36b8cb3f..37f4a89d 100644 --- a/komorebi-bar/src/time.rs +++ b/komorebi-bar/src/time.rs @@ -3,6 +3,7 @@ use crate::config::LabelPrefix; use crate::render::RenderConfig; use crate::selected_frame::SelectableFrame; use crate::widget::BarWidget; +use chrono_tz::Tz; use eframe::egui::text::LayoutJob; use eframe::egui::Align; use eframe::egui::Context; @@ -26,6 +27,19 @@ pub struct TimeConfig { pub format: TimeFormat, /// Display label prefix pub label_prefix: Option, + /// TimeZone (https://docs.rs/chrono-tz/latest/chrono_tz/enum.Tz.html) + /// + /// Use a custom format to display additional information, i.e.: + /// ```json + /// { + /// "Time": { + /// "enable": true, + /// "format": { "Custom": "%T %Z (Tokyo)" }, + /// "timezone": "Asia/Tokyo" + /// } + ///} + /// ``` + pub timezone: Option, } impl From for Time { @@ -34,6 +48,7 @@ impl From for Time { enable: value.enable, format: value.format, label_prefix: value.label_prefix.unwrap_or(LabelPrefix::Icon), + timezone: value.timezone, } } } @@ -88,15 +103,27 @@ pub struct Time { pub enable: bool, pub format: TimeFormat, label_prefix: LabelPrefix, + timezone: Option, } impl Time { fn output(&mut self) -> String { - chrono::Local::now() - .format(&self.format.fmt_string()) - .to_string() - .trim() - .to_string() + match &self.timezone { + Some(timezone) => match timezone.parse::() { + Ok(tz) => chrono::Local::now() + .with_timezone(&tz) + .format(&self.format.fmt_string()) + .to_string() + .trim() + .to_string(), + Err(_) => format!("Invalid timezone: {}", timezone), + }, + None => chrono::Local::now() + .format(&self.format.fmt_string()) + .to_string() + .trim() + .to_string(), + } } fn paint_binary_circle( diff --git a/schema.bar.json b/schema.bar.json index 80173129..28a747c5 100644 --- a/schema.bar.json +++ b/schema.bar.json @@ -265,6 +265,10 @@ ] } ] + }, + "timezone": { + "description": "TimeZone (https://docs.rs/chrono-tz/latest/chrono_tz/enum.Tz.html)\n\nUse a custom format to display additional information, i.e.: ```json { \"Date\": { \"enable\": true, \"format\": { \"Custom\": \"%D %Z (Tokyo)\" }, \"timezone\": \"Asia/Tokyo\" } } ```", + "type": "string" } } } @@ -988,6 +992,10 @@ ] } ] + }, + "timezone": { + "description": "TimeZone (https://docs.rs/chrono-tz/latest/chrono_tz/enum.Tz.html)\n\nUse a custom format to display additional information, i.e.: ```json { \"Time\": { \"enable\": true, \"format\": { \"Custom\": \"%T %Z (Tokyo)\" }, \"timezone\": \"Asia/Tokyo\" } } ```", + "type": "string" } } } @@ -1663,6 +1671,10 @@ ] } ] + }, + "timezone": { + "description": "TimeZone (https://docs.rs/chrono-tz/latest/chrono_tz/enum.Tz.html)\n\nUse a custom format to display additional information, i.e.: ```json { \"Date\": { \"enable\": true, \"format\": { \"Custom\": \"%D %Z (Tokyo)\" }, \"timezone\": \"Asia/Tokyo\" } } ```", + "type": "string" } } } @@ -2386,6 +2398,10 @@ ] } ] + }, + "timezone": { + "description": "TimeZone (https://docs.rs/chrono-tz/latest/chrono_tz/enum.Tz.html)\n\nUse a custom format to display additional information, i.e.: ```json { \"Time\": { \"enable\": true, \"format\": { \"Custom\": \"%T %Z (Tokyo)\" }, \"timezone\": \"Asia/Tokyo\" } } ```", + "type": "string" } } } @@ -2994,6 +3010,10 @@ ] } ] + }, + "timezone": { + "description": "TimeZone (https://docs.rs/chrono-tz/latest/chrono_tz/enum.Tz.html)\n\nUse a custom format to display additional information, i.e.: ```json { \"Date\": { \"enable\": true, \"format\": { \"Custom\": \"%D %Z (Tokyo)\" }, \"timezone\": \"Asia/Tokyo\" } } ```", + "type": "string" } } } @@ -3717,6 +3737,10 @@ ] } ] + }, + "timezone": { + "description": "TimeZone (https://docs.rs/chrono-tz/latest/chrono_tz/enum.Tz.html)\n\nUse a custom format to display additional information, i.e.: ```json { \"Time\": { \"enable\": true, \"format\": { \"Custom\": \"%T %Z (Tokyo)\" }, \"timezone\": \"Asia/Tokyo\" } } ```", + "type": "string" } } }