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);
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
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. –