C# 22H2之后的windows版本使用SetDynamicTimeZoneInformation设置时区失败处理
使用SetDynamicTimeZoneInformation设置时区返回false,设置失败。
使用PowerShell设置Set-TimeZone成功。
/// <summary> /// 设置本地时区 /// 参数取值"China Standard Time",即可设置为中国时区 /// </summary> /// <param name="timeZoneId"></param> /// <returns></returns> public static bool SetLocalTimeZone(string timeZoneId) { var dynamicTimeZoneInformation = ConvertDynamicTimeZoneInformation(timeZoneId); bool success; // 检测当前系统是否为旧系统 if (IsOldOsVersion()) { var tzi = ConvertTimeZoneInformation(dynamicTimeZoneInformation); success = SetTimeZoneInformation(ref tzi); } else { success = SetDynamicTimeZoneInformation(ref dynamicTimeZoneInformation); } if (success) { TimeZoneInfo.ClearCachedData(); // 清除缓存 } else { success = SetTimeZoneByPowerShell(dynamicTimeZoneInformation.timeZoneKeyName); } return success; } /// <summary> /// 根据时区名获取对应的DynamicTimeZoneInformation /// </summary> /// <param name="timeZoneName"></param> /// <returns></returns> private static DynamicTimeZoneInformation ConvertDynamicTimeZoneInformation(string timeZoneName) { var timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName); var info = new DynamicTimeZoneInformation { standardName = timeZoneInfo.StandardName, standardDate = new SystemTime(), daylightName = timeZoneInfo.DaylightName, daylightDate = new SystemTime(), timeZoneKeyName = timeZoneInfo.Id, dynamicDaylightTimeDisabled = false, bias = -Convert.ToInt32(timeZoneInfo.BaseUtcOffset.TotalMinutes) }; return info; } /// <summary> /// 判断Windows系统是否为旧版本 /// </summary> /// <returns></returns> public static bool IsOldOsVersion() { var os = Environment.OSVersion; return os.Platform != PlatformID.Win32NT || os.Version.Major < 6; } /// <summary> /// 将DynamicTimeZoneInformation转换为TimeZoneInformation /// </summary> /// <param name="info"></param> /// <returns></returns> private static TimeZoneInformation ConvertTimeZoneInformation(DynamicTimeZoneInformation info) { return new TimeZoneInformation { bias = info.bias, standardName = info.standardName, standardDate = info.standardDate, standardBias = info.standardBias, daylightName = info.daylightName, daylightDate = info.daylightDate, daylightBias = info.daylightBias }; } // 针对于旧Windows系统,如Windows XP [DllImport("kernel32.dll", CharSet = CharSet.Auto)] private static extern int GetTimeZoneInformation(ref TimeZoneInformation lpTimeZoneInformation); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] private static extern bool SetTimeZoneInformation(ref TimeZoneInformation lpTimeZoneInformation); //针对于新Windows系统,如Windows 7,Windows 8, Windows10 [DllImport("kernel32.dll", CharSet = CharSet.Auto)] private static extern int GetDynamicTimeZoneInformation(ref DynamicTimeZoneInformation lpDynamicTimeZoneInformation); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] private static extern bool SetDynamicTimeZoneInformation(ref DynamicTimeZoneInformation lpDynamicTimeZoneInformation); /// <summary> /// 通过PowerShell设置时区 /// </summary> /// <param name="id"></param> /// <returns></returns> public static bool SetTimeZoneByPowerShell(string id) { using var powerShell = PowerShell.Create(); try { //通过PowerShell设置时区 powerShell.AddCommand("Set-TimeZone").AddParameter("Id", id); powerShell.Invoke(); } catch (Exception) { return false; } return true; }