Программная установка часового пояса работает только для часовых поясов + UTC

Я написал следующий код для программной установки часовых поясов на моей машине. Он отлично работает, если я использую положительное время UTC, например, стандартное время Новой Зеландии. Если я использую отрицательное время в формате UTC, например, Mountain Standard Time, код работает без ошибок, но часовой пояс устанавливается на западную международную линию дат (-12: 00).

Я что-то пропустил?

Вот код, который я использую:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct TimeZoneInformation
{
    public int Bias;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
    public string StandardName;
    public SystemTime StandardDate;
    public int StandardBias;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
    public string DaylightName;
    public SystemTime DaylightDate;
    public int DaylightBias;

    public static TimeZoneInformation FromTimeZoneInfo(TimeZoneInfo timeZoneInfo)
    {
        var timeZoneInformation = new TimeZoneInformation();

        timeZoneInformation.StandardName = timeZoneInfo.StandardName;
        timeZoneInformation.DaylightName = timeZoneInfo.DaylightName;

        var timeZoneRegistryPath = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\" + timeZoneInfo.Id;
        var tzi = (byte[])Microsoft.Win32.Registry.GetValue(timeZoneRegistryPath, "TZI", new byte[] {});

        if (tzi == null || tzi.Length != 44)
        {
            throw new ArgumentException("Invalid REG_TZI_FORMAT");
        }

        timeZoneInformation.Bias = BitConverter.ToInt32(tzi, 0);
        timeZoneInformation.StandardBias = BitConverter.ToInt32(tzi, 4);
        timeZoneInformation.DaylightBias = BitConverter.ToInt32(tzi, 8);
        timeZoneInformation.StandardDate.Year = BitConverter.ToInt16(tzi, 12);
        timeZoneInformation.StandardDate.Month = BitConverter.ToInt16(tzi, 14);
        timeZoneInformation.StandardDate.DayOfWeek = BitConverter.ToInt16(tzi, 0x10);
        timeZoneInformation.StandardDate.Day = BitConverter.ToInt16(tzi, 0x12);
        timeZoneInformation.StandardDate.Hour = BitConverter.ToInt16(tzi, 20);
        timeZoneInformation.StandardDate.Minute = BitConverter.ToInt16(tzi, 0x16);
        timeZoneInformation.StandardDate.Second = BitConverter.ToInt16(tzi, 0x18);
        timeZoneInformation.StandardDate.Millisecond = BitConverter.ToInt16(tzi, 0x1a);
        timeZoneInformation.DaylightDate.Year = BitConverter.ToInt16(tzi, 0x1c);
        timeZoneInformation.DaylightDate.Month = BitConverter.ToInt16(tzi, 30);
        timeZoneInformation.DaylightDate.DayOfWeek = BitConverter.ToInt16(tzi, 0x20);
        timeZoneInformation.DaylightDate.Day = BitConverter.ToInt16(tzi, 0x22);
        timeZoneInformation.DaylightDate.Hour = BitConverter.ToInt16(tzi, 0x24);
        timeZoneInformation.DaylightDate.Minute = BitConverter.ToInt16(tzi, 0x26);
        timeZoneInformation.DaylightDate.Second = BitConverter.ToInt16(tzi, 40);
        timeZoneInformation.DaylightDate.Millisecond = BitConverter.ToInt16(tzi, 0x2a);

        return timeZoneInformation;
    }
}

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetTimeZoneInformation([In] ref TimeZoneInformation timeZoneInformation);

var t = TimeZoneInformation.FromTimeZoneInfo(TimeZoneInfo.FindSystemTimeZoneById("Mountain Standard Time"));
SetTimeZoneInformation(ref t);
5
задан Nathanael 27 July 2011 в 01:18
поделиться