2011-07-27 45 views
5

Tôi đã viết mã sau đây để đặt múi giờ theo lập trình trên máy của tôi. Nó hoạt động tốt nếu tôi sử dụng một thời gian UTC tích cực, ví dụ như Giờ chuẩn New Zealand. Nếu tôi sử dụng thời gian UTC âm, chẳng hạn như Giờ chuẩn miền núi, mã sẽ chạy mà không có lỗi, nhưng múi giờ được đặt thành Đường ngày tháng quốc tế hướng Tây (-12: 00).Múi giờ cài đặt theo lập trình chỉ hoạt động cho các múi giờ + UTC

Tôi đã bỏ lỡ điều gì đó?

Đây là mã Tôi đang sử dụng:

[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); 
+2

Oh chết tiệt - Tôi đã vô tình viết các trường Bias và StandardBias là longs thay vì ints trong mã của tôi. Longs trong CLR là 64bits làm sai lệch cách bố trí của cấu trúc của tôi. Có vẻ như tôi đã xoay sở để trả lời câu hỏi của chính mình. – Nathanael

+3

Bạn nên đăng câu trả lời dưới dạng câu trả lời và chấp nhận câu trả lời. –

Trả lời

7

Trong public struct TimeZoneinformation tôi xác định BiasStandardBias như long thay vì int.

Long trong CLR luôn là giá trị 64 bit, không giống như C++, nơi thường mặc dù không phải luôn luôn 32 bit. Điều này làm tăng kích thước của cấu trúc của tôi lên tới 64 bit và làm cho mã gốc giải thích sai các giá trị mà nó thấy. Hoàn toàn ngẫu nhiên là do múi giờ + UTC hoạt động.

Tôi đã sửa mã ở trên và đặt thành công múi giờ nếu có ai quan tâm.

Các vấn đề liên quan