Merge pull request #900 from Blewzman/FixAggregateExceptionGetBaseException
[mono.git] / mcs / class / corlib / System / TimeSpan.cs
index 60e8e7b0c9c3665a62bf42cd6a92ca9a5a55250f..7762dfc9177d180adbe5d7ec43d4a55ef72d1ce7 100644 (file)
@@ -5,10 +5,12 @@
 //   Duco Fijma (duco@lorentz.xs4all.nl)
 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
 //   Sebastien Pouliot  <sebastien@ximian.com>
+//   Marek Safar (marek.safar@gmail.com)
 //
 // (C) 2001 Duco Fijma
 // (C) 2004 Andreas Nahr
 // Copyright (C) 2004 Novell (http://www.novell.com)
+// Copyright (C) 2014 Xamarin Inc (http://www.xamarin.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -309,7 +311,7 @@ namespace System
                                value = (value * (tickMultiplicator / TicksPerMillisecond));
 
                                checked {
-                                       long val = (long) Math.Round(value);
+                                       long val = (long) Math.Round(value, MidpointRounding.AwayFromZero);
                                        return new TimeSpan (val * TicksPerMillisecond);
                                }
                        }
@@ -360,25 +362,25 @@ namespace System
                }
 
 #if NET_4_0
-               public static TimeSpan Parse (string s, IFormatProvider formatProvider)
+               public static TimeSpan Parse (string input, IFormatProvider formatProvider)
                {
-                       if (s == null)
-                               throw new ArgumentNullException ("s");
+                       if (input == null)
+                               throw new ArgumentNullException ("input");
 
                        TimeSpan result;
-                       Parser p = new Parser (s, formatProvider);
+                       Parser p = new Parser (input, formatProvider);
                        p.Execute (false, out result);
                        return result;
                }
 
-               public static bool TryParse (string s, IFormatProvider formatProvider, out TimeSpan result)
+               public static bool TryParse (string input, IFormatProvider formatProvider, out TimeSpan result)
                {
-                       if (s == null || s.Length == 0) {
+                       if (string.IsNullOrEmpty (input)) {
                                result = TimeSpan.Zero;
                                return false;
                        }
 
-                       Parser p = new Parser (s, formatProvider);
+                       Parser p = new Parser (input, formatProvider);
                        return p.Execute (true, out result);
                }
 
@@ -439,7 +441,7 @@ namespace System
                {
                        result = TimeSpan.Zero;
 
-                       if (formats == null || formats.Length == 0)
+                       if (input == null || formats == null || formats.Length == 0)
                                return false;
 
                        Parser p = new Parser (input, formatProvider);
@@ -543,7 +545,7 @@ namespace System
 
                        NumberFormatInfo number_info = null;
                        if (formatProvider != null)
-                               number_info = (NumberFormatInfo)formatProvider.GetFormat (typeof (NumberFormatInfo));
+                               number_info = formatProvider.GetFormat (typeof (NumberFormatInfo)) as NumberFormatInfo;
                        if (number_info == null)
                                number_info = Thread.CurrentThread.CurrentCulture.NumberFormat;
 
@@ -606,7 +608,7 @@ namespace System
 
                        StringBuilder sb = new StringBuilder (format.Length + 1);
 
-                       for (;;) {
+                       while (true) {
                                if (parser.AtEnd)
                                        break;
 
@@ -614,42 +616,42 @@ namespace System
                                switch (element.Type) {
                                        case FormatElementType.Days:
                                                value = Math.Abs (Days);
-                                               sb.Append (value.ToString ("D" + element.IntValue));
                                                break;
                                        case FormatElementType.Hours:
                                                value = Math.Abs (Hours);
-                                               sb.Append (value.ToString ("D" + element.IntValue));
                                                break;
                                        case FormatElementType.Minutes:
                                                value = Math.Abs (Minutes);
-                                               sb.Append (value.ToString ("D" + element.IntValue));
                                                break;
                                        case FormatElementType.Seconds:
                                                value = Math.Abs (Seconds);
-                                               sb.Append (value.ToString ("D" + element.IntValue));
                                                break;
                                        case FormatElementType.Ticks:
-                                               value = Math.Abs (Milliseconds);
-                                               sb.Append (value.ToString ("D" + element.IntValue));
-                                               break;
                                        case FormatElementType.TicksUppercase:
                                                value = Math.Abs (Milliseconds);
-                                               if (value > 0) {
-                                                       int threshold = (int)Math.Pow (10, element.IntValue);
-                                                       while (value >= threshold)
-                                                               value /= 10;
-                                                       sb.Append (value.ToString ());
+                                               if (value == 0) {
+                                                       if (element.Type == FormatElementType.Ticks)
+                                                               break;
+
+                                                       continue;
                                                }
-                                               break;
+
+                                               int threshold = (int)Math.Pow (10, element.IntValue);
+                                               while (value >= threshold)
+                                                       value /= 10;
+                                               sb.Append (value.ToString ());
+                                               continue;
                                        case FormatElementType.EscapedChar:
                                                sb.Append (element.CharValue);
-                                               break;
+                                               continue;
                                        case FormatElementType.Literal:
                                                sb.Append (element.StringValue);
-                                               break;
+                                               continue;
                                        default:
                                                throw new FormatException ("The format is not recognized.");
                                }
+
+                               sb.Append (value.ToString ("D" + element.IntValue.ToString ()));
                        }
 
                        return sb.ToString ();
@@ -756,11 +758,11 @@ namespace System
                                number_format = GetNumberFormatInfo (formatProvider);
                        }
 
-                       NumberFormatInfo GetNumberFormatInfo (IFormatProvider formatProvider)
+                       static NumberFormatInfo GetNumberFormatInfo (IFormatProvider formatProvider)
                        {
                                NumberFormatInfo format = null;
                                if (formatProvider != null)
-                                       format = (NumberFormatInfo) formatProvider.GetFormat (typeof (NumberFormatInfo));
+                                       format = formatProvider.GetFormat (typeof (NumberFormatInfo)) as NumberFormatInfo;
                                if (format == null)
                                        format = Thread.CurrentThread.CurrentCulture.NumberFormat;
 
@@ -863,19 +865,6 @@ namespace System
                                return (int)res;
                        }
 
-                       // Parse optional dot
-                       private bool ParseOptDot ()
-                       {
-                               if (AtEnd)
-                                       return false;
-
-                               if (_src[_cur] == '.') {
-                                       _cur++;
-                                       return true;
-                               }
-                               return false;
-                       }       
-
 #if NET_4_0
                        // This behaves pretty much like ParseOptDot, but we need to have it
                        // as a separated routine for both days and decimal separators.
@@ -935,6 +924,18 @@ namespace System
                                return false;
                        }
 #endif
+                       // Parse optional dot
+                       private bool ParseOptDot ()
+                       {
+                               if (AtEnd)
+                                       return false;
+
+                               if (_src[_cur] == '.') {
+                                       _cur++;
+                                       return true;
+                               }
+                               return false;
+                       }       
 
                        private void ParseColon (bool optional)
                        {
@@ -1072,11 +1073,15 @@ namespace System
                                value1 = ParseInt (false);
                                if (!ParseOptDaysSeparator ()) // Parse either day separator or colon
                                        ParseColon (false);
+                               int p = _cur;
                                value2 = ParseInt (true);
-                               ParseColon (true);
-                               value3 = ParseInt (true);
-                               ParseColon (true);
-                               value4 = ParseInt (true);
+                               value3 = value4 = 0;
+                               if (p < _cur) {
+                                       ParseColon (true);
+                                       value3 = ParseInt (true);
+                                       ParseColon (true);
+                                       value4 = ParseInt (true);
+                               }
 
                                // We know the precise separator for ticks, so there's no need to guess.
                                if (ParseOptDecimalSeparator ())
@@ -1177,9 +1182,13 @@ namespace System
                                        days = 0;
                                }
                                ParseColon(false);
+                               int p = _cur;
                                minutes = ParseInt (true);
-                               ParseColon (true);
-                               seconds = ParseInt (true);
+                               seconds = 0;
+                               if (p < _cur) {
+                                       ParseColon (true);
+                                       seconds = ParseInt (true);
+                               }
 
                                if ( ParseOptDot () ) {
                                        ticks = ParseTicks ();