Repository: RustPython/RustPython (language: rust)

Issue:
Implement time.tzname for windows
Blocker for #5517 


Discussion / hints:

Fix patch:
diff --git a/vm/Cargo.toml b/vm/Cargo.toml
index 6eaca281f8..b461104cb2 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 566650d0f2..5a493c3472 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::<String>();
+        let daylight = widestring::decode_utf16_lossy(info.DaylightName)
+            .filter(|&c| c != '\0')
+            .collect::<String>();
+        let tz_name = (&*standard, &*daylight);
+        tz_name.into_pytuple(vm)
+    }
+
     fn pyobj_to_date_time(
         value: Either<f64, i64>,
         vm: &VirtualMachine,


Test patch: