diff --git a/vm/Cargo.toml b/vm/Cargo.toml index 6eaca281f86..b461104cb27 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -115,6 +115,7 @@ features = [ "Win32_Foundation", "Win32_System_LibraryLoader", "Win32_System_Threading", + "Win32_System_Time", "Win32_UI_Shell", ] diff --git a/vm/src/stdlib/time.rs b/vm/src/stdlib/time.rs index 566650d0f2f..5a493c34724 100644 --- a/vm/src/stdlib/time.rs +++ b/vm/src/stdlib/time.rs @@ -43,6 +43,9 @@ mod decl { DateTime, Datelike, Timelike, }; use std::time::Duration; + #[cfg(target_env = "msvc")] + #[cfg(not(target_arch = "wasm32"))] + use windows::Win32::System::Time; #[allow(dead_code)] pub(super) const SEC_TO_MS: i64 = 1000; @@ -152,6 +155,15 @@ mod decl { Ok(get_perf_time(vm)?.as_nanos()) } + #[cfg(target_env = "msvc")] + #[cfg(not(target_arch = "wasm32"))] + fn get_tz_info() -> Time::TIME_ZONE_INFORMATION { + let mut info = Time::TIME_ZONE_INFORMATION::default(); + let info_ptr = &mut info as *mut Time::TIME_ZONE_INFORMATION; + let _ = unsafe { Time::GetTimeZoneInformation(info_ptr) }; + info + } + // #[pyfunction] // fn tzset() { // unsafe { super::_tzset() }; @@ -164,6 +176,15 @@ mod decl { unsafe { super::c_timezone } } + #[cfg(target_env = "msvc")] + #[cfg(not(target_arch = "wasm32"))] + #[pyattr] + fn timezone(_vm: &VirtualMachine) -> i32 { + let info = get_tz_info(); + // https://users.rust-lang.org/t/accessing-tzname-and-similar-constants-in-windows/125771/3 + (info.Bias + info.StandardBias) * 60 + } + #[cfg(not(target_os = "freebsd"))] #[cfg(not(target_env = "msvc"))] #[cfg(not(target_arch = "wasm32"))] @@ -172,6 +193,15 @@ mod decl { unsafe { super::c_daylight } } + #[cfg(target_env = "msvc")] + #[cfg(not(target_arch = "wasm32"))] + #[pyattr] + fn daylight(_vm: &VirtualMachine) -> i32 { + let info = get_tz_info(); + // https://users.rust-lang.org/t/accessing-tzname-and-similar-constants-in-windows/125771/3 + (info.StandardBias != info.DaylightBias) as i32 + } + #[cfg(not(target_env = "msvc"))] #[cfg(not(target_arch = "wasm32"))] #[pyattr] @@ -184,6 +214,22 @@ mod decl { unsafe { (to_str(super::c_tzname[0]), to_str(super::c_tzname[1])) }.into_pytuple(vm) } + #[cfg(target_env = "msvc")] + #[cfg(not(target_arch = "wasm32"))] + #[pyattr] + fn tzname(vm: &VirtualMachine) -> crate::builtins::PyTupleRef { + use crate::builtins::tuple::IntoPyTuple; + let info = get_tz_info(); + let standard = widestring::decode_utf16_lossy(info.StandardName) + .filter(|&c| c != '\0') + .collect::(); + let daylight = widestring::decode_utf16_lossy(info.DaylightName) + .filter(|&c| c != '\0') + .collect::(); + let tz_name = (&*standard, &*daylight); + tz_name.into_pytuple(vm) + } + fn pyobj_to_date_time( value: Either, vm: &VirtualMachine,