Last active
September 15, 2015 07:34
-
-
Save nobnak/65b0980d310df1f672ff to your computer and use it in GitHub Desktop.
Time zone converter for Unity (Windows)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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