Setting system TimeZone Information programmatically in c#
-
2012年3月7日 14:27
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
- 已编辑 Shruthi.9822 2012年3月7日 14:28
- 已移动 Leo Liu - MSFT 2012年3月8日 6:23 Moved for better support. (From:Visual C# Language)
- 已移动 Karel ZikmundMicrosoft Employee 2012年4月11日 14:00 Windows API problem (From:Common Language Runtime)
全部回复
-
2012年3月7日 14:40
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
-
2012年3月8日 5:22
[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 ?
-
2012年3月8日 7: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
-
2012年3月8日 12:11
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
- 已编辑 Shruthi.9822 2012年3月8日 14:30
-
2012年3月13日 2:51
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
-
2012年3月19日 12:06Thanks for your reply rocky .... But we are using 32 bit Windows 7 Operatinfg system .
-
2012年3月20日 2:24
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
-
2012年3月22日 12:47
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;
}
}
}
-
2012年3月28日 3:57
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
-
2012年4月10日 13:45
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

