none
Setting system TimeZone Information programmatically in c#

    Pregunta

  • Hello All ,

               I want to change the System TimeZone Information through c# 4.0 in Windows 7 Operating System. I used following structure but it is not working .

     [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;
    }

              Is this the correct structure to be referred .

     And also please give us a sample working code.

    Thanks

    Shruthi

     


    • Editado Shruthi.9822 miércoles, 07 de marzo de 2012 14:28
    • Cambiado Leo Liu - MSFT jueves, 08 de marzo de 2012 6:23 Moved for better support. (From:Visual C# Language)
    • Cambiado Karel ZikmundMicrosoft employee miércoles, 11 de abril de 2012 14:00 Windows API problem (From:Common Language Runtime)
    miércoles, 07 de marzo de 2012 14:27

Todas las respuestas

  • Hi,

    first of all, you just defined a structure in there. You have to call some functions to change the TimeZone. So you should have a closer look at the SetTimeZoneInformation function: http://msdn.microsoft.com/en-us/library/ms724944.aspx

    You can use P/Invoke to call this function.

    Code that shows how this could be done can be found in this thread, too:
    http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/fa563f41-344c-465d-bfbe-1859299d2491/

    With kind regards,

    Konrad

    miércoles, 07 de marzo de 2012 14:40

  • [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct DYNAMIC_TIME_ZONE_INFORMATION
        {
            public int bias;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string standardName;
            public SYSTEM_TIME standardDate;
            public int standardBias;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string daylightName;
            public SYSTEM_TIME daylightDate;
            public int daylightBias;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
            public string timeZoneKeyName;
            public bool dynamicDaylightTimeDisabled;
        }




    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct TIME_ZONE_INFORMATION
        {
            public int bias;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string standardName;
            public SYSTEM_TIME standardDate;
            public int standardBias;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string daylightName;
            public SYSTEM_TIME daylightDate;
            public int daylightBias;
        }




    [StructLayout(LayoutKind.Sequential)]
            private struct TZI
            {
                public int nBias;
                public int nStandardBias;
                public int nDaylightBias;
                public SYSTEM_TIME dtStandardDate;
                public SYSTEM_TIME dtDaylightDate;
            }




     [StructLayout(LayoutKind.Sequential)]
        public struct REG_TZI_FORMAT
        {
            public int bias;
            public int standardBias;
            public int daylightBias;
            public SYSTEM_TIME standardDate;
            public SYSTEM_TIME daylightDate;
        }



            const string SE_TIME_ZONE_NAME = "SeTimeZonePrivilege";


            public void SetTimeZone(string TimeZone)
            {
                OperatingSystem os = Environment.OSVersion;
                int osBuildNumber = os.Version.Build;


                ASCIIEncoding encoding = new ASCIIEncoding();


                RegistryKey key =
                Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\" + TimeZone);
                //byte[] regTziAsByteArray =
                //encoding.GetBytes(key.GetValue("TZI").ToString());


                byte[] regTziAsByteArray = (byte[])key.GetValue("TZI");


                REG_TZI_FORMAT regTzi =
                TimeZoneControl.GetRegTziFormat(regTziAsByteArray);


                if (osBuildNumber >= 6000)
                {
                    DYNAMIC_TIME_ZONE_INFORMATION info = new DYNAMIC_TIME_ZONE_INFORMATION();
                    info.bias = regTzi.bias;
                    info.standardBias = regTzi.standardBias;
                    info.daylightBias = regTzi.daylightBias;


                    if (key.GetValue("MUI_Std").ToString() == String.Empty)
                    {
                        info.standardName = key.GetValue("Std").ToString();
                    }
                    else
                    {
                        info.standardName = key.GetValue("MUI_Std").ToString();
                    }


                    if (key.GetValue("MUI_Dlt").ToString() == String.Empty)
                    {
                        info.daylightName = key.GetValue("Dlt").ToString();
                    }
                    else
                    {
                        info.daylightName = key.GetValue("MUI_Dlt").ToString();
                    }


                    info.timeZoneKeyName = TimeZone;
                    info.standardDate = regTzi.standardDate;
                    info.daylightDate = regTzi.daylightDate;
                    info.dynamicDaylightTimeDisabled = false;


                    TokenPrivileges.EnablePrivilege(SE_TIME_ZONE_NAME);
                    TimeZoneControl.SetDynamicTimeZone(info);
                    TokenPrivileges.DisablePrivilege(SE_TIME_ZONE_NAME);
                }
                else
                {
                    TIME_ZONE_INFORMATION info = new TIME_ZONE_INFORMATION();
                    info.bias = regTzi.bias;
                    info.standardBias = regTzi.standardBias;
                    info.daylightBias = regTzi.daylightBias;


                    info.standardDate = regTzi.standardDate;
                    info.daylightDate = regTzi.daylightDate;


                    info.standardName = key.GetValue("Std").ToString();
                    info.daylightName = key.GetValue("Dlt").ToString();


                    TimeZoneControl.SetTimeZone(info);


                }
            }

    This is whole code we are using to set the Time Zone of System.  SetTimeZone(string TimeZone) is called by UI . But it is not working. Please let us know where we are going wrong .... 

    Is the structures used are correct for Windows 7 OS ?

           
    jueves, 08 de marzo de 2012 5:22
  • Hi,

    I cannot really help you on your question because I have no idea what methods you are using to set the TimeZone. What is the TimeZoneControl you are using?

    Did you check out the code of the thread I linked? That code is using the Function SetTimeZoneInformation of kernel32.dll which is the correct way to set the Timezone and also provides the required structures.

    With kind regards,

    Konrad

    jueves, 08 de marzo de 2012 7:22
  • Hello ....

              Thanks for u r prompt reply ......

              I am really sorry for missing the TimeZoneControl information in my previous post. We are using the same SetTimeZoneInformation of kernel32.dll defined in a differnt class. Following is the Class for TimeZoneControl  class

    publicclassTimeZoneControl{

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]

    privatestaticexternboolSetTimeZoneInformation([In] refTIME_ZONE_INFORMATIONlpTimeZoneInformation);

    publicstaticvoidSetTimeZone(TIME_ZONE_INFORMATIONtzi)

    {

    SetTimeZoneInformation(reftzi);

    }

    }

    We are following the same approach as  in the link referred by you. 

    Please go through the above code and let us know any other thing which we are missing ...

    The same code is working in Windows XP . But not working in Windows 7


    jueves, 08 de marzo de 2012 12:11
  • If your Windows 7 is 64 bit, I think you'd better to change the registry which you get TimeZone information.

    In 64bit OS regidtry, it should be HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Time Zones.

    Otherwise, please try to change to target CPU as x86 when you complie this application.

    Hope it helps.


    Best Regards,
    Rocky Yue[MSFT]
    MSDN Community Support | Feedback to us

    martes, 13 de marzo de 2012 2:51
  • Thanks for your reply rocky .... But we are using 32 bit Windows 7 Operatinfg system .
    lunes, 19 de marzo de 2012 12:06
  • From the code above you provided, I still can't reproduce it. Could you send me a test project? It will be very benefit for us to find a solution for you.

    My email: rocky_msn@hotmail.com

    Thanks for your understanding.


    Best Regards,
    Rocky Yue[MSFT]
    MSDN Community Support | Feedback to us

    martes, 20 de marzo de 2012 2:24
  •                 

    Thanks for your promt reply . I have also send the whole test project to your email id  rocky_msn@hotmail.com

    The same code is working fine for Windows XP ,32 bit Operating system. But it is not working for Windows 7 , 32bit Operating System.

                    Please let us know the problem. Or what changes has to be done for Setting the Time Zone using C# 4.0 with Windows 7 , 32bit  Operating System .

    Following is the class which is we used for setting the Time Zone Programmatically:                 

    using System;
    using System.Windows.Forms;
    using Microsoft.Win32;
    using System.Runtime.InteropServices;
    using System.Globalization;


    namespace TimeZone
    {
        public partial class frmTimeZone : Form
        {
            #region Members


            [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
            private extern static bool SetTimeZoneInformation([In] ref TIME_ZONE_INFORMATION lpTimeZoneInformation);


            [StructLayoutAttribute(LayoutKind.Sequential)]
            public struct SYSTEMTIME
            {
                public ushort wYear;
                public ushort wMonth;
                public ushort wDayOfWeek;
                public ushort wDay;
                public ushort wHour;
                public ushort wMinute;
                public ushort wSecond;
                public ushort wMilliseconds;
            }


            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
            private struct TIME_ZONE_INFORMATION
            {
                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;
            }


            [StructLayoutAttribute(LayoutKind.Sequential)]
            private struct REGTZI
            {
                public int Bias;
                public int StandardBias;
                public int DaylightBias;
                public SYSTEMTIME StandardDate;
                public SYSTEMTIME DaylightDate;
            }


            #endregion




            public frmTimeZone()
            {
                InitializeComponent();
            }


            private void Form1_Load(object sender, EventArgs e)
            {
                comboBox1.Items.Clear();
                foreach (TimeZoneInfo tzi in TimeZoneInfo.GetSystemTimeZones())
                {
                    comboBox1.Items.Add(tzi);
                }
            }


            private void button1_Click(object sender, EventArgs e)
            {
                if(comboBox1.SelectedItem != null)
                {
                    string strStdTime = ((TimeZoneInfo)comboBox1.SelectedItem).Id;
                    SetTimeZone(strStdTime);
                }
            }


            public void SetTimeZone(string strZone)
            {
                RegistryKey rootKey = Registry.LocalMachine;
                rootKey = rootKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\" + strZone + "\\");
                object varValue = new object();
                varValue = rootKey.GetValue("TZI") as byte[];


                // We've found the right time zone, get the TZI data            
                byte[] baData = varValue as byte[];
                int iSize = baData.Length;
                IntPtr buffer = Marshal.AllocHGlobal(iSize);
                Marshal.Copy(baData, 0, buffer, iSize);
                REGTZI rtzi = (REGTZI)Marshal.PtrToStructure(buffer, typeof(REGTZI));
                Marshal.FreeHGlobal(buffer);


                // Now fill out TIME_ZONE_INFORMATION with that data
                TIME_ZONE_INFORMATION tZoneInfo = new TIME_ZONE_INFORMATION();
                tZoneInfo.Bias = rtzi.Bias;
                tZoneInfo.StandardBias = rtzi.StandardBias;
                tZoneInfo.DaylightBias = rtzi.DaylightBias;
                tZoneInfo.StandardDate = rtzi.StandardDate;
                tZoneInfo.DaylightDate = rtzi.DaylightDate;
                tZoneInfo.StandardName = (string)rootKey.GetValue("Std");
                tZoneInfo.DaylightName = (string)rootKey.GetValue("Dlt");


                if (!SetTimeZoneInformation(ref tZoneInfo))
                {
                    //return (false);
                }
                //return true;
            }
        }
    }
        
        



    jueves, 22 de marzo de 2012 12:47
  • As I found, to set the Windows 7 time zone, we need change the following registry also.
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation (this is the main affect the local system time zone.)

    Also, we need set all of the value.


    From the code snippet, I think you can read the data and set a time zone information, and then reset the value of the currentControlSet\Control\TimeZoneInformation. 

    Hope it helps.





    Best Regards,
    Rocky Yue[MSFT]
    MSDN Community Support | Feedback to us

    miércoles, 28 de marzo de 2012 3:57
  • Thanks for your reply ,setting the value currentControlSet\Control\TimeZoneInformation. is changing the registry value . But it is getting effected only after the System is restarted once. Is there any way to instantly change the value. To inform the Operating System that the Time Zone has changed instantly.

    Thanks & Regards  

    Shruthi

    martes, 10 de abril de 2012 13:45