2656 lines
112 KiB
C#

#if FRAMEWORK20
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Permissions;
using System.Runtime.Serialization;
using System.Globalization;
using System.Security;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.IO;
using System.Runtime.ConstrainedExecution;
namespace DevComponents.Schedule
{
[Serializable, HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)]
public sealed class TimeZoneInfo : IEquatable<TimeZoneInfo>, ISerializable, IDeserializationCallback
{
// Fields
private const string c_daylightValue = "Dlt";
private const string c_disableDST = "DisableAutoDaylightTimeSet";
private const string c_disableDynamicDST = "DynamicDaylightTimeDisabled";
private const string c_displayValue = "Display";
private const string c_firstEntryValue = "FirstEntry";
private const string c_lastEntryValue = "LastEntry";
private const string c_localId = "Local";
private const int c_maxKeyLength = 0xff;
private const string c_muiDaylightValue = "MUI_Dlt";
private const string c_muiDisplayValue = "MUI_Display";
private const string c_muiStandardValue = "MUI_Std";
private const string c_standardValue = "Std";
private const long c_ticksPerDay = 0xc92a69c000L;
private const long c_ticksPerDayRange = 0xc92a6998f0L;
private const long c_ticksPerHour = 0x861c46800L;
private const long c_ticksPerMillisecond = 0x2710L;
private const long c_ticksPerMinute = 0x23c34600L;
private const long c_ticksPerSecond = 0x989680L;
private const string c_timeZoneInfoRegistryHive = @"SYSTEM\CurrentControlSet\Control\TimeZoneInformation";
private const string c_timeZoneInfoRegistryHivePermissionList = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation";
private const string c_timeZoneInfoValue = "TZI";
private const string c_timeZonesRegistryHive = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones";
private const string c_timeZonesRegistryHivePermissionList = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones";
private const string c_utcId = "UTC";
private AdjustmentRule[] m_adjustmentRules;
private TimeSpan m_baseUtcOffset;
private string m_daylightDisplayName;
private string m_displayName;
private string m_id;
private string m_standardDisplayName;
private bool m_supportsDaylightSavingTime;
private static bool s_allSystemTimeZonesRead = false;
private static object s_hiddenInternalSyncObject;
private static Dictionary<string, TimeZoneInfo> s_hiddenSystemTimeZones;
private static TimeZoneInfo s_localTimeZone;
private static List<TimeZoneInfo> s_readOnlySystemTimeZones;
private static TimeZoneInfo s_utcTimeZone;
// Methods
private TimeZoneInfo(NativeMethods.TimeZoneInformation zone, bool dstDisabled)
{
if (string.IsNullOrEmpty(zone.StandardName))
{
this.m_id = "Local";
}
else
{
this.m_id = zone.StandardName;
}
this.m_baseUtcOffset = new TimeSpan(0, -zone.Bias, 0);
if (!dstDisabled)
{
NativeMethods.RegistryTimeZoneInformation timeZoneInformation = new NativeMethods.RegistryTimeZoneInformation(zone);
AdjustmentRule rule = CreateAdjustmentRuleFromTimeZoneInformation(timeZoneInformation, DateTime.MinValue.Date, DateTime.MaxValue.Date);
if (rule != null)
{
this.m_adjustmentRules = new AdjustmentRule[] { rule };
}
}
ValidateTimeZoneInfo(this.m_id, this.m_baseUtcOffset, this.m_adjustmentRules, out this.m_supportsDaylightSavingTime);
this.m_displayName = zone.StandardName;
this.m_standardDisplayName = zone.StandardName;
this.m_daylightDisplayName = zone.DaylightName;
}
private TimeZoneInfo(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new ArgumentNullException("info");
}
this.m_id = (string)info.GetValue("Id", typeof(string));
this.m_displayName = (string)info.GetValue("DisplayName", typeof(string));
this.m_standardDisplayName = (string)info.GetValue("StandardName", typeof(string));
this.m_daylightDisplayName = (string)info.GetValue("DaylightName", typeof(string));
this.m_baseUtcOffset = (TimeSpan)info.GetValue("BaseUtcOffset", typeof(TimeSpan));
this.m_adjustmentRules = (AdjustmentRule[])info.GetValue("AdjustmentRules", typeof(AdjustmentRule[]));
this.m_supportsDaylightSavingTime = (bool)info.GetValue("SupportsDaylightSavingTime", typeof(bool));
}
private TimeZoneInfo(string id, TimeSpan baseUtcOffset, string displayName, string standardDisplayName, string daylightDisplayName, AdjustmentRule[] adjustmentRules, bool disableDaylightSavingTime)
{
bool flag;
ValidateTimeZoneInfo(id, baseUtcOffset, adjustmentRules, out flag);
if ((!disableDaylightSavingTime && (adjustmentRules != null)) && (adjustmentRules.Length > 0))
{
this.m_adjustmentRules = (AdjustmentRule[])adjustmentRules.Clone();
}
this.m_id = id;
this.m_baseUtcOffset = baseUtcOffset;
this.m_displayName = displayName;
this.m_standardDisplayName = standardDisplayName;
this.m_daylightDisplayName = disableDaylightSavingTime ? null : daylightDisplayName;
this.m_supportsDaylightSavingTime = flag && !disableDaylightSavingTime;
}
[SecurityCritical, SecurityTreatAsSafe]
private static bool CheckDaylightSavingTimeDisabled()
{
try
{
PermissionSet set = new PermissionSet(PermissionState.None);
set.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation"));
set.Assert();
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\TimeZoneInformation", RegistryKeyPermissionCheck.Default, RegistryRights.ExecuteKey))
{
if (key == null)
{
return false;
}
int num = 0;
try
{
num = (int)key.GetValue("DisableAutoDaylightTimeSet", 0, RegistryValueOptions.None);
}
catch (InvalidCastException)
{
}
if (num != 1)
{
try
{
num = (int)key.GetValue("DynamicDaylightTimeDisabled", 0, RegistryValueOptions.None);
}
catch (InvalidCastException)
{
}
if (num != 1)
{
goto Label_009C;
}
}
return true;
}
}
finally
{
PermissionSet.RevertAssert();
}
Label_009C:
return false;
}
private static bool CheckDaylightSavingTimeNotSupported(NativeMethods.TimeZoneInformation timeZone)
{
return (((((timeZone.DaylightDate.Year == timeZone.StandardDate.Year) && (timeZone.DaylightDate.Month == timeZone.StandardDate.Month)) && ((timeZone.DaylightDate.DayOfWeek == timeZone.StandardDate.DayOfWeek) && (timeZone.DaylightDate.Day == timeZone.StandardDate.Day))) && (((timeZone.DaylightDate.Hour == timeZone.StandardDate.Hour) && (timeZone.DaylightDate.Minute == timeZone.StandardDate.Minute)) && (timeZone.DaylightDate.Second == timeZone.StandardDate.Second))) && (timeZone.DaylightDate.Milliseconds == timeZone.StandardDate.Milliseconds));
}
private static bool CheckIsDst(DateTime startTime, DateTime time, DateTime endTime)
{
if (startTime.Year != endTime.Year)
{
endTime = endTime.AddYears(startTime.Year - endTime.Year);
}
if (startTime.Year != time.Year)
{
time = time.AddYears(startTime.Year - time.Year);
}
if (startTime > endTime)
{
return ((time < endTime) || (time >= startTime));
}
return ((time >= startTime) && (time < endTime));
}
public static void ClearCachedData()
{
lock (s_internalSyncObject)
{
s_localTimeZone = null;
s_utcTimeZone = null;
s_systemTimeZones = null;
s_readOnlySystemTimeZones = null;
s_allSystemTimeZonesRead = false;
}
}
public static DateTime ConvertTime(DateTime dateTime, TimeZoneInfo destinationTimeZone)
{
if (destinationTimeZone == null)
{
throw new ArgumentNullException("destinationTimeZone");
}
if (dateTime.Kind == DateTimeKind.Utc)
{
lock (s_internalSyncObject)
{
return ConvertTime(dateTime, Utc, destinationTimeZone);
}
}
lock (s_internalSyncObject)
{
return ConvertTime(dateTime, Local, destinationTimeZone);
}
}
public static DateTimeOffset ConvertTime(DateTimeOffset dateTimeOffset, TimeZoneInfo destinationTimeZone)
{
if (destinationTimeZone == null)
{
throw new ArgumentNullException("destinationTimeZone");
}
DateTime utcDateTime = dateTimeOffset.UtcDateTime;
TimeSpan utcOffsetFromUtc = GetUtcOffsetFromUtc(utcDateTime, destinationTimeZone);
long ticks = utcDateTime.Ticks + utcOffsetFromUtc.Ticks;
if (ticks > DateTimeOffset.MaxValue.Ticks)
{
return DateTimeOffset.MaxValue;
}
if (ticks < DateTimeOffset.MinValue.Ticks)
{
return DateTimeOffset.MinValue;
}
return new DateTimeOffset(ticks, utcOffsetFromUtc);
}
public static DateTime ConvertTime(DateTime dateTime, TimeZoneInfo sourceTimeZone, TimeZoneInfo destinationTimeZone)
{
return ConvertTime(dateTime, sourceTimeZone, destinationTimeZone, TimeZoneInfoOptions.None);
}
internal static DateTime ConvertTime(DateTime dateTime, TimeZoneInfo sourceTimeZone, TimeZoneInfo destinationTimeZone, TimeZoneInfoOptions flags)
{
if (sourceTimeZone == null)
{
throw new ArgumentNullException("sourceTimeZone");
}
if (destinationTimeZone == null)
{
throw new ArgumentNullException("destinationTimeZone");
}
DateTimeKind correspondingKind = sourceTimeZone.GetCorrespondingKind();
if ((((flags & TimeZoneInfoOptions.NoThrowOnInvalidTime) == 0) && (dateTime.Kind != DateTimeKind.Unspecified)) && (dateTime.Kind != correspondingKind))
{
throw new ArgumentException("Argument_ConvertMismatch", "sourceTimeZone");
}
AdjustmentRule adjustmentRuleForTime = sourceTimeZone.GetAdjustmentRuleForTime(dateTime);
TimeSpan baseUtcOffset = sourceTimeZone.BaseUtcOffset;
if (adjustmentRuleForTime != null)
{
bool flag = false;
DaylightTime daylightTime = GetDaylightTime(dateTime.Year, adjustmentRuleForTime);
if (((flags & TimeZoneInfoOptions.NoThrowOnInvalidTime) == 0) && GetIsInvalidTime(dateTime, adjustmentRuleForTime, daylightTime))
{
throw new ArgumentException("Argument_DateTimeIsInvalid", "dateTime");
}
flag = GetIsDaylightSavings(dateTime, adjustmentRuleForTime, daylightTime);
baseUtcOffset += flag ? adjustmentRuleForTime.DaylightDelta : TimeSpan.Zero;
}
DateTimeKind kind = destinationTimeZone.GetCorrespondingKind();
if (((dateTime.Kind != DateTimeKind.Unspecified) && (correspondingKind != DateTimeKind.Unspecified)) && (correspondingKind == kind))
{
return dateTime;
}
long ticks = dateTime.Ticks - baseUtcOffset.Ticks;
DateTime time2 = ConvertUtcToTimeZone(ticks, destinationTimeZone);
if (kind == DateTimeKind.Local)
{
kind = DateTimeKind.Unspecified;
}
return new DateTime(time2.Ticks, kind);
}
public static DateTime ConvertTimeBySystemTimeZoneId(DateTime dateTime, string destinationTimeZoneId)
{
return ConvertTime(dateTime, FindSystemTimeZoneById(destinationTimeZoneId));
}
public static DateTimeOffset ConvertTimeBySystemTimeZoneId(DateTimeOffset dateTimeOffset, string destinationTimeZoneId)
{
return ConvertTime(dateTimeOffset, FindSystemTimeZoneById(destinationTimeZoneId));
}
public static DateTime ConvertTimeBySystemTimeZoneId(DateTime dateTime, string sourceTimeZoneId, string destinationTimeZoneId)
{
if ((dateTime.Kind == DateTimeKind.Local) && (string.Compare(sourceTimeZoneId, Local.Id, StringComparison.OrdinalIgnoreCase) == 0))
{
lock (s_internalSyncObject)
{
return ConvertTime(dateTime, Local, FindSystemTimeZoneById(destinationTimeZoneId));
}
}
if ((dateTime.Kind == DateTimeKind.Utc) && (string.Compare(sourceTimeZoneId, Utc.Id, StringComparison.OrdinalIgnoreCase) == 0))
{
lock (s_internalSyncObject)
{
return ConvertTime(dateTime, Utc, FindSystemTimeZoneById(destinationTimeZoneId));
}
}
return ConvertTime(dateTime, FindSystemTimeZoneById(sourceTimeZoneId), FindSystemTimeZoneById(destinationTimeZoneId));
}
public static DateTime ConvertTimeFromUtc(DateTime dateTime, TimeZoneInfo destinationTimeZone)
{
lock (s_internalSyncObject)
{
return ConvertTime(dateTime, Utc, destinationTimeZone);
}
}
public static DateTime ConvertTimeToUtc(DateTime dateTime)
{
if (dateTime.Kind == DateTimeKind.Utc)
{
return dateTime;
}
lock (s_internalSyncObject)
{
return ConvertTime(dateTime, Local, Utc);
}
}
public static DateTime ConvertTimeToUtc(DateTime dateTime, TimeZoneInfo sourceTimeZone)
{
lock (s_internalSyncObject)
{
return ConvertTime(dateTime, sourceTimeZone, Utc);
}
}
private static DateTime ConvertUtcToTimeZone(long ticks, TimeZoneInfo destinationTimeZone)
{
DateTime maxValue;
if (ticks > DateTime.MaxValue.Ticks)
{
maxValue = DateTime.MaxValue;
}
else if (ticks < DateTime.MinValue.Ticks)
{
maxValue = DateTime.MinValue;
}
else
{
maxValue = new DateTime(ticks);
}
TimeSpan utcOffsetFromUtc = GetUtcOffsetFromUtc(maxValue, destinationTimeZone);
ticks += utcOffsetFromUtc.Ticks;
if (ticks > DateTime.MaxValue.Ticks)
{
return DateTime.MaxValue;
}
if (ticks < DateTime.MinValue.Ticks)
{
return DateTime.MinValue;
}
return new DateTime(ticks);
}
private static AdjustmentRule CreateAdjustmentRuleFromTimeZoneInformation(NativeMethods.RegistryTimeZoneInformation timeZoneInformation, DateTime startDate, DateTime endDate)
{
if (timeZoneInformation.StandardDate.Month == 0)
{
return null;
}
TransitionTime? nullable = TransitionTimeFromTimeZoneInformation(timeZoneInformation, true);
if (!nullable.HasValue)
{
return null;
}
TransitionTime? nullable2 = TransitionTimeFromTimeZoneInformation(timeZoneInformation, false);
if (!nullable2.HasValue)
{
return null;
}
if (nullable.Equals(nullable2))
{
return null;
}
return AdjustmentRule.CreateAdjustmentRule(startDate, endDate, new TimeSpan(0, -timeZoneInformation.DaylightBias, 0), nullable.Value, nullable2.Value);
}
public static TimeZoneInfo CreateCustomTimeZone(string id, TimeSpan baseUtcOffset, string displayName, string standardDisplayName)
{
return new TimeZoneInfo(id, baseUtcOffset, displayName, standardDisplayName, standardDisplayName, null, false);
}
public static TimeZoneInfo CreateCustomTimeZone(string id, TimeSpan baseUtcOffset, string displayName, string standardDisplayName, string daylightDisplayName, AdjustmentRule[] adjustmentRules)
{
return new TimeZoneInfo(id, baseUtcOffset, displayName, standardDisplayName, daylightDisplayName, adjustmentRules, false);
}
public static TimeZoneInfo CreateCustomTimeZone(string id, TimeSpan baseUtcOffset, string displayName, string standardDisplayName, string daylightDisplayName, AdjustmentRule[] adjustmentRules, bool disableDaylightSavingTime)
{
return new TimeZoneInfo(id, baseUtcOffset, displayName, standardDisplayName, daylightDisplayName, adjustmentRules, disableDaylightSavingTime);
}
public bool Equals(TimeZoneInfo other)
{
return (((other != null) && (string.Compare(this.m_id, other.m_id, StringComparison.OrdinalIgnoreCase) == 0)) && this.HasSameRules(other));
}
[SecurityCritical, SecurityTreatAsSafe]
private static string FindIdFromTimeZoneInformation(NativeMethods.TimeZoneInformation timeZone, out bool dstDisabled)
{
dstDisabled = false;
try
{
PermissionSet set = new PermissionSet(PermissionState.None);
set.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"));
set.Assert();
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones", RegistryKeyPermissionCheck.Default, RegistryRights.ExecuteKey))
{
if (key == null)
{
return null;
}
foreach (string str in key.GetSubKeyNames())
{
if (TryCompareTimeZoneInformationToRegistry(timeZone, str, out dstDisabled))
{
return str;
}
}
}
}
finally
{
PermissionSet.RevertAssert();
}
return null;
}
public static TimeZoneInfo FindSystemTimeZoneById(string id)
{
if (string.Compare(id, "UTC", StringComparison.OrdinalIgnoreCase) == 0)
{
return Utc;
}
lock (s_internalSyncObject)
{
return GetTimeZone(id);
}
}
public static TimeZoneInfo FromSerializedString(string source)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (source.Length == 0)
{
throw new ArgumentException("Argument_InvalidSerializedString source");
}
return StringSerializer.GetDeserializedTimeZoneInfo(source);
}
private AdjustmentRule GetAdjustmentRuleForTime(DateTime dateTime)
{
if ((this.m_adjustmentRules != null) && (this.m_adjustmentRules.Length != 0))
{
DateTime date = dateTime.Date;
for (int i = 0; i < this.m_adjustmentRules.Length; i++)
{
if ((this.m_adjustmentRules[i].DateStart <= date) && (this.m_adjustmentRules[i].DateEnd >= date))
{
return this.m_adjustmentRules[i];
}
}
}
return null;
}
public AdjustmentRule[] GetAdjustmentRules()
{
if (this.m_adjustmentRules == null)
{
return new AdjustmentRule[0];
}
return (AdjustmentRule[])this.m_adjustmentRules.Clone();
}
public TimeSpan[] GetAmbiguousTimeOffsets(DateTime dateTime)
{
DateTime time;
bool flag;
if (!this.m_supportsDaylightSavingTime)
{
throw new ArgumentException("Argument_DateTimeIsNotAmbiguous", "dateTime");
}
if (dateTime.Kind == DateTimeKind.Local)
{
lock (s_internalSyncObject)
{
time = ConvertTime(dateTime, Local, this, TimeZoneInfoOptions.NoThrowOnInvalidTime);
goto Label_007D;
}
}
if (dateTime.Kind == DateTimeKind.Utc)
{
lock (s_internalSyncObject)
{
time = ConvertTime(dateTime, Utc, this, TimeZoneInfoOptions.NoThrowOnInvalidTime);
goto Label_007D;
}
}
time = dateTime;
Label_007D:
flag = false;
AdjustmentRule adjustmentRuleForTime = this.GetAdjustmentRuleForTime(time);
if (adjustmentRuleForTime != null)
{
DaylightTime daylightTime = GetDaylightTime(time.Year, adjustmentRuleForTime);
flag = GetIsAmbiguousTime(time, adjustmentRuleForTime, daylightTime);
}
if (!flag)
{
throw new ArgumentException("Argument_DateTimeIsNotAmbiguous", "dateTime");
}
TimeSpan[] spanArray = new TimeSpan[2];
if (adjustmentRuleForTime.DaylightDelta > TimeSpan.Zero)
{
spanArray[0] = this.m_baseUtcOffset;
spanArray[1] = this.m_baseUtcOffset + adjustmentRuleForTime.DaylightDelta;
return spanArray;
}
spanArray[0] = this.m_baseUtcOffset + adjustmentRuleForTime.DaylightDelta;
spanArray[1] = this.m_baseUtcOffset;
return spanArray;
}
public TimeSpan[] GetAmbiguousTimeOffsets(DateTimeOffset dateTimeOffset)
{
if (!this.m_supportsDaylightSavingTime)
{
throw new ArgumentException("Argument_DateTimeOffsetIsNotAmbiguous", "dateTimeOffset");
}
DateTime dateTime = ConvertTime(dateTimeOffset, this).DateTime;
bool flag = false;
AdjustmentRule adjustmentRuleForTime = this.GetAdjustmentRuleForTime(dateTime);
if (adjustmentRuleForTime != null)
{
DaylightTime daylightTime = GetDaylightTime(dateTime.Year, adjustmentRuleForTime);
flag = GetIsAmbiguousTime(dateTime, adjustmentRuleForTime, daylightTime);
}
if (!flag)
{
throw new ArgumentException("Argument_DateTimeOffsetIsNotAmbiguous", "dateTimeOffset");
}
TimeSpan[] spanArray = new TimeSpan[2];
if (adjustmentRuleForTime.DaylightDelta > TimeSpan.Zero)
{
spanArray[0] = this.m_baseUtcOffset;
spanArray[1] = this.m_baseUtcOffset + adjustmentRuleForTime.DaylightDelta;
return spanArray;
}
spanArray[0] = this.m_baseUtcOffset + adjustmentRuleForTime.DaylightDelta;
spanArray[1] = this.m_baseUtcOffset;
return spanArray;
}
private DateTimeKind GetCorrespondingKind()
{
if (this == s_utcTimeZone)
{
return DateTimeKind.Utc;
}
if (this == s_localTimeZone)
{
return DateTimeKind.Local;
}
return DateTimeKind.Unspecified;
}
private static DaylightTime GetDaylightTime(int year, AdjustmentRule rule)
{
TimeSpan daylightDelta = rule.DaylightDelta;
DateTime start = TransitionTimeToDateTime(year, rule.DaylightTransitionStart);
return new DaylightTime(start, TransitionTimeToDateTime(year, rule.DaylightTransitionEnd), daylightDelta);
}
public override int GetHashCode()
{
return this.m_id.ToUpperInvariant().GetHashCode();
}
private static bool GetIsAmbiguousTime(DateTime time, AdjustmentRule rule, DaylightTime daylightTime)
{
bool flag = false;
if ((rule != null) && (rule.DaylightDelta != TimeSpan.Zero))
{
DateTime end;
DateTime time3;
DateTime time4;
DateTime time5;
if (rule.DaylightDelta > TimeSpan.Zero)
{
end = daylightTime.End;
time3 = daylightTime.End - rule.DaylightDelta;
}
else
{
end = daylightTime.Start;
time3 = daylightTime.Start + rule.DaylightDelta;
}
flag = (time >= time3) && (time < end);
if (flag || (end.Year == time3.Year))
{
return flag;
}
try
{
time4 = end.AddYears(1);
time5 = time3.AddYears(1);
flag = (time >= time5) && (time < time4);
}
catch (ArgumentOutOfRangeException)
{
}
if (flag)
{
return flag;
}
try
{
time4 = end.AddYears(-1);
time5 = time3.AddYears(-1);
flag = (time >= time5) && (time < time4);
}
catch (ArgumentOutOfRangeException)
{
}
}
return flag;
}
private static bool GetIsDaylightSavings(DateTime time, AdjustmentRule rule, DaylightTime daylightTime)
{
if (rule == null)
{
return false;
}
bool flag = rule.DaylightDelta > TimeSpan.Zero;
DateTime startTime = daylightTime.Start + (flag ? rule.DaylightDelta : TimeSpan.Zero);
DateTime endTime = daylightTime.End + (flag ? -(rule.DaylightDelta) : TimeSpan.Zero);
return CheckIsDst(startTime, time, endTime);
}
private static bool GetIsDaylightSavingsFromUtc(DateTime time, int Year, TimeSpan utc, AdjustmentRule rule)
{
if (rule == null)
{
return false;
}
TimeSpan span = utc;
DaylightTime daylightTime = GetDaylightTime(Year, rule);
DateTime startTime = daylightTime.Start - span;
DateTime endTime = (daylightTime.End - span) - rule.DaylightDelta;
return CheckIsDst(startTime, time, endTime);
}
private static bool GetIsInvalidTime(DateTime time, AdjustmentRule rule, DaylightTime daylightTime)
{
bool flag = false;
if ((rule != null) && (rule.DaylightDelta != TimeSpan.Zero))
{
DateTime end;
DateTime time3;
DateTime time4;
DateTime time5;
if (rule.DaylightDelta < TimeSpan.Zero)
{
end = daylightTime.End;
time3 = daylightTime.End - rule.DaylightDelta;
}
else
{
end = daylightTime.Start;
time3 = daylightTime.Start + rule.DaylightDelta;
}
flag = (time >= end) && (time < time3);
if (flag || (end.Year == time3.Year))
{
return flag;
}
try
{
time4 = end.AddYears(1);
time5 = time3.AddYears(1);
flag = (time >= time4) && (time < time5);
}
catch (ArgumentOutOfRangeException)
{
}
if (flag)
{
return flag;
}
try
{
time4 = end.AddYears(-1);
time5 = time3.AddYears(-1);
flag = (time >= time4) && (time < time5);
}
catch (ArgumentOutOfRangeException)
{
}
}
return flag;
}
[SecurityCritical]
private static TimeZoneInfo GetLocalTimeZone()
{
string id = null;
try
{
TimeZoneInfo info;
Exception exception;
TimeZoneInfo info2;
Exception exception2;
NativeMethods.DynamicTimeZoneInformation lpDynamicTimeZoneInformation = new NativeMethods.DynamicTimeZoneInformation();
long dynamicTimeZoneInformation = UnsafeNativeMethods.GetDynamicTimeZoneInformation(out lpDynamicTimeZoneInformation);
if (dynamicTimeZoneInformation == -1L)
{
return CreateCustomTimeZone("Local", TimeSpan.Zero, "Local", "Local");
}
NativeMethods.TimeZoneInformation timeZone = new NativeMethods.TimeZoneInformation(lpDynamicTimeZoneInformation);
bool dstDisabled = CheckDaylightSavingTimeDisabled();
if (!string.IsNullOrEmpty(lpDynamicTimeZoneInformation.TimeZoneKeyName) && (TryGetTimeZone(lpDynamicTimeZoneInformation.TimeZoneKeyName, dstDisabled, out info, out exception) == TimeZoneInfoResult.Success))
{
return info;
}
id = FindIdFromTimeZoneInformation(timeZone, out dstDisabled);
if ((id != null) && (TryGetTimeZone(id, dstDisabled, out info2, out exception2) == TimeZoneInfoResult.Success))
{
return info2;
}
return GetLocalTimeZoneFromWin32Data(timeZone, dstDisabled);
}
catch (EntryPointNotFoundException)
{
bool flag2;
TimeZoneInfo info3;
Exception exception3;
NativeMethods.TimeZoneInformation lpTimeZoneInformation = new NativeMethods.TimeZoneInformation();
long timeZoneInformation = UnsafeNativeMethods.GetTimeZoneInformation(out lpTimeZoneInformation);
if (timeZoneInformation == -1L)
{
return CreateCustomTimeZone("Local", TimeSpan.Zero, "Local", "Local");
}
id = FindIdFromTimeZoneInformation(lpTimeZoneInformation, out flag2);
if ((id != null) && (TryGetTimeZone(id, flag2, out info3, out exception3) == TimeZoneInfoResult.Success))
{
return info3;
}
return GetLocalTimeZoneFromWin32Data(lpTimeZoneInformation, flag2);
}
}
private static TimeZoneInfo GetLocalTimeZoneFromWin32Data(NativeMethods.TimeZoneInformation timeZoneInformation, bool dstDisabled)
{
TimeZoneInfo info = null;
try
{
info = new TimeZoneInfo(timeZoneInformation, dstDisabled);
}
catch (ArgumentException)
{
}
catch (InvalidTimeZoneException)
{
}
return info;
try
{
info = new TimeZoneInfo(timeZoneInformation, true);
}
catch (ArgumentException)
{
}
catch (InvalidTimeZoneException)
{
}
return info;
}
[SecurityTreatAsSafe, SecurityCritical]
public static List<TimeZoneInfo> GetSystemTimeZones()
{
lock (s_internalSyncObject)
{
if (!s_allSystemTimeZonesRead)
{
PermissionSet set = new PermissionSet(PermissionState.None);
set.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"));
set.Assert();
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones", RegistryKeyPermissionCheck.Default, RegistryRights.ExecuteKey))
{
if (key == null)
{
List<TimeZoneInfo> list;
if (s_systemTimeZones != null)
{
list = new List<TimeZoneInfo>(s_systemTimeZones.Values);
}
else
{
list = new List<TimeZoneInfo>();
}
s_readOnlySystemTimeZones = new List<TimeZoneInfo>(list);
s_allSystemTimeZonesRead = true;
return s_readOnlySystemTimeZones;
}
foreach (string str in key.GetSubKeyNames())
{
TimeZoneInfo info;
Exception exception;
TryGetTimeZone(str, false, out info, out exception);
}
}
IComparer<TimeZoneInfo> comparer = new TimeZoneInfoComparer();
List<TimeZoneInfo> list2 = new List<TimeZoneInfo>(s_systemTimeZones.Values);
list2.Sort(comparer);
s_readOnlySystemTimeZones = new List<TimeZoneInfo>(list2);
s_allSystemTimeZonesRead = true;
}
return s_readOnlySystemTimeZones;
}
}
private static TimeZoneInfo GetTimeZone(string id)
{
TimeZoneInfo info;
Exception exception;
if (id == null)
{
throw new ArgumentNullException("id");
}
if (((id.Length == 0) || (id.Length > 0xff)) || id.Contains("\0"))
{
throw new TimeZoneNotFoundException("TimeZoneNotFound_MissingRegistryData, id");
}
switch (TryGetTimeZone(id, false, out info, out exception))
{
case TimeZoneInfoResult.Success:
return info;
case TimeZoneInfoResult.InvalidTimeZoneException:
throw new InvalidTimeZoneException("InvalidTimeZone_InvalidRegistryData, id", exception);
case TimeZoneInfoResult.SecurityException:
throw new SecurityException("Security_CannotReadRegistryData, id", exception);
}
throw new TimeZoneNotFoundException("TimeZoneNotFound_MissingRegistryData, id", exception);
}
public TimeSpan GetUtcOffset(DateTime dateTime)
{
if (dateTime.Kind == DateTimeKind.Local)
{
DateTime time;
lock (s_internalSyncObject)
{
if (this.GetCorrespondingKind() == DateTimeKind.Local)
{
return GetUtcOffset(dateTime, this);
}
time = ConvertTime(dateTime, Local, Utc, TimeZoneInfoOptions.NoThrowOnInvalidTime);
}
return GetUtcOffsetFromUtc(time, this);
}
if (dateTime.Kind != DateTimeKind.Utc)
{
return GetUtcOffset(dateTime, this);
}
if (this.GetCorrespondingKind() == DateTimeKind.Utc)
{
return this.m_baseUtcOffset;
}
return GetUtcOffsetFromUtc(dateTime, this);
}
public TimeSpan GetUtcOffset(DateTimeOffset dateTimeOffset)
{
return GetUtcOffsetFromUtc(dateTimeOffset.UtcDateTime, this);
}
private static TimeSpan GetUtcOffset(DateTime time, TimeZoneInfo zone)
{
TimeSpan baseUtcOffset = zone.BaseUtcOffset;
AdjustmentRule adjustmentRuleForTime = zone.GetAdjustmentRuleForTime(time);
if (adjustmentRuleForTime != null)
{
DaylightTime daylightTime = GetDaylightTime(time.Year, adjustmentRuleForTime);
bool flag = GetIsDaylightSavings(time, adjustmentRuleForTime, daylightTime);
baseUtcOffset += flag ? adjustmentRuleForTime.DaylightDelta : TimeSpan.Zero;
}
return baseUtcOffset;
}
private static TimeSpan GetUtcOffsetFromUtc(DateTime time, TimeZoneInfo zone)
{
bool flag;
return GetUtcOffsetFromUtc(time, zone, out flag);
}
private static TimeSpan GetUtcOffsetFromUtc(DateTime time, TimeZoneInfo zone, out bool isDaylightSavings)
{
int year;
AdjustmentRule adjustmentRuleForTime;
isDaylightSavings = false;
TimeSpan baseUtcOffset = zone.BaseUtcOffset;
if (time > new DateTime(0x270f, 12, 0x1f))
{
adjustmentRuleForTime = zone.GetAdjustmentRuleForTime(DateTime.MaxValue);
year = 0x270f;
}
else if (time < new DateTime(1, 1, 2))
{
adjustmentRuleForTime = zone.GetAdjustmentRuleForTime(DateTime.MinValue);
year = 1;
}
else
{
DateTime dateTime = time + baseUtcOffset;
year = time.Year;
adjustmentRuleForTime = zone.GetAdjustmentRuleForTime(dateTime);
}
if (adjustmentRuleForTime != null)
{
isDaylightSavings = GetIsDaylightSavingsFromUtc(time, year, zone.m_baseUtcOffset, adjustmentRuleForTime);
baseUtcOffset += isDaylightSavings ? adjustmentRuleForTime.DaylightDelta : TimeSpan.Zero;
}
return baseUtcOffset;
}
public bool HasSameRules(TimeZoneInfo other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if ((this.m_baseUtcOffset != other.m_baseUtcOffset) || (this.m_supportsDaylightSavingTime != other.m_supportsDaylightSavingTime))
{
return false;
}
AdjustmentRule[] adjustmentRules = this.m_adjustmentRules;
AdjustmentRule[] ruleArray2 = other.m_adjustmentRules;
bool flag = ((adjustmentRules == null) && (ruleArray2 == null)) || ((adjustmentRules != null) && (ruleArray2 != null));
if (!flag)
{
return false;
}
if (adjustmentRules != null)
{
if (adjustmentRules.Length != ruleArray2.Length)
{
return false;
}
for (int i = 0; i < adjustmentRules.Length; i++)
{
if (!adjustmentRules[i].Equals(ruleArray2[i]))
{
return false;
}
}
}
return flag;
}
public bool IsAmbiguousTime(DateTime dateTime)
{
DateTime time;
AdjustmentRule rule;
if (!this.m_supportsDaylightSavingTime)
{
return false;
}
if (dateTime.Kind == DateTimeKind.Local)
{
lock (s_internalSyncObject)
{
time = ConvertTime(dateTime, Local, this, TimeZoneInfoOptions.NoThrowOnInvalidTime);
goto Label_0068;
}
}
if (dateTime.Kind == DateTimeKind.Utc)
{
lock (s_internalSyncObject)
{
time = ConvertTime(dateTime, Utc, this, TimeZoneInfoOptions.NoThrowOnInvalidTime);
goto Label_0068;
}
}
time = dateTime;
Label_0068:
rule = this.GetAdjustmentRuleForTime(time);
if (rule != null)
{
DaylightTime daylightTime = GetDaylightTime(time.Year, rule);
return GetIsAmbiguousTime(time, rule, daylightTime);
}
return false;
}
public bool IsAmbiguousTime(DateTimeOffset dateTimeOffset)
{
if (!this.m_supportsDaylightSavingTime)
{
return false;
}
DateTimeOffset offset = ConvertTime(dateTimeOffset, this);
return this.IsAmbiguousTime(offset.DateTime);
}
public bool IsDaylightSavingTime(DateTime dateTime)
{
DateTime time;
AdjustmentRule rule;
if (!this.m_supportsDaylightSavingTime || (this.m_adjustmentRules == null))
{
return false;
}
if (dateTime.Kind == DateTimeKind.Local)
{
lock (s_internalSyncObject)
{
time = ConvertTime(dateTime, Local, this, TimeZoneInfoOptions.NoThrowOnInvalidTime);
goto Label_0064;
}
}
if (dateTime.Kind == DateTimeKind.Utc)
{
bool flag;
if (this.GetCorrespondingKind() == DateTimeKind.Utc)
{
return false;
}
GetUtcOffsetFromUtc(dateTime, this, out flag);
return flag;
}
time = dateTime;
Label_0064:
rule = this.GetAdjustmentRuleForTime(time);
if (rule != null)
{
DaylightTime daylightTime = GetDaylightTime(time.Year, rule);
return GetIsDaylightSavings(time, rule, daylightTime);
}
return false;
}
public bool IsDaylightSavingTime(DateTimeOffset dateTimeOffset)
{
bool flag;
GetUtcOffsetFromUtc(dateTimeOffset.UtcDateTime, this, out flag);
return flag;
}
public bool IsInvalidTime(DateTime dateTime)
{
bool flag = false;
if ((dateTime.Kind != DateTimeKind.Unspecified) && ((dateTime.Kind != DateTimeKind.Local) || (this.GetCorrespondingKind() != DateTimeKind.Local)))
{
return flag;
}
AdjustmentRule adjustmentRuleForTime = this.GetAdjustmentRuleForTime(dateTime);
if (adjustmentRuleForTime != null)
{
DaylightTime daylightTime = GetDaylightTime(dateTime.Year, adjustmentRuleForTime);
return GetIsInvalidTime(dateTime, adjustmentRuleForTime, daylightTime);
}
return false;
}
void IDeserializationCallback.OnDeserialization(object sender)
{
try
{
bool flag;
ValidateTimeZoneInfo(this.m_id, this.m_baseUtcOffset, this.m_adjustmentRules, out flag);
if (flag != this.m_supportsDaylightSavingTime)
{
throw new SerializationException("Serialization_CorruptField, SupportsDaylightSavingTime" );
}
}
catch (ArgumentException exception)
{
throw new SerializationException("Serialization_InvalidData", exception);
}
catch (InvalidTimeZoneException exception2)
{
throw new SerializationException("Serialization_InvalidData", exception2);
}
}
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new ArgumentNullException("info");
}
info.AddValue("Id", this.m_id);
info.AddValue("DisplayName", this.m_displayName);
info.AddValue("StandardName", this.m_standardDisplayName);
info.AddValue("DaylightName", this.m_daylightDisplayName);
info.AddValue("BaseUtcOffset", this.m_baseUtcOffset);
info.AddValue("AdjustmentRules", this.m_adjustmentRules);
info.AddValue("SupportsDaylightSavingTime", this.m_supportsDaylightSavingTime);
}
public string ToSerializedString()
{
return StringSerializer.GetSerializedString(this);
}
public override string ToString()
{
return this.DisplayName;
}
private static TransitionTime? TransitionTimeFromTimeZoneInformation(NativeMethods.RegistryTimeZoneInformation timeZoneInformation, bool readStartDate)
{
TransitionTime time;
if (timeZoneInformation.StandardDate.Month == 0)
{
return null;
}
if (readStartDate)
{
if (timeZoneInformation.DaylightDate.Year == 0)
{
time = TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, timeZoneInformation.DaylightDate.Hour, timeZoneInformation.DaylightDate.Minute, timeZoneInformation.DaylightDate.Second, timeZoneInformation.DaylightDate.Milliseconds), timeZoneInformation.DaylightDate.Month, timeZoneInformation.DaylightDate.Day, (DayOfWeek)timeZoneInformation.DaylightDate.DayOfWeek);
}
else
{
time = TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, timeZoneInformation.DaylightDate.Hour, timeZoneInformation.DaylightDate.Minute, timeZoneInformation.DaylightDate.Second, timeZoneInformation.DaylightDate.Milliseconds), timeZoneInformation.DaylightDate.Month, timeZoneInformation.DaylightDate.Day);
}
}
else if (timeZoneInformation.StandardDate.Year == 0)
{
time = TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, timeZoneInformation.StandardDate.Hour, timeZoneInformation.StandardDate.Minute, timeZoneInformation.StandardDate.Second, timeZoneInformation.StandardDate.Milliseconds), timeZoneInformation.StandardDate.Month, timeZoneInformation.StandardDate.Day, (DayOfWeek)timeZoneInformation.StandardDate.DayOfWeek);
}
else
{
time = TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, timeZoneInformation.StandardDate.Hour, timeZoneInformation.StandardDate.Minute, timeZoneInformation.StandardDate.Second, timeZoneInformation.StandardDate.Milliseconds), timeZoneInformation.StandardDate.Month, timeZoneInformation.StandardDate.Day);
}
return new TransitionTime?(time);
}
private static DateTime TransitionTimeToDateTime(int year, TransitionTime transitionTime)
{
DateTime time;
DateTime timeOfDay = transitionTime.TimeOfDay;
if (transitionTime.IsFixedDateRule)
{
int num = DateTime.DaysInMonth(year, transitionTime.Month);
return new DateTime(year, transitionTime.Month, (num < transitionTime.Day) ? num : transitionTime.Day, timeOfDay.Hour, timeOfDay.Minute, timeOfDay.Second, timeOfDay.Millisecond);
}
if (transitionTime.Week <= 4)
{
time = new DateTime(year, transitionTime.Month, 1, timeOfDay.Hour, timeOfDay.Minute, timeOfDay.Second, timeOfDay.Millisecond);
int dayOfWeek = (int)time.DayOfWeek;
int num3 = ((int)transitionTime.DayOfWeek) - dayOfWeek;
if (num3 < 0)
{
num3 += 7;
}
num3 += 7 * (transitionTime.Week - 1);
if (num3 > 0)
{
time = time.AddDays((double)num3);
}
return time;
}
int day = DateTime.DaysInMonth(year, transitionTime.Month);
time = new DateTime(year, transitionTime.Month, day, timeOfDay.Hour, timeOfDay.Minute, timeOfDay.Second, timeOfDay.Millisecond);
int num6 = (int)(time.DayOfWeek - transitionTime.DayOfWeek);
if (num6 < 0)
{
num6 += 7;
}
if (num6 > 0)
{
time = time.AddDays((double)-num6);
}
return time;
}
private static bool TryCompareStandardDate(NativeMethods.TimeZoneInformation timeZone, NativeMethods.RegistryTimeZoneInformation registryTimeZoneInfo)
{
return ((((((timeZone.Bias == registryTimeZoneInfo.Bias) && (timeZone.StandardBias == registryTimeZoneInfo.StandardBias)) && ((timeZone.StandardDate.Year == registryTimeZoneInfo.StandardDate.Year) && (timeZone.StandardDate.Month == registryTimeZoneInfo.StandardDate.Month))) && (((timeZone.StandardDate.DayOfWeek == registryTimeZoneInfo.StandardDate.DayOfWeek) && (timeZone.StandardDate.Day == registryTimeZoneInfo.StandardDate.Day)) && ((timeZone.StandardDate.Hour == registryTimeZoneInfo.StandardDate.Hour) && (timeZone.StandardDate.Minute == registryTimeZoneInfo.StandardDate.Minute)))) && (timeZone.StandardDate.Second == registryTimeZoneInfo.StandardDate.Second)) && (timeZone.StandardDate.Milliseconds == registryTimeZoneInfo.StandardDate.Milliseconds));
}
[SecurityTreatAsSafe, SecurityCritical]
private static bool TryCompareTimeZoneInformationToRegistry(NativeMethods.TimeZoneInformation timeZone, string id, out bool dstDisabled)
{
bool flag2;
dstDisabled = false;
try
{
PermissionSet set = new PermissionSet(PermissionState.None);
set.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"));
set.Assert();
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(string.Format(CultureInfo.InvariantCulture, @"{0}\{1}", new object[] { @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones", id }), RegistryKeyPermissionCheck.Default, RegistryRights.ExecuteKey))
{
NativeMethods.RegistryTimeZoneInformation information;
if (key == null)
{
return false;
}
try
{
information = new NativeMethods.RegistryTimeZoneInformation((byte[])key.GetValue("TZI", null, RegistryValueOptions.None));
}
catch (InvalidCastException)
{
return false;
}
catch (ArgumentException)
{
return false;
}
if (!TryCompareStandardDate(timeZone, information))
{
return false;
}
dstDisabled = CheckDaylightSavingTimeDisabled();
bool flag = (dstDisabled || CheckDaylightSavingTimeNotSupported(timeZone)) || (((((timeZone.DaylightBias == information.DaylightBias) && (timeZone.DaylightDate.Year == information.DaylightDate.Year)) && ((timeZone.DaylightDate.Month == information.DaylightDate.Month) && (timeZone.DaylightDate.DayOfWeek == information.DaylightDate.DayOfWeek))) && (((timeZone.DaylightDate.Day == information.DaylightDate.Day) && (timeZone.DaylightDate.Hour == information.DaylightDate.Hour)) && ((timeZone.DaylightDate.Minute == information.DaylightDate.Minute) && (timeZone.DaylightDate.Second == information.DaylightDate.Second)))) && (timeZone.DaylightDate.Milliseconds == information.DaylightDate.Milliseconds));
if (flag)
{
string strA = key.GetValue("Std", string.Empty, RegistryValueOptions.None) as string;
flag = string.Compare(strA, timeZone.StandardName, StringComparison.Ordinal) == 0;
}
flag2 = flag;
}
}
finally
{
PermissionSet.RevertAssert();
}
return flag2;
}
private static bool TryCreateAdjustmentRules(string id, NativeMethods.RegistryTimeZoneInformation defaultTimeZoneInformation, out AdjustmentRule[] rules, out Exception e)
{
e = null;
try
{
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(string.Format(CultureInfo.InvariantCulture, @"{0}\{1}\Dynamic DST", new object[] { @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones", id }), RegistryKeyPermissionCheck.Default, RegistryRights.ExecuteKey))
{
if (key == null)
{
AdjustmentRule rule = CreateAdjustmentRuleFromTimeZoneInformation(defaultTimeZoneInformation, DateTime.MinValue.Date, DateTime.MaxValue.Date);
if (rule == null)
{
rules = null;
}
else
{
rules = new AdjustmentRule[] { rule };
}
return true;
}
int year = (int)key.GetValue("FirstEntry", -1, RegistryValueOptions.None);
int num2 = (int)key.GetValue("LastEntry", -1, RegistryValueOptions.None);
if (((year == -1) || (num2 == -1)) || (year > num2))
{
rules = null;
return false;
}
NativeMethods.RegistryTimeZoneInformation timeZoneInformation = new NativeMethods.RegistryTimeZoneInformation((byte[])key.GetValue(year.ToString(CultureInfo.InvariantCulture), null, RegistryValueOptions.None));
if (year == num2)
{
AdjustmentRule rule2 = CreateAdjustmentRuleFromTimeZoneInformation(timeZoneInformation, DateTime.MinValue.Date, DateTime.MaxValue.Date);
if (rule2 == null)
{
rules = null;
}
else
{
rules = new AdjustmentRule[] { rule2 };
}
return true;
}
List<AdjustmentRule> list = new List<AdjustmentRule>(1);
AdjustmentRule item = CreateAdjustmentRuleFromTimeZoneInformation(timeZoneInformation, DateTime.MinValue.Date, new DateTime(year, 12, 0x1f));
if (item != null)
{
list.Add(item);
}
for (int i = year + 1; i < num2; i++)
{
timeZoneInformation = new NativeMethods.RegistryTimeZoneInformation((byte[])key.GetValue(i.ToString(CultureInfo.InvariantCulture), null, RegistryValueOptions.None));
AdjustmentRule rule4 = CreateAdjustmentRuleFromTimeZoneInformation(timeZoneInformation, new DateTime(i, 1, 1), new DateTime(i, 12, 0x1f));
if (rule4 != null)
{
list.Add(rule4);
}
}
timeZoneInformation = new NativeMethods.RegistryTimeZoneInformation((byte[])key.GetValue(num2.ToString(CultureInfo.InvariantCulture), null, RegistryValueOptions.None));
AdjustmentRule rule5 = CreateAdjustmentRuleFromTimeZoneInformation(timeZoneInformation, new DateTime(num2, 1, 1), DateTime.MaxValue.Date);
if (rule5 != null)
{
list.Add(rule5);
}
rules = list.ToArray();
if ((rules != null) && (rules.Length == 0))
{
rules = null;
}
}
}
catch (InvalidCastException exception)
{
rules = null;
e = exception;
return false;
}
catch (ArgumentOutOfRangeException exception2)
{
rules = null;
e = exception2;
return false;
}
catch (ArgumentException exception3)
{
rules = null;
e = exception3;
return false;
}
return true;
}
[SecurityTreatAsSafe, SecurityCritical, FileIOPermission(SecurityAction.Assert, AllLocalFiles = FileIOPermissionAccess.PathDiscovery)]
private static string TryGetLocalizedNameByMuiNativeResource(string resource)
{
string str;
int num;
if (string.IsNullOrEmpty(resource))
{
return string.Empty;
}
string[] strArray = resource.Split(new char[] { ',' }, StringSplitOptions.None);
if (strArray.Length != 2)
{
return string.Empty;
}
string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.System);
string str3 = strArray[0].TrimStart(new char[] { '@' });
try
{
str = Path.Combine(folderPath, str3);
}
catch (ArgumentException)
{
return string.Empty;
}
if (!int.TryParse(strArray[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out num))
{
return string.Empty;
}
num = -num;
try
{
StringBuilder fileMuiPath = new StringBuilder(260);
fileMuiPath.Length = 260;
int fileMuiPathLength = 260;
int languageLength = 0;
long enumerator = 0L;
if (!UnsafeNativeMethods.GetFileMUIPath(0x10, str, null, ref languageLength, fileMuiPath, ref fileMuiPathLength, ref enumerator))
{
return string.Empty;
}
return TryGetLocalizedNameByNativeResource(fileMuiPath.ToString(), num);
}
catch (EntryPointNotFoundException)
{
return string.Empty;
}
}
[SecurityCritical]
private static string TryGetLocalizedNameByNativeResource(string filePath, int resource)
{
if (File.Exists(filePath))
{
using (SafeLibraryHandle handle = UnsafeNativeMethods.LoadLibraryEx(filePath, IntPtr.Zero, 2))
{
if (!handle.IsInvalid)
{
StringBuilder buffer = new StringBuilder(500);
buffer.Length = 500;
if (UnsafeNativeMethods.LoadString(handle, resource, buffer, buffer.Length) != 0)
{
return buffer.ToString();
}
}
}
}
return string.Empty;
}
private static bool TryGetLocalizedNamesByRegistryKey(RegistryKey key, out string displayName, out string standardName, out string daylightName)
{
displayName = string.Empty;
standardName = string.Empty;
daylightName = string.Empty;
string str = key.GetValue("MUI_Display", string.Empty, RegistryValueOptions.None) as string;
string str2 = key.GetValue("MUI_Std", string.Empty, RegistryValueOptions.None) as string;
string str3 = key.GetValue("MUI_Dlt", string.Empty, RegistryValueOptions.None) as string;
if (!string.IsNullOrEmpty(str))
{
displayName = TryGetLocalizedNameByMuiNativeResource(str);
}
if (!string.IsNullOrEmpty(str2))
{
standardName = TryGetLocalizedNameByMuiNativeResource(str2);
}
if (!string.IsNullOrEmpty(str3))
{
daylightName = TryGetLocalizedNameByMuiNativeResource(str3);
}
if (string.IsNullOrEmpty(displayName))
{
displayName = key.GetValue("Display", string.Empty, RegistryValueOptions.None) as string;
}
if (string.IsNullOrEmpty(standardName))
{
standardName = key.GetValue("Std", string.Empty, RegistryValueOptions.None) as string;
}
if (string.IsNullOrEmpty(daylightName))
{
daylightName = key.GetValue("Dlt", string.Empty, RegistryValueOptions.None) as string;
}
return true;
}
private static TimeZoneInfoResult TryGetTimeZone(string id, bool dstDisabled, out TimeZoneInfo value, out Exception e)
{
TimeZoneInfoResult success = TimeZoneInfoResult.Success;
e = null;
TimeZoneInfo info = null;
if (s_systemTimeZones.TryGetValue(id, out info))
{
if (dstDisabled && info.m_supportsDaylightSavingTime)
{
value = CreateCustomTimeZone(info.m_id, info.m_baseUtcOffset, info.m_displayName, info.m_standardDisplayName);
return success;
}
value = new TimeZoneInfo(info.m_id, info.m_baseUtcOffset, info.m_displayName, info.m_standardDisplayName, info.m_daylightDisplayName, info.m_adjustmentRules, false);
return success;
}
if (!s_allSystemTimeZonesRead)
{
success = TryGetTimeZoneByRegistryKey(id, out info, out e);
if (success == TimeZoneInfoResult.Success)
{
s_systemTimeZones.Add(id, info);
if (dstDisabled && info.m_supportsDaylightSavingTime)
{
value = CreateCustomTimeZone(info.m_id, info.m_baseUtcOffset, info.m_displayName, info.m_standardDisplayName);
return success;
}
value = new TimeZoneInfo(info.m_id, info.m_baseUtcOffset, info.m_displayName, info.m_standardDisplayName, info.m_daylightDisplayName, info.m_adjustmentRules, false);
return success;
}
value = null;
return success;
}
success = TimeZoneInfoResult.TimeZoneNotFoundException;
value = null;
return success;
}
[SecurityCritical, SecurityTreatAsSafe]
private static TimeZoneInfoResult TryGetTimeZoneByRegistryKey(string id, out TimeZoneInfo value, out Exception e)
{
TimeZoneInfoResult invalidTimeZoneException;
e = null;
try
{
PermissionSet set = new PermissionSet(PermissionState.None);
set.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"));
set.Assert();
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(string.Format(CultureInfo.InvariantCulture, @"{0}\{1}", new object[] { @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones", id }), RegistryKeyPermissionCheck.Default, RegistryRights.ExecuteKey))
{
NativeMethods.RegistryTimeZoneInformation information;
AdjustmentRule[] ruleArray;
string str;
string str2;
string str3;
if (key == null)
{
value = null;
return TimeZoneInfoResult.TimeZoneNotFoundException;
}
try
{
information = new NativeMethods.RegistryTimeZoneInformation((byte[])key.GetValue("TZI", null, RegistryValueOptions.None));
}
catch (InvalidCastException exception)
{
value = null;
e = exception;
return TimeZoneInfoResult.InvalidTimeZoneException;
}
catch (ArgumentException exception2)
{
value = null;
e = exception2;
return TimeZoneInfoResult.InvalidTimeZoneException;
}
if (!TryCreateAdjustmentRules(id, information, out ruleArray, out e))
{
value = null;
return TimeZoneInfoResult.InvalidTimeZoneException;
}
if (!TryGetLocalizedNamesByRegistryKey(key, out str, out str2, out str3))
{
value = null;
invalidTimeZoneException = TimeZoneInfoResult.InvalidTimeZoneException;
}
else
{
try
{
value = new TimeZoneInfo(id, new TimeSpan(0, -information.Bias, 0), str, str2, str3, ruleArray, false);
invalidTimeZoneException = TimeZoneInfoResult.Success;
}
catch (ArgumentException exception3)
{
value = null;
e = exception3;
invalidTimeZoneException = TimeZoneInfoResult.InvalidTimeZoneException;
}
catch (InvalidTimeZoneException exception4)
{
value = null;
e = exception4;
invalidTimeZoneException = TimeZoneInfoResult.InvalidTimeZoneException;
}
}
}
}
finally
{
PermissionSet.RevertAssert();
}
return invalidTimeZoneException;
}
internal static bool UtcOffsetOutOfRange(TimeSpan offset)
{
if (offset.TotalHours >= -14.0)
{
return (offset.TotalHours > 14.0);
}
return true;
}
private static void ValidateTimeZoneInfo(string id, TimeSpan baseUtcOffset, AdjustmentRule[] adjustmentRules, out bool adjustmentRulesSupportDst)
{
adjustmentRulesSupportDst = false;
if (id == null)
{
throw new ArgumentNullException("id");
}
if (id.Length == 0)
{
throw new ArgumentException("Argument_InvalidId , id");
}
if (UtcOffsetOutOfRange(baseUtcOffset))
{
throw new ArgumentOutOfRangeException("baseUtcOffset", "ArgumentOutOfRange_UtcOffset");
}
if ((baseUtcOffset.Ticks % 0x23c34600L) != 0L)
{
throw new ArgumentException("Argument_TimeSpanHasSeconds", "baseUtcOffset");
}
if ((adjustmentRules != null) && (adjustmentRules.Length != 0))
{
adjustmentRulesSupportDst = true;
AdjustmentRule rule = null;
AdjustmentRule rule2 = null;
for (int i = 0; i < adjustmentRules.Length; i++)
{
rule = rule2;
rule2 = adjustmentRules[i];
if (rule2 == null)
{
throw new InvalidTimeZoneException("Argument_AdjustmentRulesNoNulls");
}
if (UtcOffsetOutOfRange(baseUtcOffset + rule2.DaylightDelta))
{
throw new InvalidTimeZoneException("ArgumentOutOfRange_UtcOffsetAndDaylightDelta");
}
if ((rule != null) && (rule2.DateStart <= rule.DateEnd))
{
throw new InvalidTimeZoneException("Argument_AdjustmentRulesOutOfOrder");
}
}
}
}
// Properties
public TimeSpan BaseUtcOffset
{
get
{
return this.m_baseUtcOffset;
}
}
public string DaylightName
{
get
{
if (this.m_daylightDisplayName != null)
{
return this.m_daylightDisplayName;
}
return string.Empty;
}
}
public string DisplayName
{
get
{
if (this.m_displayName != null)
{
return this.m_displayName;
}
return string.Empty;
}
}
public string Id
{
get
{
return this.m_id;
}
}
public static TimeZoneInfo Local
{
[SecurityCritical]
get
{
TimeZoneInfo info = s_localTimeZone;
if (info != null)
{
return info;
}
lock (s_internalSyncObject)
{
if (s_localTimeZone == null)
{
TimeZoneInfo localTimeZone = GetLocalTimeZone();
s_localTimeZone = new TimeZoneInfo(localTimeZone.m_id, localTimeZone.m_baseUtcOffset, localTimeZone.m_displayName, localTimeZone.m_standardDisplayName, localTimeZone.m_daylightDisplayName, localTimeZone.m_adjustmentRules, false);
}
return s_localTimeZone;
}
}
}
private static object s_internalSyncObject
{
get
{
if (s_hiddenInternalSyncObject == null)
{
object obj2 = new object();
System.Threading.Interlocked.CompareExchange(ref s_hiddenInternalSyncObject, obj2, null);
}
return s_hiddenInternalSyncObject;
}
}
private static Dictionary<string, TimeZoneInfo> s_systemTimeZones
{
get
{
if (s_hiddenSystemTimeZones == null)
{
s_hiddenSystemTimeZones = new Dictionary<string, TimeZoneInfo>();
}
return s_hiddenSystemTimeZones;
}
set
{
s_hiddenSystemTimeZones = value;
}
}
public string StandardName
{
get
{
if (this.m_standardDisplayName != null)
{
return this.m_standardDisplayName;
}
return string.Empty;
}
}
public bool SupportsDaylightSavingTime
{
get
{
return this.m_supportsDaylightSavingTime;
}
}
public static TimeZoneInfo Utc
{
get
{
TimeZoneInfo info = s_utcTimeZone;
if (info != null)
{
return info;
}
lock (s_internalSyncObject)
{
if (s_utcTimeZone == null)
{
s_utcTimeZone = CreateCustomTimeZone("UTC", TimeSpan.Zero, "UTC", "UTC");
}
return s_utcTimeZone;
}
}
}
// Nested Types
[Serializable, HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true), HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)]
public sealed class AdjustmentRule : IEquatable<TimeZoneInfo.AdjustmentRule>, ISerializable, IDeserializationCallback
{
// Fields
private DateTime m_dateEnd;
private DateTime m_dateStart;
private TimeSpan m_daylightDelta;
private TimeZoneInfo.TransitionTime m_daylightTransitionEnd;
private TimeZoneInfo.TransitionTime m_daylightTransitionStart;
// Methods
private AdjustmentRule()
{
}
private AdjustmentRule(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new ArgumentNullException("info");
}
this.m_dateStart = (DateTime)info.GetValue("DateStart", typeof(DateTime));
this.m_dateEnd = (DateTime)info.GetValue("DateEnd", typeof(DateTime));
this.m_daylightDelta = (TimeSpan)info.GetValue("DaylightDelta", typeof(TimeSpan));
this.m_daylightTransitionStart = (TimeZoneInfo.TransitionTime)info.GetValue("DaylightTransitionStart", typeof(TimeZoneInfo.TransitionTime));
this.m_daylightTransitionEnd = (TimeZoneInfo.TransitionTime)info.GetValue("DaylightTransitionEnd", typeof(TimeZoneInfo.TransitionTime));
}
public static TimeZoneInfo.AdjustmentRule CreateAdjustmentRule(DateTime dateStart, DateTime dateEnd, TimeSpan daylightDelta, TimeZoneInfo.TransitionTime daylightTransitionStart, TimeZoneInfo.TransitionTime daylightTransitionEnd)
{
ValidateAdjustmentRule(dateStart, dateEnd, daylightDelta, daylightTransitionStart, daylightTransitionEnd);
TimeZoneInfo.AdjustmentRule rule = new TimeZoneInfo.AdjustmentRule();
rule.m_dateStart = dateStart;
rule.m_dateEnd = dateEnd;
rule.m_daylightDelta = daylightDelta;
rule.m_daylightTransitionStart = daylightTransitionStart;
rule.m_daylightTransitionEnd = daylightTransitionEnd;
return rule;
}
public bool Equals(TimeZoneInfo.AdjustmentRule other)
{
return ((((((other != null) && (this.m_dateStart == other.m_dateStart)) && (this.m_dateEnd == other.m_dateEnd)) && (this.m_daylightDelta == other.m_daylightDelta)) && this.m_daylightTransitionEnd.Equals(other.m_daylightTransitionEnd)) && this.m_daylightTransitionStart.Equals(other.m_daylightTransitionStart));
}
public override int GetHashCode()
{
return this.m_dateStart.GetHashCode();
}
void IDeserializationCallback.OnDeserialization(object sender)
{
try
{
ValidateAdjustmentRule(this.m_dateStart, this.m_dateEnd, this.m_daylightDelta, this.m_daylightTransitionStart, this.m_daylightTransitionEnd);
}
catch (ArgumentException exception)
{
throw new SerializationException("Serialization_InvalidData", exception);
}
}
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new ArgumentNullException("info");
}
info.AddValue("DateStart", this.m_dateStart);
info.AddValue("DateEnd", this.m_dateEnd);
info.AddValue("DaylightDelta", this.m_daylightDelta);
info.AddValue("DaylightTransitionStart", this.m_daylightTransitionStart);
info.AddValue("DaylightTransitionEnd", this.m_daylightTransitionEnd);
}
private static void ValidateAdjustmentRule(DateTime dateStart, DateTime dateEnd, TimeSpan daylightDelta, TimeZoneInfo.TransitionTime daylightTransitionStart, TimeZoneInfo.TransitionTime daylightTransitionEnd)
{
if (dateStart.Kind != DateTimeKind.Unspecified)
{
throw new ArgumentException("Argument_DateTimeKindMustBeUnspecified", "dateStart");
}
if (dateEnd.Kind != DateTimeKind.Unspecified)
{
throw new ArgumentException("Argument_DateTimeKindMustBeUnspecified", "dateEnd");
}
if (daylightTransitionStart.Equals(daylightTransitionEnd))
{
throw new ArgumentException("Argument_TransitionTimesAreIdentical", "daylightTransitionEnd");
}
if (dateStart > dateEnd)
{
throw new ArgumentException("Argument_OutOfOrderDateTimes", "dateStart");
}
if (TimeZoneInfo.UtcOffsetOutOfRange(daylightDelta))
{
throw new ArgumentOutOfRangeException("daylightDelta", daylightDelta, "ArgumentOutOfRange_UtcOffset");
}
if ((daylightDelta.Ticks % 0x23c34600L) != 0L)
{
throw new ArgumentException("Argument_TimeSpanHasSeconds", "daylightDelta");
}
if (dateStart.TimeOfDay != TimeSpan.Zero)
{
throw new ArgumentException("Argument_DateTimeHasTimeOfDay", "dateStart");
}
if (dateEnd.TimeOfDay != TimeSpan.Zero)
{
throw new ArgumentException("Argument_DateTimeHasTimeOfDay", "dateEnd");
}
}
// Properties
public DateTime DateEnd
{
get
{
return this.m_dateEnd;
}
}
public DateTime DateStart
{
get
{
return this.m_dateStart;
}
}
public TimeSpan DaylightDelta
{
get
{
return this.m_daylightDelta;
}
}
public TimeZoneInfo.TransitionTime DaylightTransitionEnd
{
get
{
return this.m_daylightTransitionEnd;
}
}
public TimeZoneInfo.TransitionTime DaylightTransitionStart
{
get
{
return this.m_daylightTransitionStart;
}
}
}
private sealed class StringSerializer
{
// Fields
private const string dateTimeFormat = "MM:dd:yyyy";
private const char esc = '\\';
private const string escapedEsc = @"\\";
private const string escapedLhs = @"\[";
private const string escapedRhs = @"\]";
private const string escapedSep = @"\;";
private const string escString = @"\";
private const int initialCapacityForString = 0x40;
private const char lhs = '[';
private const string lhsString = "[";
private int m_currentTokenStartIndex;
private string m_serializedText;
private State m_state;
private const char rhs = ']';
private const string rhsString = "]";
private const char sep = ';';
private const string sepString = ";";
private const string timeOfDayFormat = "HH:mm:ss.FFF";
// Methods
private StringSerializer(string str)
{
this.m_serializedText = str;
this.m_state = State.StartOfToken;
}
public static TimeZoneInfo GetDeserializedTimeZoneInfo(string source)
{
TimeZoneInfo info;
TimeZoneInfo.StringSerializer serializer = new TimeZoneInfo.StringSerializer(source);
string nextStringValue = serializer.GetNextStringValue(false);
TimeSpan nextTimeSpanValue = serializer.GetNextTimeSpanValue(false);
string displayName = serializer.GetNextStringValue(false);
string standardDisplayName = serializer.GetNextStringValue(false);
string daylightDisplayName = serializer.GetNextStringValue(false);
TimeZoneInfo.AdjustmentRule[] nextAdjustmentRuleArrayValue = serializer.GetNextAdjustmentRuleArrayValue(false);
try
{
info = TimeZoneInfo.CreateCustomTimeZone(nextStringValue, nextTimeSpanValue, displayName, standardDisplayName, daylightDisplayName, nextAdjustmentRuleArrayValue);
}
catch (ArgumentException exception)
{
throw new SerializationException("Serialization_InvalidData", exception);
}
catch (InvalidTimeZoneException exception2)
{
throw new SerializationException("Serialization_InvalidData", exception2);
}
return info;
}
private TimeZoneInfo.AdjustmentRule[] GetNextAdjustmentRuleArrayValue(bool canEndWithoutSeparator)
{
List<TimeZoneInfo.AdjustmentRule> list = new List<TimeZoneInfo.AdjustmentRule>(1);
int num = 0;
for (TimeZoneInfo.AdjustmentRule rule = this.GetNextAdjustmentRuleValue(true); rule != null; rule = this.GetNextAdjustmentRuleValue(true))
{
list.Add(rule);
num++;
}
if (!canEndWithoutSeparator)
{
if (this.m_state == State.EndOfLine)
{
throw new SerializationException("Serialization_InvalidData");
}
if ((this.m_currentTokenStartIndex < 0) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length))
{
throw new SerializationException("Serialization_InvalidData");
}
}
if (num == 0)
{
return null;
}
return list.ToArray();
}
private TimeZoneInfo.AdjustmentRule GetNextAdjustmentRuleValue(bool canEndWithoutSeparator)
{
TimeZoneInfo.AdjustmentRule rule;
if (this.m_state == State.EndOfLine)
{
if (!canEndWithoutSeparator)
{
throw new SerializationException("Serialization_InvalidData");
}
return null;
}
if ((this.m_currentTokenStartIndex < 0) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length))
{
throw new SerializationException("Serialization_InvalidData");
}
if (this.m_serializedText[this.m_currentTokenStartIndex] == ';')
{
return null;
}
if (this.m_serializedText[this.m_currentTokenStartIndex] != '[')
{
throw new SerializationException("Serialization_InvalidData");
}
this.m_currentTokenStartIndex++;
DateTime nextDateTimeValue = this.GetNextDateTimeValue(false, "MM:dd:yyyy");
DateTime dateEnd = this.GetNextDateTimeValue(false, "MM:dd:yyyy");
TimeSpan nextTimeSpanValue = this.GetNextTimeSpanValue(false);
TimeZoneInfo.TransitionTime nextTransitionTimeValue = this.GetNextTransitionTimeValue(false);
TimeZoneInfo.TransitionTime daylightTransitionEnd = this.GetNextTransitionTimeValue(false);
if ((this.m_state == State.EndOfLine) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length))
{
throw new SerializationException("Serialization_InvalidData");
}
if (this.m_serializedText[this.m_currentTokenStartIndex] != ']')
{
this.SkipVersionNextDataFields(1);
}
else
{
this.m_currentTokenStartIndex++;
}
try
{
rule = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(nextDateTimeValue, dateEnd, nextTimeSpanValue, nextTransitionTimeValue, daylightTransitionEnd);
}
catch (ArgumentException exception)
{
throw new SerializationException("Serialization_InvalidData", exception);
}
if (this.m_currentTokenStartIndex >= this.m_serializedText.Length)
{
this.m_state = State.EndOfLine;
return rule;
}
this.m_state = State.StartOfToken;
return rule;
}
private DateTime GetNextDateTimeValue(bool canEndWithoutSeparator, string format)
{
DateTime time;
if (!DateTime.TryParseExact(this.GetNextStringValue(canEndWithoutSeparator), format, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out time))
{
throw new SerializationException("Serialization_InvalidData");
}
return time;
}
private int GetNextInt32Value(bool canEndWithoutSeparator)
{
int num;
if (!int.TryParse(this.GetNextStringValue(canEndWithoutSeparator), NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out num))
{
throw new SerializationException("Serialization_InvalidData");
}
return num;
}
private string GetNextStringValue(bool canEndWithoutSeparator)
{
if (this.m_state == State.EndOfLine)
{
if (!canEndWithoutSeparator)
{
throw new SerializationException("Serialization_InvalidData");
}
return null;
}
if ((this.m_currentTokenStartIndex < 0) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length))
{
throw new SerializationException("Serialization_InvalidData");
}
State notEscaped = State.NotEscaped;
StringBuilder builder = new StringBuilder(0x40);
for (int i = this.m_currentTokenStartIndex; i < this.m_serializedText.Length; i++)
{
if (notEscaped == State.Escaped)
{
VerifyIsEscapableCharacter(this.m_serializedText[i]);
builder.Append(this.m_serializedText[i]);
notEscaped = State.NotEscaped;
}
else if (notEscaped == State.NotEscaped)
{
switch (this.m_serializedText[i])
{
case '[':
throw new SerializationException("Serialization_InvalidData");
case '\\':
notEscaped = State.Escaped;
break;
case ']':
if (!canEndWithoutSeparator)
{
throw new SerializationException("Serialization_InvalidData");
}
this.m_currentTokenStartIndex = i;
this.m_state = State.StartOfToken;
return builder.ToString();
case ';':
this.m_currentTokenStartIndex = i + 1;
if (this.m_currentTokenStartIndex >= this.m_serializedText.Length)
{
this.m_state = State.EndOfLine;
}
else
{
this.m_state = State.StartOfToken;
}
return builder.ToString();
case '\0':
throw new SerializationException("Serialization_InvalidData");
default:
builder.Append(this.m_serializedText[i]);
break;
}
}
}
if (notEscaped == State.Escaped)
{
throw new SerializationException("Serialization_InvalidEscapeSequence");
}
if (!canEndWithoutSeparator)
{
throw new SerializationException("Serialization_InvalidData");
}
this.m_currentTokenStartIndex = this.m_serializedText.Length;
this.m_state = State.EndOfLine;
return builder.ToString();
}
private TimeSpan GetNextTimeSpanValue(bool canEndWithoutSeparator)
{
TimeSpan span;
int minutes = this.GetNextInt32Value(canEndWithoutSeparator);
try
{
span = new TimeSpan(0, minutes, 0);
}
catch (ArgumentOutOfRangeException exception)
{
throw new SerializationException("Serialization_InvalidData", exception);
}
return span;
}
private TimeZoneInfo.TransitionTime GetNextTransitionTimeValue(bool canEndWithoutSeparator)
{
TimeZoneInfo.TransitionTime time;
if ((this.m_state == State.EndOfLine) || ((this.m_currentTokenStartIndex < this.m_serializedText.Length) && (this.m_serializedText[this.m_currentTokenStartIndex] == ']')))
{
throw new SerializationException("Serialization_InvalidData");
}
if ((this.m_currentTokenStartIndex < 0) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length))
{
throw new SerializationException("Serialization_InvalidData");
}
if (this.m_serializedText[this.m_currentTokenStartIndex] != '[')
{
throw new SerializationException("Serialization_InvalidData");
}
this.m_currentTokenStartIndex++;
int num = this.GetNextInt32Value(false);
if ((num != 0) && (num != 1))
{
throw new SerializationException("Serialization_InvalidData");
}
DateTime nextDateTimeValue = this.GetNextDateTimeValue(false, "HH:mm:ss.FFF");
nextDateTimeValue = new DateTime(1, 1, 1, nextDateTimeValue.Hour, nextDateTimeValue.Minute, nextDateTimeValue.Second, nextDateTimeValue.Millisecond);
int month = this.GetNextInt32Value(false);
if (num == 1)
{
int day = this.GetNextInt32Value(false);
try
{
time = TimeZoneInfo.TransitionTime.CreateFixedDateRule(nextDateTimeValue, month, day);
goto Label_015B;
}
catch (ArgumentException exception)
{
throw new SerializationException("Serialization_InvalidData", exception);
}
}
int week = this.GetNextInt32Value(false);
int num5 = this.GetNextInt32Value(false);
try
{
time = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(nextDateTimeValue, month, week, (DayOfWeek)num5);
}
catch (ArgumentException exception2)
{
throw new SerializationException("Serialization_InvalidData", exception2);
}
Label_015B:
if ((this.m_state == State.EndOfLine) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length))
{
throw new SerializationException("Serialization_InvalidData");
}
if (this.m_serializedText[this.m_currentTokenStartIndex] != ']')
{
this.SkipVersionNextDataFields(1);
}
else
{
this.m_currentTokenStartIndex++;
}
bool flag = false;
if ((this.m_currentTokenStartIndex < this.m_serializedText.Length) && (this.m_serializedText[this.m_currentTokenStartIndex] == ';'))
{
this.m_currentTokenStartIndex++;
flag = true;
}
if (!flag && !canEndWithoutSeparator)
{
throw new SerializationException("Serialization_InvalidData");
}
if (this.m_currentTokenStartIndex >= this.m_serializedText.Length)
{
this.m_state = State.EndOfLine;
return time;
}
this.m_state = State.StartOfToken;
return time;
}
public static string GetSerializedString(TimeZoneInfo zone)
{
StringBuilder serializedText = new StringBuilder();
serializedText.Append(SerializeSubstitute(zone.Id));
serializedText.Append(';');
serializedText.Append(SerializeSubstitute(zone.BaseUtcOffset.TotalMinutes.ToString(CultureInfo.InvariantCulture)));
serializedText.Append(';');
serializedText.Append(SerializeSubstitute(zone.DisplayName));
serializedText.Append(';');
serializedText.Append(SerializeSubstitute(zone.StandardName));
serializedText.Append(';');
serializedText.Append(SerializeSubstitute(zone.DaylightName));
serializedText.Append(';');
TimeZoneInfo.AdjustmentRule[] adjustmentRules = zone.GetAdjustmentRules();
if ((adjustmentRules != null) && (adjustmentRules.Length > 0))
{
for (int i = 0; i < adjustmentRules.Length; i++)
{
TimeZoneInfo.AdjustmentRule rule = adjustmentRules[i];
serializedText.Append('[');
serializedText.Append(SerializeSubstitute(rule.DateStart.ToString("MM:dd:yyyy", DateTimeFormatInfo.InvariantInfo)));
serializedText.Append(';');
serializedText.Append(SerializeSubstitute(rule.DateEnd.ToString("MM:dd:yyyy", DateTimeFormatInfo.InvariantInfo)));
serializedText.Append(';');
serializedText.Append(SerializeSubstitute(rule.DaylightDelta.TotalMinutes.ToString(CultureInfo.InvariantCulture)));
serializedText.Append(';');
SerializeTransitionTime(rule.DaylightTransitionStart, serializedText);
serializedText.Append(';');
SerializeTransitionTime(rule.DaylightTransitionEnd, serializedText);
serializedText.Append(';');
serializedText.Append(']');
}
}
serializedText.Append(';');
return serializedText.ToString();
}
private static string SerializeSubstitute(string text)
{
text = text.Replace(@"\", @"\\");
text = text.Replace("[", @"\[");
text = text.Replace("]", @"\]");
return text.Replace(";", @"\;");
}
private static void SerializeTransitionTime(TimeZoneInfo.TransitionTime time, StringBuilder serializedText)
{
serializedText.Append('[');
serializedText.Append((time.IsFixedDateRule ? 1 : 0).ToString(CultureInfo.InvariantCulture));
serializedText.Append(';');
if (time.IsFixedDateRule)
{
serializedText.Append(SerializeSubstitute(time.TimeOfDay.ToString("HH:mm:ss.FFF", DateTimeFormatInfo.InvariantInfo)));
serializedText.Append(';');
serializedText.Append(SerializeSubstitute(time.Month.ToString(CultureInfo.InvariantCulture)));
serializedText.Append(';');
serializedText.Append(SerializeSubstitute(time.Day.ToString(CultureInfo.InvariantCulture)));
serializedText.Append(';');
}
else
{
serializedText.Append(SerializeSubstitute(time.TimeOfDay.ToString("HH:mm:ss.FFF", DateTimeFormatInfo.InvariantInfo)));
serializedText.Append(';');
serializedText.Append(SerializeSubstitute(time.Month.ToString(CultureInfo.InvariantCulture)));
serializedText.Append(';');
serializedText.Append(SerializeSubstitute(time.Week.ToString(CultureInfo.InvariantCulture)));
serializedText.Append(';');
serializedText.Append(SerializeSubstitute(((int)time.DayOfWeek).ToString(CultureInfo.InvariantCulture)));
serializedText.Append(';');
}
serializedText.Append(']');
}
private void SkipVersionNextDataFields(int depth)
{
if ((this.m_currentTokenStartIndex < 0) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length))
{
throw new SerializationException("Serialization_InvalidData");
}
State notEscaped = State.NotEscaped;
for (int i = this.m_currentTokenStartIndex; i < this.m_serializedText.Length; i++)
{
switch (notEscaped)
{
case State.Escaped:
{
VerifyIsEscapableCharacter(this.m_serializedText[i]);
notEscaped = State.NotEscaped;
continue;
}
case State.NotEscaped:
switch (this.m_serializedText[i])
{
case '[':
{
depth++;
continue;
}
case '\\':
{
notEscaped = State.Escaped;
continue;
}
case ']':
depth--;
if (depth != 0)
{
continue;
}
this.m_currentTokenStartIndex = i + 1;
if (this.m_currentTokenStartIndex < this.m_serializedText.Length)
{
goto Label_00B5;
}
this.m_state = State.EndOfLine;
return;
case '\0':
throw new SerializationException("Serialization_InvalidData");
}
break;
}
continue;
Label_00B5:
this.m_state = State.StartOfToken;
return;
}
throw new SerializationException("Serialization_InvalidData");
}
private static void VerifyIsEscapableCharacter(char c)
{
if (((c != '\\') && (c != ';')) && ((c != '[') && (c != ']')))
{
throw new SerializationException("Serialization_InvalidEscapeSequence " + c.ToString());
}
}
// Nested Types
private enum State
{
Escaped,
NotEscaped,
StartOfToken,
EndOfLine
}
}
private class TimeZoneInfoComparer : IComparer<TimeZoneInfo>
{
// Methods
int IComparer<TimeZoneInfo>.Compare(TimeZoneInfo x, TimeZoneInfo y)
{
return DevComponents.AdvTree.Utilities.CompareAlphaNumeric(x.Id, y.Id);
}
}
private enum TimeZoneInfoResult
{
Success,
TimeZoneNotFoundException,
InvalidTimeZoneException,
SecurityException
}
[Serializable, StructLayout(LayoutKind.Sequential), HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true), HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)]
public struct TransitionTime : IEquatable<TimeZoneInfo.TransitionTime>, ISerializable, IDeserializationCallback
{
private DateTime m_timeOfDay;
private byte m_month;
private byte m_week;
private byte m_day;
private DayOfWeek m_dayOfWeek;
private bool m_isFixedDateRule;
public DateTime TimeOfDay
{
get
{
return this.m_timeOfDay;
}
}
public int Month
{
get
{
return this.m_month;
}
}
public int Week
{
get
{
return this.m_week;
}
}
public int Day
{
get
{
return this.m_day;
}
}
public DayOfWeek DayOfWeek
{
get
{
return this.m_dayOfWeek;
}
}
public bool IsFixedDateRule
{
get
{
return this.m_isFixedDateRule;
}
}
public override bool Equals(object obj)
{
return ((obj is TimeZoneInfo.TransitionTime) && this.Equals((TimeZoneInfo.TransitionTime)obj));
}
public static bool operator ==(TimeZoneInfo.TransitionTime left, TimeZoneInfo.TransitionTime right)
{
return left.Equals(right);
}
public static bool operator !=(TimeZoneInfo.TransitionTime left, TimeZoneInfo.TransitionTime right)
{
return !left.Equals(right);
}
public bool Equals(TimeZoneInfo.TransitionTime other)
{
bool flag = ((this.m_isFixedDateRule == other.m_isFixedDateRule) && (this.m_timeOfDay == other.m_timeOfDay)) && (this.m_month == other.m_month);
if (!flag)
{
return flag;
}
if (other.m_isFixedDateRule)
{
return (this.m_day == other.m_day);
}
return ((this.m_week == other.m_week) && (this.m_dayOfWeek == other.m_dayOfWeek));
}
public override int GetHashCode()
{
return (this.m_month ^ (this.m_week << 8));
}
public static TimeZoneInfo.TransitionTime CreateFixedDateRule(DateTime timeOfDay, int month, int day)
{
return CreateTransitionTime(timeOfDay, month, 1, day, DayOfWeek.Sunday, true);
}
public static TimeZoneInfo.TransitionTime CreateFloatingDateRule(DateTime timeOfDay, int month, int week, DayOfWeek dayOfWeek)
{
return CreateTransitionTime(timeOfDay, month, week, 1, dayOfWeek, false);
}
private static TimeZoneInfo.TransitionTime CreateTransitionTime(DateTime timeOfDay, int month, int week, int day, DayOfWeek dayOfWeek, bool isFixedDateRule)
{
ValidateTransitionTime(timeOfDay, month, week, day, dayOfWeek);
TimeZoneInfo.TransitionTime time = new TimeZoneInfo.TransitionTime();
time.m_isFixedDateRule = isFixedDateRule;
time.m_timeOfDay = timeOfDay;
time.m_dayOfWeek = dayOfWeek;
time.m_day = (byte)day;
time.m_week = (byte)week;
time.m_month = (byte)month;
return time;
}
private static void ValidateTransitionTime(DateTime timeOfDay, int month, int week, int day, DayOfWeek dayOfWeek)
{
if (timeOfDay.Kind != DateTimeKind.Unspecified)
{
throw new ArgumentException("Argument_DateTimeKindMustBeUnspecified", "timeOfDay");
}
if ((month < 1) || (month > 12))
{
throw new ArgumentOutOfRangeException("month", "ArgumentOutOfRange_Month");
}
if ((day < 1) || (day > 0x1f))
{
throw new ArgumentOutOfRangeException("day", "ArgumentOutOfRange_Day");
}
if ((week < 1) || (week > 5))
{
throw new ArgumentOutOfRangeException("week", "ArgumentOutOfRange_Week");
}
if ((dayOfWeek < DayOfWeek.Sunday) || (dayOfWeek > DayOfWeek.Saturday))
{
throw new ArgumentOutOfRangeException("dayOfWeek", "ArgumentOutOfRange_DayOfWeek");
}
if (((timeOfDay.Year != 1) || (timeOfDay.Month != 1)) || ((timeOfDay.Day != 1) || ((timeOfDay.Ticks % 0x2710L) != 0L)))
{
throw new ArgumentException("Argument_DateTimeHasTicks", "timeOfDay");
}
}
void IDeserializationCallback.OnDeserialization(object sender)
{
try
{
ValidateTransitionTime(this.m_timeOfDay, this.m_month, this.m_week, this.m_day, this.m_dayOfWeek);
}
catch (ArgumentException exception)
{
throw new SerializationException("Serialization_InvalidData", exception);
}
}
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new ArgumentNullException("info");
}
info.AddValue("TimeOfDay", this.m_timeOfDay);
info.AddValue("Month", this.m_month);
info.AddValue("Week", this.m_week);
info.AddValue("Day", this.m_day);
info.AddValue("RelativeDayOfWeek", this.m_dayOfWeek);
info.AddValue("IsFixedDateRule", this.m_isFixedDateRule);
}
private TransitionTime(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new ArgumentNullException("info");
}
this.m_timeOfDay = (DateTime)info.GetValue("TimeOfDay", typeof(DateTime));
this.m_month = (byte)info.GetValue("Month", typeof(byte));
this.m_week = (byte)info.GetValue("Week", typeof(byte));
this.m_day = (byte)info.GetValue("Day", typeof(byte));
this.m_dayOfWeek = (DayOfWeek)info.GetValue("RelativeDayOfWeek", typeof(DayOfWeek));
this.m_isFixedDateRule = (bool)info.GetValue("IsFixedDateRule", typeof(bool));
}
}
}
[Flags]
internal enum TimeZoneInfoOptions
{
None = 1,
NoThrowOnInvalidTime = 2
}
[Serializable, HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)]
public class InvalidTimeZoneException : Exception
{
// Methods
public InvalidTimeZoneException()
{
}
public InvalidTimeZoneException(string message)
: base(message)
{
}
protected InvalidTimeZoneException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
public InvalidTimeZoneException(string message, Exception innerException)
: base(message, innerException)
{
}
}
[Serializable, HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)]
public class TimeZoneNotFoundException : Exception
{
// Methods
public TimeZoneNotFoundException()
{
}
public TimeZoneNotFoundException(string message)
: base(message)
{
}
protected TimeZoneNotFoundException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
public TimeZoneNotFoundException(string message, Exception innerException)
: base(message, innerException)
{
}
}
[SuppressUnmanagedCodeSecurity, HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)]
internal sealed class SafeLibraryHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
{
// Methods
internal SafeLibraryHandle()
: base(true)
{
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
private static extern bool FreeLibrary(IntPtr hModule);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern SafeLibraryHandle LoadLibraryEx(string libFilename, IntPtr reserved, int flags);
protected override bool ReleaseHandle()
{
return FreeLibrary(base.handle);
}
}
}
#endif