[profiles] Fix MOBILE assemblies and tests compilation + Rename MOBILE to AOT_HYBRID
[mono.git] / mcs / class / corlib / System / TimeZoneInfo.cs
index ff76486877cfb2427ccf2b5f9069985552b4c3d2..b64e180f7e06aec98191dc6729acd83db8a48dae 100644 (file)
@@ -105,10 +105,10 @@ namespace System
 
                        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;
                        }
@@ -149,7 +149,7 @@ namespace System
                        return true;
                }
 
-#if !MOBILE || MOBILE_STATIC
+#if !MONODROID && !MONOTOUCH && !XAMMAC
                static TimeZoneInfo CreateLocal ()
                {
 #if !MOBILE_STATIC
@@ -237,7 +237,7 @@ namespace System
                        throw new NotImplementedException ("This method is not implemented for this platform");
 #endif
                }
-#endif
+#endif // !MONODROID && !MONOTOUCH && !XAMMAC
 
                string standardDisplayName;
                public string StandardName {
@@ -273,7 +273,7 @@ namespace System
 #endif
                private AdjustmentRule [] adjustmentRules;
 
-#if !NET_2_1 || MOBILE_STATIC
+#if !MOBILE || !MOBILE_STATIC
                /// <summary>
                /// Determine whether windows of not (taken Stephane Delcroix's code)
                /// </summary>
@@ -330,7 +330,7 @@ namespace System
                        }
                }
 #endif
-#endif
+#endif // !MOBILE || !MOBILE_STATIC
 
                private static bool TryAddTicks (DateTime date, long ticks, out DateTime result, DateTimeKind kind = DateTimeKind.Unspecified)
                {
@@ -412,7 +412,14 @@ namespace System
 
                public static DateTime ConvertTimeBySystemTimeZoneId (DateTime dateTime, string sourceTimeZoneId, string destinationTimeZoneId)
                {
-                       return ConvertTime (dateTime, FindSystemTimeZoneById (sourceTimeZoneId), FindSystemTimeZoneById (destinationTimeZoneId));
+                       TimeZoneInfo source_tz;
+                       if (dateTime.Kind == DateTimeKind.Utc && sourceTimeZoneId == TimeZoneInfo.Utc.Id) {
+                               source_tz = Utc;
+                       } else {
+                               source_tz = FindSystemTimeZoneById (sourceTimeZoneId);
+                       }
+
+                       return ConvertTime (dateTime, source_tz, FindSystemTimeZoneById (destinationTimeZoneId));
                }
 
                public static DateTimeOffset ConvertTimeBySystemTimeZoneId (DateTimeOffset dateTimeOffset, string destinationTimeZoneId)
@@ -531,7 +538,7 @@ namespace System
                        //FIXME: this method should check for cached values in systemTimeZones
                        if (id == null)
                                throw new ArgumentNullException ("id");
-#if !NET_2_1
+#if !MOBILE
                        if (TimeZoneKey != null)
                        {
                                if (id == "Coordinated Universal Time")
@@ -561,7 +568,7 @@ namespace System
                }
 #endif
 
-#if !NET_2_1
+#if !MOBILE
                private static TimeZoneInfo FromRegistryKey (string id, RegistryKey key)
                {
                        byte [] reg_tzi = (byte []) key.GetValue ("TZI");
@@ -804,9 +811,16 @@ namespace System
                                        return tz.BaseUtcOffset;
                        }
 
-                       if (tzRule != null && tz.IsInDST (tzRule, stdUtcDateTime) && tz.IsInDST (tzRule, dstUtcDateTime)) {
+                       if (tzRule != null && tz.IsInDST (tzRule, stdUtcDateTime)) {
+                               // 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.
                                isDST = true;
-                               return tz.BaseUtcOffset + tzRule.DaylightDelta;
+                               if (tz.IsInDST (tzRule, dstUtcDateTime)) {
+                                       return tz.BaseUtcOffset + tzRule.DaylightDelta;
+                               } else {
+                                       return tz.BaseUtcOffset;
+                               }
                        }
 
                        return tz.BaseUtcOffset;
@@ -951,12 +965,17 @@ namespace System
                        } 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;
                                }
 
@@ -1165,16 +1184,27 @@ namespace System
                                        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;
 
-                               if (ttime > date)
+                               var delta =  new TimeSpan (0, 0, ttype.Offset) - BaseUtcOffset;
+
+                               if ((ttime + delta) > date) {
+                                       inDelta = ttime <= date;
                                        continue;
+                               }
 
                                offset =  new TimeSpan (0, 0, ttype.Offset);
-                               isDst = ttype.IsDst;
+                               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;
+                               }
 
                                return true;
                        }