使用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;
}