By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,756 Members | 1,729 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,756 IT Pros & Developers. It's quick & easy.

Problem Setting the Time Zone with SetTimeZoneInformation

P: n/a
I'm writing an application for Windows XP Embedded. This application
requires that the user be able to change the time zone from within the
application. I'm trying to do this using SetTimeZoneInformation, but
it's not working correctly and I can't figure out why. I'm using Visual
C# to write the application.

The problem I'm having is that if I choose US Eastern Time (-5:00)
Eastern Time (US & Canada) then the code below winds up setting my Time
Zone to (-5:00) Bogota, Lima, Quito, even though I've managed to find
US Eastern Time in the registry and set the variables correctly. This
is a problem because although the time is correct I loose my daylight
savings time information.

Does anyone have any clue why this isn't working or how I could better
set the time zone?

Here's some code snippets from the code I'm using:

Expand|Select|Wrap|Line Numbers
  1. [DllImport("Kernel32.dll")]
  2. private extern static Int64 GetTimeZoneInformation( ref
  3. TIME_ZONE_INFORMATION lpTimeZoneInformation );
  4.  
  5. private struct SYSTEMTIME
  6. {
  7. public ushort wYear;
  8. public ushort wMonth;
  9. public ushort wDayOfWeek;
  10. public ushort wDay;
  11. public ushort wHour;
  12. public ushort wMinute;
  13. public ushort wSecond;
  14. public ushort wMilliseconds;
  15. }
  16.  
  17. private unsafe struct TIME_ZONE_INFORMATION
  18. {
  19. public int Bias;
  20. public fixed char StandardName[32];
  21. public SYSTEMTIME StandardDate;
  22. public int StandardBias;
  23. public fixed char DaylightName[32];
  24. public SYSTEMTIME DaylightDate;
  25. public int DaylightBias;
  26. }
  27.  
  28. private struct REGTIMEZONEINFORMATION
  29. {
  30. public int Bias;
  31. public int StandardBias;
  32. public int DaylightBias;
  33. public SYSTEMTIME StandardDate;
  34. public SYSTEMTIME DaylightDate;
  35. }
  36.  
  37. public bool SetTimeZone(int index)
  38. {
  39. // Omitted (uses index to find the time zone in the registry so that I
  40. can get the
  41. // information about the time zone using the appropriate key's TZI
  42. value
  43.  
  44. // We've found the right time zone, get the TZI data
  45. object varValue = rkTZInfo.GetValue("TZI");
  46. byte[] baData = varValue as byte[];
  47. int iSize = baData.Length;
  48. IntPtr buffer = Marshal.AllocHGlobal(iSize);
  49. Marshal.Copy(baData, 0, buffer, iSize);
  50. rtzi = (REGTIMEZONEINFORMATION)Marshal.PtrToStructure(buffer,
  51. typeof(REGTIMEZONEINFORMATION));
  52. Marshal.FreeHGlobal(buffer);
  53.  
  54. // Now fill out TIME_ZONE_INFORMATION with that data
  55.  
  56. TIME_ZONE_INFORMATION tZoneInfo = new TIME_ZONE_INFORMATION();
  57. tZoneInfo.Bias = rtzi.Bias;
  58. tZoneInfo.StandardBias = rtzi.StandardBias;
  59. tZoneInfo.DaylightBias = rtzi.DaylightBias;
  60. tZoneInfo.StandardDate = rtzi.StandardDate;
  61. tZoneInfo.DaylightDate = rtzi.DaylightDate;
  62.  
  63. if (!SetTimeZoneInformation(ref tZoneInfo))
  64. {
  65. return (false);
  66. }
  67. }
Mar 30 '06 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Well it appears I've solved my own problem, however since I spent so
much time looking for a solution. I thought others might like to know,
so here are the above code snippets with the changes that made it all
work. Apparently, absolutely every field in TIME_ZONE_INFORMATION must
be filled in (especially the name) or it won't work.

Hopefully all this toil will help someone else.


Expand|Select|Wrap|Line Numbers
  1. [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  2. private extern static bool SetTimeZoneInformation( ref
  3. TIME_ZONE_INFORMATION lpTimeZoneInformation );
  4.  
  5. [StructLayoutAttribute(LayoutKind.Sequential)]
  6. private struct SYSTEMTIME
  7. {
  8. public ushort wYear;
  9. public ushort wMonth;
  10. public ushort wDayOfWeek;
  11. public ushort wDay;
  12. public ushort wHour;
  13. public ushort wMinute;
  14. public ushort wSecond;
  15. public ushort wMilliseconds;
  16. }
  17.  
  18. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  19. private struct TIME_ZONE_INFORMATION
  20. {
  21. public int Bias;
  22. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
  23. public string StandardName;
  24. public SYSTEMTIME StandardDate;
  25. public int StandardBias;
  26. [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
  27. public string DaylightName;
  28. public SYSTEMTIME DaylightDate;
  29. public int DaylightBias;
  30. }
  31.  
  32. [StructLayoutAttribute(LayoutKind.Sequential)]
  33. private struct REGTZI
  34. {
  35. public int Bias;
  36. public int StandardBias;
  37. public int DaylightBias;
  38. public SYSTEMTIME StandardDate;
  39. public SYSTEMTIME DaylightDate;
  40. }
  41.  
  42. public bool SetTimeZone(int index)
  43. {
  44. // Omitted (uses index to find the time zone in the registry so
  45. that I
  46. can get the
  47. // information about the time zone using the appropriate key's
  48. TZI
  49. value
  50.  
  51. // We've found the right time zone, get the TZI data
  52. object varValue = rkTZInfo.GetValue("TZI");
  53. byte[] baData = varValue as byte[];
  54. int iSize = baData.Length;
  55. IntPtr buffer = Marshal.AllocHGlobal(iSize);
  56. Marshal.Copy(baData, 0, buffer, iSize);
  57. rtzi = (REGTZI)Marshal.PtrToStructure(buffer, typeof(REGTZI));
  58. Marshal.FreeHGlobal(buffer);
  59.  
  60. // Now fill out TIME_ZONE_INFORMATION with that data
  61. TIME_ZONE_INFORMATION tZoneInfo = new TIME_ZONE_INFORMATION();
  62. tZoneInfo.Bias = rtzi.Bias;
  63. tZoneInfo.StandardBias = rtzi.StandardBias;
  64. tZoneInfo.DaylightBias = rtzi.DaylightBias;
  65. tZoneInfo.StandardDate = rtzi.StandardDate;
  66. tZoneInfo.DaylightDate = rtzi.DaylightDate;
  67. tZoneInfo.StandardName = (string)rkTZInfo.GetValue("Std");
  68. tZoneInfo.DaylightName = (string)rkTZInfo.GetValue("Dlt");
  69.  
  70. if (!SetTimeZoneInformation(ref tZoneInfo))
  71. {
  72. return (false);
  73. }
  74. }
Mar 31 '06 #2

tlhintoq
Expert 2.5K+
P: 3,525
It was really good of you to post the solution to your own question, so others would have it. Thanks you!

TIP: When you are writing your question, there is a button on the tool bar that wraps the [code] tags around your copy/pasted code. It helps a bunch. Its the button with a '#' on it. More on tags. They're cool. Check'em out.
Mar 3 '10 #3

This discussion thread is closed

Replies have been disabled for this discussion.