Skip to content

Instantly share code, notes, and snippets.

@nobnak
Last active September 15, 2015 07:34
Show Gist options
  • Save nobnak/65b0980d310df1f672ff to your computer and use it in GitHub Desktop.
Save nobnak/65b0980d310df1f672ff to your computer and use it in GitHub Desktop.
Time zone converter for Unity (Windows)
using System.Collections.Generic;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using System;
using System.Text;
namespace WorldClock {
public static class TimeZoneDatabase {
public const string KERNEL32 = "kernel32.dll";
public const string REGISTRY = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones";
public static readonly Dictionary<string, TIME_ZONE_INFORMATION> TIME_ZONES
= new Dictionary<string, TIME_ZONE_INFORMATION>();
static TimeZoneDatabase() {
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(REGISTRY)) {
foreach (string zoneName in key.GetSubKeyNames()) {
using (RegistryKey subKey = key.OpenSubKey(zoneName)) {
//var displayName =(string)subKey.GetValue("Display");
var info = TIME_ZONE_INFORMATION.Generate(
(string)subKey.GetValue("Std"),
(string)subKey.GetValue("Dlt"),
(TZI)((byte[])subKey.GetValue("Tzi")));
TIME_ZONES.Add(zoneName, info);
}
}
}
}
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEMTIME {
public UInt16 wYear;
public UInt16 wMonth;
public UInt16 wDayOfWeek;
public UInt16 wDay;
public UInt16 wHour;
public UInt16 wMinute;
public UInt16 wSecond;
public UInt16 wMilliseconds;
public static implicit operator SYSTEMTIME(DateTime dt) {
return new SYSTEMTIME(){
wYear = Convert.ToUInt16(dt.Year),
wMonth = Convert.ToUInt16(dt.Month),
wDayOfWeek = Convert.ToUInt16(dt.DayOfWeek),
wDay = Convert.ToUInt16(dt.Day),
wHour = Convert.ToUInt16(dt.Hour),
wMinute = Convert.ToUInt16(dt.Minute),
wSecond = Convert.ToUInt16(dt.Second),
wMilliseconds = Convert.ToUInt16(dt.Millisecond)
};
}
public static implicit operator DateTime(SYSTEMTIME st) {
return new DateTime(st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds,
DateTimeKind.Unspecified);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct TZI {
public int bias;
public int standardBias;
public int daylightBias;
public SYSTEMTIME standardDate;
public SYSTEMTIME daylightDate;
public static implicit operator TZI(byte[] binaryTzi) {
if (binaryTzi.Length != Marshal.SizeOf(typeof(TZI)))
throw new ArgumentException("TZI size is incorrect", "binaryTzi");
TZI tzi;
var h = GCHandle.Alloc(binaryTzi, GCHandleType.Pinned);
try {
tzi = (TZI)Marshal.PtrToStructure(h.AddrOfPinnedObject(), typeof(TZI));
} finally {
h.Free();
}
return tzi;
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct TIME_ZONE_INFORMATION {
[MarshalAs(UnmanagedType.I4)]
public Int32 Bias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string StandardName;
public SYSTEMTIME StandardDate;
[MarshalAs(UnmanagedType.I4)]
public Int32 StandardBias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string DaylightName;
public SYSTEMTIME DaylightDate;
[MarshalAs(UnmanagedType.I4)]
public Int32 DaylightBias;
public static TIME_ZONE_INFORMATION Generate(string StandardName, string DaylightName, TZI tzi) {
return new TIME_ZONE_INFORMATION() {
StandardName = StandardName, DaylightName = DaylightName,
Bias = tzi.bias, StandardBias = tzi.standardBias, DaylightBias = tzi.daylightBias,
StandardDate = tzi.standardDate, DaylightDate = tzi.daylightDate
};
}
public DateTime Universal2Local(DateTime utf) {
var st = (SYSTEMTIME)utf;
SYSTEMTIME local;
SystemTimeToTzSpecificLocalTime(ref this, ref st, out local);
return (DateTime)local;
}
public DateTime Local2Universal(DateTime local) {
var st = (SYSTEMTIME)local;
SYSTEMTIME utf;
TzSpecificLocalTimeToSystemTime(ref this, ref st, out utf);
return utf;
}
}
[DllImport(KERNEL32)]
public static extern uint GetTimeZoneInformation(out TIME_ZONE_INFORMATION lpTimeZoneInformation);
[DllImport(KERNEL32)]
public static extern bool SystemTimeToTzSpecificLocalTime(
[In] ref TIME_ZONE_INFORMATION lpTimeZone,
[In] ref SYSTEMTIME lpUniversalTime,
out SYSTEMTIME lpLocalTime);
[DllImport(KERNEL32)]
public static extern bool TzSpecificLocalTimeToSystemTime(
[In] ref TIME_ZONE_INFORMATION lpTimeZone,
[In] ref SYSTEMTIME lpLocalTime,
out SYSTEMTIME lpUniversalTime);
}
}
/* References
- Convert local time to Timezone. https://staceyw1.wordpress.com/2006/08/31/convert-local-time-to-timezone/
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment