try {
ret = readlink (path, buf, buf.Length);
- } catch (DllNotFoundException e) {
+ } catch (DllNotFoundException) {
readlinkNotFound = true;
return null;
- } catch (EntryPointNotFoundException e) {
+ } catch (EntryPointNotFoundException) {
readlinkNotFound = true;
return null;
}
return true;
}
-#if !MOBILE || MOBILE_STATIC
+#if !MONODROID && !MONOTOUCH && !XAMMAC
static TimeZoneInfo CreateLocal ()
{
-#if !MOBILE_STATIC
+#if WIN_PLATFORM
if (IsWindows && LocalZoneKey != null) {
string name = (string)LocalZoneKey.GetValue ("TimeZoneKeyName");
if (name == null)
name = TrimSpecial (name);
if (name != null)
return TimeZoneInfo.FindSystemTimeZoneById (name);
+ } else if (IsWindows) {
+ return GetLocalTimeZoneInfoWinRTFallback ();
}
#endif
static void GetSystemTimeZonesCore (List<TimeZoneInfo> systemTimeZones)
{
-#if !MOBILE_STATIC
+#if WIN_PLATFORM
if (TimeZoneKey != null) {
foreach (string id in TimeZoneKey.GetSubKeyNames ()) {
try {
} catch {}
}
+ return;
+ } else if (IsWindows) {
+ systemTimeZones.AddRange (GetSystemTimeZonesWinRTFallback ());
return;
}
#endif
throw new NotImplementedException ("This method is not implemented for this platform");
#endif
}
-#endif
+#endif // !MONODROID && !MONOTOUCH && !XAMMAC
string standardDisplayName;
public string StandardName {
#endif
private AdjustmentRule [] adjustmentRules;
-#if !MOBILE || MOBILE_STATIC
+#if (!MOBILE || !FULL_AOT_DESKTOP || WIN_PLATFORM) && !XAMMAC_4_5
/// <summary>
/// Determine whether windows of not (taken Stephane Delcroix's code)
/// </summary>
return str.Substring (Istart, Iend-Istart+1);
}
-
-#if !MOBILE_STATIC
+
+#if !FULL_AOT_DESKTOP || WIN_PLATFORM
static RegistryKey timeZoneKey;
static RegistryKey TimeZoneKey {
get {
if (!IsWindows)
return null;
- return timeZoneKey = Registry.LocalMachine.OpenSubKey (
- "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
- false);
+ try {
+ return timeZoneKey = Registry.LocalMachine.OpenSubKey (
+ "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones",
+ false);
+ } catch {
+ return null;
+ }
}
}
if (!IsWindows)
return null;
- return localZoneKey = Registry.LocalMachine.OpenSubKey (
- "SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation", false);
+ try {
+ return localZoneKey = Registry.LocalMachine.OpenSubKey (
+ "SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation", false);
+ } catch {
+ return null;
+ }
}
}
#endif
-#endif
+#endif // !MOBILE || !FULL_AOT_DESKTOP || WIN_PLATFORM
private static bool TryAddTicks (DateTime date, long ticks, out DateTime result, DateTimeKind kind = DateTimeKind.Unspecified)
{
//FIXME: this method should check for cached values in systemTimeZones
if (id == null)
throw new ArgumentNullException ("id");
-#if !MOBILE
+#if WIN_PLATFORM
if (TimeZoneKey != null)
{
if (id == "Coordinated Universal Time")
if (key == null)
throw new TimeZoneNotFoundException ();
return FromRegistryKey(id, key);
+ } else if (IsWindows) {
+ return FindSystemTimeZoneByIdWinRTFallback (id);
}
#endif
// Local requires special logic that already exists in the Local property (bug #326)
#if LIBC
private static TimeZoneInfo FindSystemTimeZoneByFileName (string id, string filepath)
{
- if (!File.Exists (filepath))
- throw new TimeZoneNotFoundException ();
-
- using (FileStream stream = File.OpenRead (filepath)) {
+ FileStream stream = null;
+ try {
+ stream = File.OpenRead (filepath);
+ } catch (Exception ex) {
+ throw new TimeZoneNotFoundException ("Couldn't read time zone file " + filepath, ex);
+ }
+ try {
return BuildFromStream (id, stream);
+ } finally {
+ if (stream != null)
+ stream.Dispose();
}
}
#endif
-#if !MOBILE
+#if WIN_PLATFORM
private static TimeZoneInfo FromRegistryKey (string id, RegistryKey key)
{
byte [] reg_tzi = (byte []) key.GetValue ("TZI");
else
ParseRegTzi(adjustmentRules, 1, 9999, reg_tzi);
- return CreateCustomTimeZone (id, baseUtcOffset, display_name, standard_name, daylight_name, ValidateRules (adjustmentRules).ToArray ());
+ return CreateCustomTimeZone (id, baseUtcOffset, display_name, standard_name, daylight_name, ValidateRules (adjustmentRules));
}
private static void ParseRegTzi (List<AdjustmentRule> adjustmentRules, int start_year, int end_year, byte [] buffer)
return tz.BaseUtcOffset;
}
- if (tzRule != null && tz.IsInDST (tzRule, stdUtcDateTime)) {
+ if (tzRule != null && tz.IsInDST (tzRule, dateTime)) {
// Replicate what .NET does when given a time which falls into the hour which is lost when
// DST starts. isDST should always be true but the offset should be BaseUtcOffset without the
// DST delta while in that hour.
AdjustmentRule rule = GetApplicableRule (dateTime);
if (rule != null) {
DateTime tpoint = TransitionPoint (rule.DaylightTransitionEnd, dateTime.Year);
- if (dateTime > tpoint - rule.DaylightDelta && dateTime <= tpoint)
+ if (dateTime > tpoint - rule.DaylightDelta && dateTime <= tpoint)
return true;
}
DST_start -= BaseUtcOffset;
DST_end -= (BaseUtcOffset + rule.DaylightDelta);
}
-
return (dateTime >= DST_start && dateTime < DST_end);
}
} else {
AdjustmentRule first = null, last = null;
+ // Rule start/end dates are either very specific or very broad depending on the platform
+ // 2015-10-04..2016-04-03 - Rule for a time zone in southern hemisphere on non-Windows platforms
+ // 2016-03-27..2016-10-03 - Rule for a time zone in northern hemisphere on non-Windows platforms
+ // 0001-01-01..9999-12-31 - Rule for a time zone on Windows
+
foreach (var rule in GetAdjustmentRules ()) {
- if (rule.DateStart.Year != year && rule.DateEnd.Year != year)
+ if (rule.DateStart.Year > year || rule.DateEnd.Year < year)
continue;
- if (rule.DateStart.Year == year)
+ if (rule.DateStart.Year <= year && (first == null || rule.DateStart.Year > first.DateStart.Year))
first = rule;
- if (rule.DateEnd.Year == year)
+ if (rule.DateEnd.Year >= year && (last == null || rule.DateEnd.Year < last.DateEnd.Year))
last = rule;
}
return false;
}
- var inDelta = false;
- for (var i = transitions.Count - 1; i >= 0; i--) {
- var pair = transitions [i];
- DateTime ttime = pair.Key;
- TimeType ttype = pair.Value;
-
- var delta = new TimeSpan (0, 0, ttype.Offset) - BaseUtcOffset;
-
- if ((ttime + delta) > date) {
- inDelta = ttime <= date;
- continue;
- }
-
- offset = new TimeSpan (0, 0, ttype.Offset);
- if (inDelta) {
- // Replicate what .NET does when given a time which falls into the hour which is lost when
- // DST starts. isDST should be true but the offset should be the non-DST offset.
- isDst = transitions [i - 1].Value.IsDst;
- } else {
- isDst = ttype.IsDst;
+ AdjustmentRule current = GetApplicableRule(date);
+ if (current != null) {
+ DateTime tStart = TransitionPoint(current.DaylightTransitionStart, date.Year);
+ DateTime tEnd = TransitionPoint(current.DaylightTransitionEnd, date.Year);
+ if ((date >= tStart) && (date <= tEnd)) {
+ offset = baseUtcOffset + current.DaylightDelta;
+ isDst = true;
+ return true;
}
-
- return true;
}
-
return false;
}
return new DateTime (year, transition.Month, day) + transition.TimeOfDay.TimeOfDay;
}
- static List<AdjustmentRule> ValidateRules (List<AdjustmentRule> adjustmentRules)
+ static AdjustmentRule[] ValidateRules (List<AdjustmentRule> adjustmentRules)
{
+ if (adjustmentRules == null || adjustmentRules.Count == 0)
+ return null;
+
AdjustmentRule prev = null;
foreach (AdjustmentRule current in adjustmentRules.ToArray ()) {
if (prev != null && prev.DateEnd > current.DateStart) {
}
prev = current;
}
- return adjustmentRules;
+ return adjustmentRules.ToArray ();
}
#if LIBC || MONOTOUCH
}
tz = CreateCustomTimeZone (id, baseUtcOffset, id, standardDisplayName);
} else {
- tz = CreateCustomTimeZone (id, baseUtcOffset, id, standardDisplayName, daylightDisplayName, ValidateRules (adjustmentRules).ToArray ());
+ tz = CreateCustomTimeZone (id, baseUtcOffset, id, standardDisplayName, daylightDisplayName, ValidateRules (adjustmentRules));
}
if (storeTransition && transitions.Count > 0) {
tz.transitions = transitions;
- tz.supportsDaylightSavingTime = true;
}
+ tz.supportsDaylightSavingTime = adjustmentRules.Count > 0;
return tz;
}
if (zone.IsAmbiguousTime (time)) {
isAmbiguousLocalDst = true;
- return baseOffset;
+// return baseOffset;
}
return zone.GetUtcOffset (time, out isDaylightSavings);