Peter Duniho said:
[...]
That stinks. I was reading a post somewhere else where they were using
the registry to get all available Timezones. However, I am not sure
how they figured out UTC offsets from that, nor how they handled Day
Light Savings Time. I will just ignore it.
I don't recall the format off the top of my head, but the timezone
database in the registry is not all that complicated. Microsoft has a KB
article on their support web site...
You'll find that KB article here:
http://support.microsoft.com/kb/115231
Once you're grabbed all the timezones from the registry you can use
SystemTimeToTzSpecificLocalTime and
TzSpecificLocalTimeToSystemTime to convert betwen UTC and timezone specific
local time
The following code should help:
[DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = false)]
private static extern int SystemTimeToTzSpecificLocalTime(ref
TIME_ZONE_INFORMATION lpTimeZone, ref SYSTEMTIME lpUniversalTIme, out
SYSTEMTIME lpLocalTime);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = false)]
private static extern int TzSpecificLocalTimeToSystemTime(ref
TIME_ZONE_INFORMATION lpTimeZone, ref SYSTEMTIME lpLocalTime, out SYSTEMTIME
lpUniversalTIme);
[StructLayout(LayoutKind.Sequential)]
private 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;
}
//Registry time zone format. See KB article Q115231
[StructLayout(LayoutKind.Sequential)]
private struct REG_TIME_ZONE_INFORMATION
{
public int Bias;
public int StandardBias;
public int DaylightBias;
public SYSTEMTIME StandardDate;
public SYSTEMTIME DaylightDate;
}
[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;
}
private static List<TIME_ZONE_INFORMATION> GetTimeZones()
{
List<TIME_ZONE_INFORMATION> list = new List<TIME_ZONE_INFORMATION>();
RegistryKey key =
Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows
NT\CurrentVersion\Time Zones");
if (key == null)
return list;
string[] subKeyNames = key.GetSubKeyNames();
foreach (string subKeyName in subKeyNames)
{
RegistryKey subKey = key.OpenSubKey(subKeyName);
if (subKey != null)
{
object value = subKey.GetValue("TZI");
if (value != null)
{
int length =
Marshal.SizeOf(typeof(REG_TIME_ZONE_INFORMATION));
IntPtr p = Marshal.AllocHGlobal(length);
Marshal.Copy((byte[])value, 0, p, length);
REG_TIME_ZONE_INFORMATION rtzi =
(REG_TIME_ZONE_INFORMATION)Marshal.PtrToStructure(p,
typeof(REG_TIME_ZONE_INFORMATION));
Marshal.FreeHGlobal(p);
TIME_ZONE_INFORMATION tzi = new TIME_ZONE_INFORMATION();
tzi.Bias = rtzi.Bias;
tzi.DaylightBias = rtzi.DaylightBias;
tzi.StandardBias = rtzi.StandardBias;
tzi.DaylightDate = rtzi.DaylightDate;
tzi.StandardDate = rtzi.StandardDate;
tzi.DaylightName = (string)subKey.GetValue("Dlt", "");
tzi.StandardName = (string)subKey.GetValue("Std", "");
list.Add(tzi);
}
subKey.Close();
}
}
key.Close();
return list;
}
/claes