fix: use localzone crate to get local tz

This commit is contained in:
ThetaDev 2025-01-25 21:12:46 +01:00
parent 34f8e9b551
commit 5acbf0e456
No known key found for this signature in database
GPG key ID: E319D3C5148D65B6
5 changed files with 5 additions and 67 deletions

View file

@ -56,10 +56,7 @@ data-encoding = "2.0.0"
urlencoding = "2.1.0"
quick-xml = { version = "0.37.0", features = ["serialize"] }
tracing = { version = "0.1.0", features = ["log"] }
windows-sys = { version = "0.59.0", features = [
"Win32_System_Time",
"Win32_Foundation",
] }
localzone = "0.3.1"
# CLI
indicatif = "0.17.0"
@ -118,11 +115,9 @@ phf.workspace = true
data-encoding.workspace = true
urlencoding.workspace = true
tracing.workspace = true
localzone.workspace = true
quick-xml = { workspace = true, optional = true }
[target.'cfg(windows)'.dependencies]
windows-sys.workspace = true
[dev-dependencies]
rstest.workspace = true
tokio-test.workspace = true

View file

@ -2626,7 +2626,7 @@ fn validate_country(country: Country) -> Country {
fn local_tz_offset() -> (String, i16) {
match (
util::local_timezone_name(),
localzone::get_local_zone().ok_or(Error::Other("could not get local timezone".into())),
UtcOffset::current_local_offset().map_err(|_| Error::Other("indeterminate offset".into())),
) {
(Ok(timezone), Ok(offset)) => (timezone, offset.whole_minutes()),

View file

@ -1,5 +1,6 @@
#![doc = include_str!("../README.md")]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![forbid(unsafe_code)]
#![warn(missing_docs, clippy::todo, clippy::dbg_macro)]
//! ## Go to

View file

@ -1,7 +1,5 @@
use time::{Date, Duration, Month, OffsetDateTime};
use crate::error::Error;
/// Shift a date by the given number of months.
/// Ambiguous month-ends are shifted backwards as necessary.
pub fn shift_months(date: Date, months: i32) -> Date {
@ -44,57 +42,6 @@ pub fn now_sec() -> OffsetDateTime {
.unwrap()
}
/// Gets the current timezone from the system.
///
/// Currently only supported for Windows, Unix, and WASM targets.
///
/// # Errors
/// Returns an [Error](enum@Error) if the timezone cannot be determined.
pub fn local_timezone_name() -> Result<String, Error> {
#[cfg(unix)]
{
use std::path::Path;
let path = Path::new("/etc/localtime");
let realpath = std::fs::read_link(path)
.map_err(|_| Error::Other("could not read localtime".into()))?;
// The part of the path we're interested in cannot contain non unicode characters.
return realpath
.to_str()
.and_then(|s| s.split("/zoneinfo/").last())
.map(str::to_owned)
.ok_or_else(|| {
Error::Other(format!("could not parse zoneinfo path: {realpath:?}").into())
});
}
#[cfg(windows)]
{
unsafe {
use windows_sys::Win32::System::Time::GetDynamicTimeZoneInformation;
use windows_sys::Win32::System::Time::DYNAMIC_TIME_ZONE_INFORMATION;
let mut data: DYNAMIC_TIME_ZONE_INFORMATION = std::mem::zeroed();
let res = GetDynamicTimeZoneInformation(&mut data as _);
if res > 2 {
return Err(Error::Other("local timezone could not be read".into()));
} else {
let win_name_utf16 = &data.TimeZoneKeyName;
let mut len: usize = 0;
while win_name_utf16[len] != 0x0 {
len += 1;
}
if len == 0 {
return Err(Error::Other("local timezone could not be read".into()));
}
return String::from_utf16(&win_name_utf16[..len])
.map_err(|_| Error::Other("local timezone is invalid UTF16".into()));
}
}
}
#[allow(unreachable_code)]
Err(Error::Other("local timezone unsupported".into()))
}
#[cfg(test)]
mod tests {
use rstest::rstest;
@ -108,9 +55,4 @@ mod tests {
let res = super::shift_weeks_monday(date, weeks);
assert_eq!(res, expect);
}
#[test]
fn local_timezone_name() {
super::local_timezone_name().unwrap();
}
}

View file

@ -5,7 +5,7 @@ mod visitor_data;
pub mod dictionary;
pub mod timeago;
pub use date::{local_timezone_name, now_sec, shift_months, shift_weeks_monday, shift_years};
pub use date::{now_sec, shift_months, shift_weeks_monday, shift_years};
pub use protobuf::{string_from_pb, ProtoBuilder};
pub use visitor_data::VisitorDataCache;