2011-07-27 17 views
5

私のマシンでプログラムでタイムゾーンを設定するには、次のコードを書いています。たとえば、ニュージーランド標準時など、正のUTC時間を使用すると正常に動作します。マウンテンスタンダードタイムなどの負のUTC時間を使用すると、コードはエラーなく実行されますが、タイムゾーンはInternational Date Line west(-12:00)に設定されます。タイムゾーンをプログラマチックに設定するには、+ UTCタイムゾーンでしか動作しません。

私は何かを見逃しましたか? public struct TimeZoneinformationで私はBiasStandardBiaslongの代わりintなどを定義し

[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

ああ、私のコードでintの代わりにBiasとStandardBiasフィールドを誤ってロングとして書きました。 CLRの長さが64ビットであるため、私の構造のレイアウトが乱雑になりました。私は自分自身の質問に答えることができたように見えます。 – Nathanael

+3

答えを回答として投稿し、それを受け入れる必要があります。 –

答えて

7

:ここ

は、私が使用しているコードです。

Longは、CLRでは常に32ビットではありませんが、C++とは異なり常に64ビット値です。これにより、私の構造体のサイズが合計で64ビット増加し、ネイティブコードが見た値を誤って解釈しました。 + UTCのタイムゾーンが働いたのは事実であった。

私は上記のコードを訂正し、誰かが興味を持っている場合はタイムゾーンを正しく設定します。

関連する問題