From ec1b80534a51d0ae147cce15fd4503d64c224256 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vuka=C5=A1in=20Vojinovi=C4=87?= <150025636+git-f0x@users.noreply.github.com> Date: Mon, 27 Apr 2026 13:07:36 +0200 Subject: [PATCH] refactor: replace `chrono` with `jiff` --- Cargo.lock | 52 ++++++++++---------------------------- Cargo.toml | 4 +-- src/common.rs | 2 +- src/time.rs | 69 +++++++++++++++++---------------------------------- 4 files changed, 39 insertions(+), 88 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3c25f5b..94555d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -875,24 +875,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" dependencies = [ "iana-time-zone", - "js-sys", "num-traits", - "pure-rust-locales", "serde", - "wasm-bindgen", "windows-link 0.2.1", ] -[[package]] -name = "chrono-tz" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3" -dependencies = [ - "chrono", - "phf 0.12.1", -] - [[package]] name = "clang-sys" version = "1.8.1" @@ -1244,8 +1231,6 @@ version = "0.1.0" dependencies = [ "anyhow", "async-fn-stream", - "chrono", - "chrono-tz", "clap_lex", "color-eyre", "cosmic-applets-config", @@ -1268,6 +1253,8 @@ dependencies = [ "i18n-embed-fl", "icu", "image", + "jiff", + "jiff-icu", "kdl", "libcosmic", "logind-zbus", @@ -3599,6 +3586,17 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "jiff-icu" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e67c2beaae8b10a82d849b9aabb698a43a682f32b17bcdc035d5ecadb44d646" +dependencies = [ + "icu_calendar", + "icu_time", + "jiff", +] + [[package]] name = "jiff-static" version = "0.2.23" @@ -4886,15 +4884,6 @@ dependencies = [ "phf_shared 0.11.3", ] -[[package]] -name = "phf" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7" -dependencies = [ - "phf_shared 0.12.1", -] - [[package]] name = "phf" version = "0.13.1" @@ -4962,15 +4951,6 @@ dependencies = [ "siphasher", ] -[[package]] -name = "phf_shared" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981" -dependencies = [ - "siphasher", -] - [[package]] name = "phf_shared" version = "0.13.1" @@ -5238,12 +5218,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "pure-rust-locales" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "869675ad2d7541aea90c6d88c81f46a7f4ea9af8cd0395d38f11a95126998a0d" - [[package]] name = "pwd" version = "1.4.0" diff --git a/Cargo.toml b/Cargo.toml index 49ba628..fd9b835 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,8 +10,8 @@ vergen = { version = "8", features = ["git", "gitcl"] } anyhow = "1" async-fn-stream = "0.3" icu = { version = "2.0.0", features = ["compiled_data"] } -chrono-tz = "0.10" -chrono = { version = "0.4", features = ["unstable-locales"] } +jiff = "0.2" +jiff-icu = "0.2" cosmic-applets-config.workspace = true cosmic-bg-config.workspace = true cosmic-comp-config.workspace = true diff --git a/src/common.rs b/src/common.rs index da3d21a..059f3fc 100644 --- a/src/common.rs +++ b/src/common.rs @@ -64,7 +64,7 @@ pub enum Message { Prompt(String, bool, Option), SessionLockEvent(SessionLockEvent), Tick, - Tz(chrono_tz::Tz), + Tz(jiff::tz::TimeZone), } impl + Send + 'static> Common { diff --git a/src/time.rs b/src/time.rs index b6c109d..49caf69 100644 --- a/src/time.rs +++ b/src/time.rs @@ -1,6 +1,5 @@ use anyhow::bail; use async_fn_stream::StreamEmitter; -use chrono::{Datelike, Timelike}; use cosmic::{ Element, Task, style, widget::{column, text}, @@ -8,12 +7,13 @@ use cosmic::{ use futures_util::StreamExt; use icu::{ datetime::{ - DateTimeFormatter, DateTimeFormatterPreferences, fieldsets, - input::{Date, DateTime, Time as IcuTime}, + DateTimeFormatter, DateTimeFormatterPreferences, fieldsets, input::DateTime, options::TimePrecision, }, locale::{Locale, preferences::extensions::unicode::keywords::HourCycle}, }; +use jiff::tz::TimeZone; +use jiff_icu::ConvertFrom; use std::time::Duration; use timedate_zbus::TimeDateProxy; use tokio::time; @@ -21,8 +21,8 @@ use tokio::time; #[derive(Debug, Clone)] pub struct Time { locale: Locale, - timezone: Option, - now: chrono::DateTime, + timezone: Option, + now: jiff::Zoned, } impl Time { @@ -53,7 +53,7 @@ impl Time { } let locale = get_local(); - let now = chrono::Local::now().fixed_offset(); + let now = jiff::Zoned::now(); Self { locale, @@ -62,7 +62,7 @@ impl Time { } } - pub fn set_tz(&mut self, tz: chrono_tz::Tz) { + pub fn set_tz(&mut self, tz: TimeZone) { self.timezone = Some(tz); self.tick(); } @@ -70,30 +70,19 @@ impl Time { pub fn tick(&mut self) { self.now = self .timezone - .map(|tz| chrono::Local::now().with_timezone(&tz).fixed_offset()) - .unwrap_or_else(|| chrono::Local::now().into()); + .as_ref() + .map(|tz| jiff::Timestamp::now().to_zoned(tz.clone())) + .unwrap_or_else(|| jiff::Zoned::now()); } - pub fn format_date(&self, date: &D) -> String { + pub fn format_date(&self) -> String { let prefs = DateTimeFormatterPreferences::from(&self.locale); let dtf = DateTimeFormatter::try_new(prefs, fieldsets::MDE::long()).unwrap(); - - let datetime = DateTime { - date: Date::try_new_gregorian(date.year(), date.month() as u8, date.day() as u8) - .unwrap(), - time: IcuTime::try_new( - self.now.hour() as u8, - self.now.minute() as u8, - self.now.second() as u8, - 0, - ) - .unwrap(), - }; - - dtf.format(&datetime).to_string() + dtf.format(&DateTime::convert_from(self.now.datetime())) + .to_string() } - pub fn format_time(&self, date: &D, military_time: bool) -> String { + pub fn format_time(&self, military_time: bool) -> String { let mut prefs = DateTimeFormatterPreferences::from(&self.locale); prefs.hour_cycle = Some(if military_time { HourCycle::H23 @@ -105,30 +94,18 @@ impl Time { fieldsets::T::medium().with_time_precision(TimePrecision::Minute), ) .unwrap(); - - let datetime = DateTime { - date: Date::try_new_gregorian(date.year(), date.month() as u8, date.day() as u8) - .unwrap(), - time: IcuTime::try_new( - self.now.hour() as u8, - self.now.minute() as u8, - self.now.second() as u8, - 0, - ) - .unwrap(), - }; - - dtf.format(&datetime).to_string() + dtf.format(&DateTime::convert_from(self.now.datetime())) + .to_string() } - pub fn date_time_widget<'a, M: 'a>(&self, military_time: bool) -> cosmic::Element<'a, M> { + pub fn date_time_widget<'a, M: 'a>(&self, military_time: bool) -> Element<'a, M> { Element::from( column::with_capacity(2) .padding(16.) .spacing(12.0) - .push(text::title2(self.format_date(&self.now)).class(style::Text::Accent)) + .push(text::title2(self.format_date()).class(style::Text::Accent)) .push( - text(self.format_time(&self.now, military_time)) + text(self.format_time(military_time)) .size(if military_time { 112. } else { 75. }) .class(style::Text::Accent), ), @@ -136,7 +113,7 @@ impl Time { } } -pub fn tz_updates() -> Task { +pub fn tz_updates() -> Task { Task::stream(async_fn_stream::fn_stream(|emitter| async move { loop { if let Err(err) = tz_stream(&emitter).await { @@ -159,7 +136,7 @@ pub fn tick() -> Task<()> { // Calculate a delta if we're ticking per minute to keep ticks stable // Based on i3status-rust - let current = chrono::Local::now().second() as u64 % 60; + let current = jiff::Zoned::now().second() as u64 % 60; if current != 0 { timer.reset_after(time::Duration::from_secs(60 - current)); } @@ -167,7 +144,7 @@ pub fn tick() -> Task<()> { })) } -pub async fn tz_stream(emitter: &StreamEmitter) -> anyhow::Result<()> { +pub async fn tz_stream(emitter: &StreamEmitter) -> anyhow::Result<()> { let Ok(conn) = zbus::Connection::system().await else { bail!("No zbus system connection."); }; @@ -184,7 +161,7 @@ pub async fn tz_stream(emitter: &StreamEmitter) -> anyhow::Result let Ok(tz) = property.get().await else { bail!("Failed to get property"); }; - let Ok(tz) = tz.parse::() else { + let Ok(tz) = TimeZone::get(&tz) else { bail!("Failed to parse timezone."); }; emitter.emit(tz).await;