Created
October 15, 2012 22:55
-
-
Save clairernovotny/3896181 to your computer and use it in GitHub Desktop.
TimeZone Conversion for NetCore - Obsolete - Use the WinRTTimeZones Nuget package for the latest
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; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Runtime.InteropServices; | |
using System.Text; | |
using System.Threading.Tasks; | |
// OBSOLETE!!! Use the Nuget WinRTTimeZones package for the latest or | |
// get the code at https://github.com/onovotny/WinRTTimeZones | |
namespace TimeZoneUtils | |
{ | |
public static class Utilities | |
{ | |
private static DYNAMIC_TIME_ZONE_INFORMATION _eastern; | |
static Utilities() | |
{ | |
_eastern = EnumerateSystemTimeZones().First(tz => tz.TimeZoneKeyName == "Eastern Standard Time"); | |
} | |
public static DateTimeOffset ConvertDateToEastern(DateTimeOffset date) | |
{ | |
var currentTime = new SYSTEMTIME(date.UtcDateTime); | |
TIME_ZONE_INFORMATION tzi; | |
if (SafeNativeMethods.GetTimeZoneInformationForYear(currentTime.Year, ref _eastern, out tzi)) | |
{ | |
SYSTEMTIME local; | |
if (SafeNativeMethods.SystemTimeToTzSpecificLocalTime(ref tzi, ref currentTime, out local)) | |
{ | |
var dt = new DateTime(local.Year, local.Month, local.Day, local.Hour, local.Minute, local.Second, local.Milliseconds, | |
DateTimeKind.Unspecified); | |
// calc offset = local hr/min - current hr/min | |
var hrs = local.Hour - currentTime.Hour; | |
var min = local.Minute - currentTime.Minute; | |
var dto = new DateTimeOffset(dt, new TimeSpan(hrs, min, 0)); | |
return dto; | |
} | |
} | |
var error = Marshal.GetLastWin32Error(); | |
Marshal.ThrowExceptionForHR(error); | |
return date; | |
} | |
internal static IEnumerable<DYNAMIC_TIME_ZONE_INFORMATION> EnumerateSystemTimeZones() | |
{ | |
var i = 0; | |
while (true) | |
{ | |
DYNAMIC_TIME_ZONE_INFORMATION tz; | |
var result = SafeNativeMethods.EnumDynamicTimeZoneInformation(i++, out tz); | |
if (result != 0) | |
yield break; | |
yield return tz; | |
} | |
} | |
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] | |
internal struct DYNAMIC_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; | |
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] | |
public string TimeZoneKeyName; | |
[MarshalAs(UnmanagedType.I1)] | |
public bool DynamicDaylightTimeDisabled; | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
internal struct SYSTEMTIME | |
{ | |
[MarshalAs(UnmanagedType.U2)] | |
public short Year; | |
[MarshalAs(UnmanagedType.U2)] | |
public short Month; | |
[MarshalAs(UnmanagedType.U2)] | |
public short DayOfWeek; | |
[MarshalAs(UnmanagedType.U2)] | |
public short Day; | |
[MarshalAs(UnmanagedType.U2)] | |
public short Hour; | |
[MarshalAs(UnmanagedType.U2)] | |
public short Minute; | |
[MarshalAs(UnmanagedType.U2)] | |
public short Second; | |
[MarshalAs(UnmanagedType.U2)] | |
public short Milliseconds; | |
public SYSTEMTIME(DateTime dt) | |
{ | |
dt = dt.ToUniversalTime(); // SetSystemTime expects the SYSTEMTIME in UTC | |
Year = (short)dt.Year; | |
Month = (short)dt.Month; | |
DayOfWeek = (short)dt.DayOfWeek; | |
Day = (short)dt.Day; | |
Hour = (short)dt.Hour; | |
Minute = (short)dt.Minute; | |
Second = (short)dt.Second; | |
Milliseconds = (short)dt.Millisecond; | |
} | |
} | |
private static class SafeNativeMethods | |
{ | |
[DllImport("kernel32.dll")] | |
internal static extern bool SystemTimeToTzSpecificLocalTime([In] ref TIME_ZONE_INFORMATION lpTimeZoneInformation, | |
[In] ref SYSTEMTIME lpUniversalTime, | |
out SYSTEMTIME lpLocalTime); | |
[DllImport("Advapi32.dll")] | |
internal static extern int EnumDynamicTimeZoneInformation([In] int dwIndex, out DYNAMIC_TIME_ZONE_INFORMATION lpTimeZoneInformation); | |
[DllImport("kernel32.dll")] | |
internal static extern bool GetTimeZoneInformationForYear([In] short wYear, | |
[In] ref DYNAMIC_TIME_ZONE_INFORMATION pdtzi, | |
out TIME_ZONE_INFORMATION ptzi); | |
} | |
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] | |
internal 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; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment