You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取各时区专属参数以调用win32api.SetTimeZoneInformation()

获取全时区SetTimeZoneInformation参数的可行方法

要生成所有时区的SetTimeZoneInformation参数表,有两种最可靠的方案,均基于Windows系统原生数据,避免手动维护的误差:


1. 读取Windows时区注册表项

Windows系统将所有时区的完整信息存储在注册表路径HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones下,每个子项对应一个时区,可直接解析出SetTimeZoneInformation需要的参数。

关键映射关系

  • Bias/StandardBias/DaylightBias:从子项的TZI二进制值中解析(该二进制结构与TIME_ZONE_INFORMATION结构体完全对应)
  • StandardName/DaylightName:对应子项的Std和Dlt字符串值
  • StandardDate/DaylightDate:从TZI二进制值中解析出SYSTEMTIME结构,转换为你需要的元组格式

Python示例代码

import win32api
import win32con
import struct

# 打开时区注册表根键
tz_root = win32api.RegOpenKeyEx(win32con.HKEY_LOCAL_MACHINE, 
                                r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones",
                                0, win32con.KEY_READ)

index = 0
while True:
    try:
        tz_name, _, _ = win32api.RegEnumKeyEx(tz_root, index)
        index += 1
        
        # 打开当前时区子项
        tz_key = win32api.RegOpenKeyEx(tz_root, tz_name, 0, win32con.KEY_READ)
        
        # 解析TZI二进制数据
        tzi_data, _ = win32api.RegQueryValueEx(tz_key, "TZI")
        bias = struct.unpack("<l", tzi_data[0:4])[0]
        standard_bias = struct.unpack("<l", tzi_data[4:8])[0]
        daylight_bias = struct.unpack("<l", tzi_data[8:12])[0]
        
        # 解析StandardDate
        std_st = struct.unpack("<8H", tzi_data[12:28])
        standard_date = (std_st[0], std_st[1], std_st[2], std_st[3], 
                         std_st[4], std_st[5], std_st[6], std_st[7])
        
        # 解析DaylightDate
        dlt_st = struct.unpack("<8H", tzi_data[28:44])
        daylight_date = (dlt_st[0], dlt_st[1], dlt_st[2], dlt_st[3], 
                         dlt_st[4], dlt_st[5], dlt_st[6], dlt_st[7])
        
        # 读取时区名称
        standard_name, _ = win32api.RegQueryValueEx(tz_key, "Std")
        daylight_name, _ = win32api.RegQueryValueEx(tz_key, "Dlt")
        
        # 组装成SetTimeZoneInformation所需的元组
        tzi_tuple = (bias, standard_name, standard_date, 
                     standard_bias, daylight_name, daylight_date, daylight_bias)
        
        print(f"时区: {tz_name}")
        print(f"参数元组: {tzi_tuple}\n")
        
        win32api.RegCloseKey(tz_key)
    except win32api.error:
        break

win32api.RegCloseKey(tz_root)

2. 调用EnumDynamicTimeZoneInformation API

该API是Windows提供的原生接口,可枚举系统中所有动态时区(包含历史夏令时规则等完整信息),返回的DYNAMIC_TIME_ZONE_INFORMATION结构体可直接转换为SetTimeZoneInformation需要的参数格式。

Python示例代码(使用ctypes)

import ctypes
from ctypes import wintypes

# 定义SYSTEMTIME结构体
class SYSTEMTIME(ctypes.Structure):
    _fields_ = [
        ("wYear", wintypes.WORD),
        ("wMonth", wintypes.WORD),
        ("wDayOfWeek", wintypes.WORD),
        ("wDay", wintypes.WORD),
        ("wHour", wintypes.WORD),
        ("wMinute", wintypes.WORD),
        ("wSecond", wintypes.WORD),
        ("wMilliseconds", wintypes.WORD)
    ]

# 定义DYNAMIC_TIME_ZONE_INFORMATION结构体
class DYNAMIC_TIME_ZONE_INFORMATION(ctypes.Structure):
    _fields_ = [
        ("Bias", wintypes.LONG),
        ("StandardName", wintypes.WCHAR * 32),
        ("StandardDate", SYSTEMTIME),
        ("StandardBias", wintypes.LONG),
        ("DaylightName", wintypes.WCHAR * 32),
        ("DaylightDate", SYSTEMTIME),
        ("DaylightBias", wintypes.LONG),
        ("TimeZoneKeyName", wintypes.WCHAR * 128),
        ("DynamicDaylightTimeDisabled", wintypes.BOOL)
    ]

# 加载kernel32并调用API
kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
EnumDynamicTimeZoneInformation = kernel32.EnumDynamicTimeZoneInformation
EnumDynamicTimeZoneInformation.argtypes = [wintypes.DWORD, ctypes.POINTER(DYNAMIC_TIME_ZONE_INFORMATION)]
EnumDynamicTimeZoneInformation.restype = wintypes.DWORD

index = 0
while True:
    dtzi = DYNAMIC_TIME_ZONE_INFORMATION()
    result = EnumDynamicTimeZoneInformation(index, ctypes.byref(dtzi))
    if result != 0:
        break
    
    # 转换为SetTimeZoneInformation所需元组
    standard_date = (
        dtzi.StandardDate.wYear, dtzi.StandardDate.wMonth,
        dtzi.StandardDate.wDayOfWeek, dtzi.StandardDate.wDay,
        dtzi.StandardDate.wHour, dtzi.StandardDate.wMinute,
        dtzi.StandardDate.wSecond, dtzi.StandardDate.wMilliseconds
    )
    daylight_date = (
        dtzi.DaylightDate.wYear, dtzi.DaylightDate.wMonth,
        dtzi.DaylightDate.wDayOfWeek, dtzi.DaylightDate.wDay,
        dtzi.DaylightDate.wHour, dtzi.DaylightDate.wMinute,
        dtzi.DaylightDate.wSecond, dtzi.DaylightDate.wMilliseconds
    )
    tzi_tuple = (
        dtzi.Bias, dtzi.StandardName, standard_date,
        dtzi.StandardBias, dtzi.DaylightName, daylight_date,
        dtzi.DaylightBias
    )
    
    print(f"时区: {dtzi.TimeZoneKeyName}")
    print(f"参数元组: {tzi_tuple}\n")
    index += 1

注意事项

  • 无夏令时的时区,DaylightName可能为空字符串,StandardDate和DaylightDate的year字段会设为0,不影响SetTimeZoneInformation的调用。
  • 两种方案均直接获取系统原生数据,与时区规则完全同步,无需手动维护参数表。

内容的提问来源于stack exchange,提问作者School of Iris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 17:54:50