2 // TimeSpanTest.cs - NUnit Test Cases for the System.TimeSpan struct
5 // Duco Fijma (duco@lorentz.xs4all.nl)
6 // Sebastien Pouliot <sebastien@ximian.com>
9 // Copyright (C) 2004 Novell (http://www.novell.com)
12 using NUnit.Framework;
14 using System.Globalization;
15 using System.Threading;
17 namespace MonoTests.System
21 public class TimeSpanTest {
23 private void Debug (TimeSpan ts)
25 Console.Out.WriteLine ("Days {0}", ts.Days);
26 Console.Out.WriteLine ("Hours {0}", ts.Hours);
27 Console.Out.WriteLine ("Minutes {0}", ts.Minutes);
28 Console.Out.WriteLine ("Seconds {0}", ts.Seconds);
29 Console.Out.WriteLine ("Milliseconds {0}", ts.Milliseconds);
30 Console.Out.WriteLine ("Ticks {0}", ts.Ticks);
34 public void TestCtors ()
36 TimeSpan t1 = new TimeSpan (1234567890);
38 Assert.AreEqual ("00:02:03.4567890", t1.ToString (), "A1");
39 t1 = new TimeSpan (1,2,3);
40 Assert.AreEqual ("01:02:03", t1.ToString (), "A2");
41 t1 = new TimeSpan (1,2,3,4);
42 Assert.AreEqual ("1.02:03:04", t1.ToString (), "A3");
43 t1 = new TimeSpan (1,2,3,4,5);
44 Assert.AreEqual ("1.02:03:04.0050000", t1.ToString (), "A4");
45 t1 = new TimeSpan (-1,2,-3,4,-5);
46 Assert.AreEqual ("-22:02:56.0050000", t1.ToString (), "A5");
47 t1 = new TimeSpan (0,25,0,0,0);
48 Assert.AreEqual ("1.01:00:00", t1.ToString (), "A6");
52 [ExpectedException (typeof (ArgumentOutOfRangeException))]
53 public void DaysOverflow ()
55 int days = (int) (Int64.MaxValue / TimeSpan.TicksPerDay) + 1;
56 TimeSpan ts = new TimeSpan (days, 0, 0, 0, 0);
60 [ExpectedException (typeof (ArgumentOutOfRangeException))]
61 public void TemporaryOverflow ()
63 // calculating part of this results in overflow (days)
64 // but the negative hours, minutes, seconds & ms correct this
65 int days = (int) (Int64.MaxValue / TimeSpan.TicksPerDay) + 1;
66 TimeSpan ts = new TimeSpan (days, Int32.MinValue, Int32.MinValue, Int32.MinValue, Int32.MinValue);
67 Assert.AreEqual (10650320, ts.Days, "Days");
68 Assert.AreEqual (0, ts.Hours, "Hours");
69 Assert.AreEqual (14, ts.Minutes, "Minutes");
70 Assert.AreEqual (28, ts.Seconds, "Seconds");
71 Assert.AreEqual (352, ts.Milliseconds, "Milliseconds");
72 Assert.AreEqual (9201876488683520000, ts.Ticks, "Ticks");
76 [ExpectedException (typeof (ArgumentOutOfRangeException))]
77 public void NoOverflowInHoursMinsSecondsMS ()
79 TimeSpan ts = new TimeSpan (0, Int32.MaxValue, Int32.MaxValue, Int32.MaxValue, Int32.MaxValue);
80 Assert.AreEqual (24879, ts.Days, "Days");
81 Assert.AreEqual (22, ts.Hours, "Hours");
82 Assert.AreEqual (44, ts.Minutes, "Minutes");
83 Assert.AreEqual (30, ts.Seconds, "Seconds");
84 Assert.AreEqual (647, ts.Milliseconds, "Milliseconds");
85 Assert.AreEqual (21496274706470000, ts.Ticks, "Ticks");
89 [ExpectedException (typeof (ArgumentOutOfRangeException))]
90 public void MaxDays ()
92 new TimeSpan (Int32.MaxValue, 0, 0, 0, 0);
96 [ExpectedException (typeof (ArgumentOutOfRangeException))]
97 public void MinDays ()
99 new TimeSpan (Int32.MinValue, 0, 0, 0, 0);
103 [ExpectedException (typeof (ArgumentOutOfRangeException))]
104 public void MaxHours ()
106 // LAMESPEC: the highest hours are "special"
107 TimeSpan ts = new TimeSpan (0, Int32.MaxValue, 0, 0, 0);
108 Assert.AreEqual (0, ts.Days, "Max-Days");
109 Assert.AreEqual (-1, ts.Hours, "Max-Hours");
110 Assert.AreEqual (0, ts.Minutes, "Max-Minutes");
111 Assert.AreEqual (0, ts.Seconds, "Max-Seconds");
112 Assert.AreEqual (0, ts.Milliseconds, "Max-Milliseconds");
113 Assert.AreEqual (-36000000000, ts.Ticks, "Max-Ticks");
115 ts = new TimeSpan (0, Int32.MaxValue - 596522, 0, 0, 0);
116 Assert.AreEqual (-24855, ts.Days, "Days");
117 Assert.AreEqual (-3, ts.Hours, "Hours");
118 Assert.AreEqual (0, ts.Minutes, "Minutes");
119 Assert.AreEqual (0, ts.Seconds, "Seconds");
120 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
121 Assert.AreEqual (-21474828000000000, ts.Ticks, "Ticks");
125 [ExpectedException (typeof (ArgumentOutOfRangeException))]
126 public void MaxHours_BreakPoint ()
128 TimeSpan ts = new TimeSpan (0, Int32.MaxValue - 596523, 0, 0, 0);
129 Assert.AreEqual (24855, ts.Days, "Days");
130 Assert.AreEqual (2, ts.Hours, "Hours");
131 Assert.AreEqual (28, ts.Minutes, "Minutes");
132 Assert.AreEqual (16, ts.Seconds, "Seconds");
133 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
134 Assert.AreEqual (21474808960000000, ts.Ticks, "Ticks");
138 public void MinHours ()
140 TimeSpan ts = new TimeSpan (0, -256204778, 0, 0, 0);
141 Assert.AreEqual (-10675199, ts.Days, "Days");
142 Assert.AreEqual (-2, ts.Hours, "Hours");
143 Assert.AreEqual (0, ts.Minutes, "Minutes");
144 Assert.AreEqual (0, ts.Seconds, "Seconds");
145 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
146 Assert.AreEqual (-9223372008000000000, ts.Ticks, "Ticks");
150 [ExpectedException (typeof (ArgumentOutOfRangeException))]
151 public void MinHours_BreakPoint ()
153 TimeSpan ts = new TimeSpan (0, -2146887124, 0, 0, 0);
154 Assert.AreEqual (-24855, ts.Days, "Days");
155 Assert.AreEqual (-2, ts.Hours, "Hours");
156 Assert.AreEqual (-28, ts.Minutes, "Minutes");
157 Assert.AreEqual (-16, ts.Seconds, "Seconds");
158 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
159 Assert.AreEqual (-21474808960000000, ts.Ticks, "Ticks");
163 public void MaxMinutes ()
166 ts = new TimeSpan (0, 0, 256204778, 0, 0);
167 Assert.AreEqual (177919, ts.Days, "Max-Days");
168 Assert.AreEqual (23, ts.Hours, "Max-Hours");
169 Assert.AreEqual (38, ts.Minutes, "Max-Minutes");
170 Assert.AreEqual (0, ts.Seconds, "Max-Seconds");
171 Assert.AreEqual (0, ts.Milliseconds, "Max-Milliseconds");
172 Assert.AreEqual (153722866800000000, ts.Ticks, "Max-Ticks");
176 [ExpectedException (typeof (ArgumentOutOfRangeException))]
177 public void MaxMinutes_BreakPoint ()
179 TimeSpan ts = new TimeSpan (0, Int32.MaxValue - 35791394, 0, 0, 0);
180 Assert.AreEqual (0, ts.Days, "Days");
181 Assert.AreEqual (0, ts.Hours, "Hours");
182 Assert.AreEqual (-52, ts.Minutes, "Minutes");
183 Assert.AreEqual (0, ts.Seconds, "Seconds");
184 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
185 Assert.AreEqual (-31200000000, ts.Ticks, "Ticks");
189 public void MinMinutes ()
192 ts = new TimeSpan (0, 0, Int32.MinValue, 0, 0);
193 Assert.AreEqual (-1491308, ts.Days, "Days");
194 Assert.AreEqual (-2, ts.Hours, "Hours");
195 Assert.AreEqual (-8, ts.Minutes, "Minutes");
196 Assert.AreEqual (0, ts.Seconds, "Seconds");
197 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
198 Assert.AreEqual (-1288490188800000000, ts.Ticks, "Ticks");
202 public void MinMinutes_BreakPoint ()
204 TimeSpan ts = new TimeSpan (0, 0, -2111692253, 0, 0);
205 Assert.AreEqual (-1466452, ts.Days, "Days");
206 Assert.AreEqual (-22, ts.Hours, "Hours");
207 Assert.AreEqual (-53, ts.Minutes, "Minutes");
208 Assert.AreEqual (-0, ts.Seconds, "Seconds");
209 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
210 Assert.AreEqual (-1267015351800000000, ts.Ticks, "Ticks");
214 public void MaxSeconds ()
216 TimeSpan ts = new TimeSpan (0, 0, 0, Int32.MaxValue, 0);
217 Assert.AreEqual (24855, ts.Days, "Days");
218 Assert.AreEqual (3, ts.Hours, "Hours");
219 Assert.AreEqual (14, ts.Minutes, "Minutes");
220 Assert.AreEqual (7, ts.Seconds, "Seconds");
221 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
222 Assert.AreEqual (21474836470000000, ts.Ticks, "Ticks");
226 public void MinSeconds ()
228 TimeSpan ts = new TimeSpan (0, 0, 0, Int32.MinValue, 0);
229 Assert.AreEqual (-24855, ts.Days, "Days");
230 Assert.AreEqual (-3, ts.Hours, "Hours");
231 Assert.AreEqual (-14, ts.Minutes, "Minutes");
232 Assert.AreEqual (-8, ts.Seconds, "Seconds");
233 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
234 Assert.AreEqual (-21474836480000000, ts.Ticks, "Ticks");
238 public void MaxMilliseconds ()
240 TimeSpan ts = new TimeSpan (0, 0, 0, 0, Int32.MaxValue);
241 Assert.AreEqual (24, ts.Days, "Days");
242 Assert.AreEqual (20, ts.Hours, "Hours");
243 Assert.AreEqual (31, ts.Minutes, "Minutes");
244 Assert.AreEqual (23, ts.Seconds, "Seconds");
245 Assert.AreEqual (647, ts.Milliseconds, "Milliseconds");
246 Assert.AreEqual (21474836470000, ts.Ticks, "Ticks");
250 public void MinMilliseconds ()
252 TimeSpan ts = new TimeSpan (0, 0, 0, 0, Int32.MinValue);
253 Assert.AreEqual (-24, ts.Days, "Days");
254 Assert.AreEqual (-20, ts.Hours, "Hours");
255 Assert.AreEqual (-31, ts.Minutes, "Minutes");
256 Assert.AreEqual (-23, ts.Seconds, "Seconds");
257 Assert.AreEqual (-648, ts.Milliseconds, "Milliseconds");
258 Assert.AreEqual (-21474836480000, ts.Ticks, "Ticks");
262 public void NegativeTimeSpan ()
264 TimeSpan ts = new TimeSpan (-23, -59, -59);
265 Assert.AreEqual (0, ts.Days, "Days");
266 Assert.AreEqual (-23, ts.Hours, "Hours");
267 Assert.AreEqual (-59, ts.Minutes, "Minutes");
268 Assert.AreEqual (-59, ts.Seconds, "Seconds");
269 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
270 Assert.AreEqual (-863990000000, ts.Ticks, "Ticks");
274 public void TestProperties ()
276 TimeSpan t1 = new TimeSpan (1,2,3,4,5);
279 Assert.AreEqual (1, t1.Days, "A1");
280 Assert.AreEqual (2, t1.Hours, "A2");
281 Assert.AreEqual (3, t1.Minutes, "A3");
282 Assert.AreEqual (4, t1.Seconds, "A4");
283 Assert.AreEqual (5, t1.Milliseconds, "A5");
284 Assert.AreEqual (-1, t2.Days, "A6");
285 Assert.AreEqual (-2, t2.Hours, "A7");
286 Assert.AreEqual (-3, t2.Minutes, "A8");
287 Assert.AreEqual (-4, t2.Seconds, "A9");
288 Assert.AreEqual (-5, t2.Milliseconds, "A10");
292 public void TestAdd ()
294 TimeSpan t1 = new TimeSpan (2,3,4,5,6);
295 TimeSpan t2 = new TimeSpan (1,2,3,4,5);
296 TimeSpan t3 = t1 + t2;
297 TimeSpan t4 = t1.Add (t2);
301 Assert.AreEqual (3, t3.Days, "A1");
302 Assert.AreEqual (5, t3.Hours, "A2");
303 Assert.AreEqual (7, t3.Minutes, "A3");
304 Assert.AreEqual (9, t3.Seconds, "A4");
305 Assert.AreEqual (11, t3.Milliseconds, "A5");
306 Assert.AreEqual ("3.05:07:09.0110000", t4.ToString (), "A6");
309 t5 = TimeSpan.MaxValue + new TimeSpan (1);
312 catch (OverflowException)
316 Assert.IsTrue (exception, "A7");
320 public void TestCompare ()
322 TimeSpan t1 = new TimeSpan (-1);
323 TimeSpan t2 = new TimeSpan (1);
327 Assert.AreEqual (-1, TimeSpan.Compare (t1, t2), "A1");
328 Assert.AreEqual (1, TimeSpan.Compare (t2, t1), "A2");
329 Assert.AreEqual (0, TimeSpan.Compare (t2, t2), "A3");
330 Assert.AreEqual (-1, TimeSpan.Compare (TimeSpan.MinValue, TimeSpan.MaxValue), "A4");
331 Assert.AreEqual (-1, t1.CompareTo (t2), "A5");
332 Assert.AreEqual (1, t2.CompareTo (t1), "A6");
333 Assert.AreEqual (0, t2.CompareTo (t2), "A7");
334 Assert.AreEqual (-1, TimeSpan.Compare (TimeSpan.MinValue, TimeSpan.MaxValue), "A8");
336 Assert.AreEqual (1, TimeSpan.Zero.CompareTo (null), "A9");
340 res = TimeSpan.Zero.CompareTo("");
343 catch (ArgumentException)
347 Assert.IsTrue (exception, "A10");
349 Assert.AreEqual (false, t1 == t2, "A11");
350 Assert.AreEqual (false, t1 > t2, "A12");
351 Assert.AreEqual (false, t1 >= t2, "A13");
352 Assert.AreEqual (true, t1 != t2, "A14");
353 Assert.AreEqual (true, t1 < t2, "A15");
354 Assert.AreEqual (true, t1 <= t2, "A16");
358 [ExpectedException (typeof (OverflowException))]
359 public void NoNegateMinValue() {
360 TimeSpan t1 = TimeSpan.MinValue.Negate ();
364 public void TestNegateAndDuration ()
369 Assert.AreEqual ("-00:00:00.0012345", new TimeSpan (12345).Negate ().ToString (), "A1");
370 Assert.AreEqual ("00:00:00.0012345", new TimeSpan (-12345).Duration ().ToString (), "A2");
374 t1 = TimeSpan.MinValue.Duration ();
377 catch (OverflowException) {
380 Assert.IsTrue (exception, "A4");
382 Assert.AreEqual ("-00:00:00.0000077", (-(new TimeSpan (77))).ToString (), "A5");
383 Assert.AreEqual ("00:00:00.0000077", (+(new TimeSpan(77))).ToString(), "A6");
387 public void TestEquals ()
389 TimeSpan t1 = new TimeSpan (1);
390 TimeSpan t2 = new TimeSpan (2);
391 string s = "justastring";
393 Assert.AreEqual (true, t1.Equals (t1), "A1");
394 Assert.AreEqual (false, t1.Equals (t2), "A2");
395 Assert.AreEqual (false, t1.Equals (s), "A3");
396 Assert.AreEqual (false, t1.Equals (null), "A4");
397 Assert.AreEqual (true, TimeSpan.Equals (t1, t1), "A5");
398 Assert.AreEqual (false, TimeSpan.Equals (t1, t2), "A6");
399 Assert.AreEqual (false, TimeSpan.Equals (t1, null), "A7");
400 Assert.AreEqual (false, TimeSpan.Equals (t1, s), "A8");
401 Assert.AreEqual (false, TimeSpan.Equals (s, t2), "A9");
402 Assert.AreEqual (true, TimeSpan.Equals (null, null), "A10");
406 public void TestFromXXXX ()
408 Assert.AreEqual ("12.08:16:48", TimeSpan.FromDays (12.345).ToString (), "A1");
409 Assert.AreEqual ("12:20:42", TimeSpan.FromHours (12.345).ToString (), "A2");
410 Assert.AreEqual ("00:12:20.7000000", TimeSpan.FromMinutes (12.345).ToString (), "A3");
411 Assert.AreEqual ("00:00:12.3450000", TimeSpan.FromSeconds (12.345).ToString (), "A4");
412 Assert.AreEqual ("00:00:00.0120000", TimeSpan.FromMilliseconds (12.345).ToString (), "A5");
413 Assert.AreEqual ("00:00:00.0012345", TimeSpan.FromTicks (12345).ToString (), "A6");
414 Assert.AreEqual ("-00:00:00.0010000", TimeSpan.FromMilliseconds (-0.5).ToString (), "A7");
415 Assert.AreEqual ("00:00:00.0010000", TimeSpan.FromMilliseconds (0.5).ToString (), "A8");
416 Assert.AreEqual ("-00:00:00.0030000", TimeSpan.FromMilliseconds (-2.5).ToString (), "A9");
417 Assert.AreEqual ("00:00:00.0030000", TimeSpan.FromMilliseconds (2.5).ToString (), "A10");
418 Assert.AreEqual ("00:00:00.0010000", TimeSpan.FromSeconds (0.0005).ToString (), "A11");
422 [ExpectedException (typeof (OverflowException))]
423 public void FromDays_MinValue ()
425 TimeSpan.FromDays (Double.MinValue);
429 [ExpectedException (typeof (OverflowException))]
430 public void FromDays_MaxValue ()
432 TimeSpan.FromDays (Double.MaxValue);
436 [ExpectedException (typeof (ArgumentException))]
437 public void FromDays_NaN ()
439 TimeSpan.FromDays (Double.NaN);
443 [ExpectedException (typeof (OverflowException))]
444 public void FromDays_PositiveInfinity ()
446 // LAMESPEC: Document to return TimeSpan.MaxValue
447 Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.FromDays (Double.PositiveInfinity));
451 [ExpectedException (typeof (OverflowException))]
452 public void FromDays_NegativeInfinity ()
454 // LAMESPEC: Document to return TimeSpan.MinValue
455 Assert.AreEqual (TimeSpan.MinValue, TimeSpan.FromDays (Double.NegativeInfinity));
459 [ExpectedException (typeof (OverflowException))]
460 public void FromHours_MinValue ()
462 TimeSpan.FromHours (Double.MinValue);
466 [ExpectedException (typeof (OverflowException))]
467 public void FromHours_MaxValue ()
469 TimeSpan.FromHours (Double.MaxValue);
473 [ExpectedException (typeof (ArgumentException))]
474 public void FromHours_NaN ()
476 TimeSpan.FromHours (Double.NaN);
480 [ExpectedException (typeof (OverflowException))]
481 public void FromHours_PositiveInfinity ()
483 // LAMESPEC: Document to return TimeSpan.MaxValue
484 Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.FromHours (Double.PositiveInfinity));
488 [ExpectedException (typeof (OverflowException))]
489 public void FromHours_NegativeInfinity ()
491 // LAMESPEC: Document to return TimeSpan.MinValue
492 Assert.AreEqual (TimeSpan.MinValue, TimeSpan.FromHours (Double.NegativeInfinity));
496 [ExpectedException (typeof (OverflowException))]
497 public void FromMilliseconds_MinValue ()
499 TimeSpan.FromMilliseconds (Double.MinValue);
503 [ExpectedException (typeof (OverflowException))]
504 public void FromMilliseconds_MaxValue ()
506 TimeSpan.FromMilliseconds (Double.MaxValue);
510 [ExpectedException (typeof (ArgumentException))]
511 public void FromMilliseconds_NaN ()
513 TimeSpan.FromMilliseconds (Double.NaN);
517 [ExpectedException (typeof (OverflowException))]
518 public void FromMilliseconds_PositiveInfinity ()
520 // LAMESPEC: Document to return TimeSpan.MaxValue
521 Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.FromMilliseconds (Double.PositiveInfinity));
525 [ExpectedException (typeof (OverflowException))]
526 public void FromMilliseconds_NegativeInfinity ()
528 // LAMESPEC: Document to return TimeSpan.MinValue
529 Assert.AreEqual (TimeSpan.MinValue, TimeSpan.FromMilliseconds (Double.NegativeInfinity));
533 [ExpectedException (typeof (OverflowException))]
534 public void FromMinutes_MinValue ()
536 TimeSpan.FromMinutes (Double.MinValue);
540 [ExpectedException (typeof (OverflowException))]
541 public void FromMinutes_MaxValue ()
543 TimeSpan.FromMinutes (Double.MaxValue);
547 [ExpectedException (typeof (ArgumentException))]
548 public void FromMinutes_NaN ()
550 TimeSpan.FromMinutes (Double.NaN);
554 [ExpectedException (typeof (OverflowException))]
555 public void FromMinutes_PositiveInfinity ()
557 // LAMESPEC: Document to return TimeSpan.MaxValue
558 Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.FromMinutes (Double.PositiveInfinity));
562 [ExpectedException (typeof (OverflowException))]
563 public void FromMinutes_NegativeInfinity ()
565 // LAMESPEC: Document to return TimeSpan.MinValue
566 Assert.AreEqual (TimeSpan.MinValue, TimeSpan.FromMinutes (Double.NegativeInfinity));
570 [ExpectedException (typeof (OverflowException))]
571 public void FromSeconds_MinValue ()
573 TimeSpan.FromSeconds (Double.MinValue);
577 [ExpectedException (typeof (OverflowException))]
578 public void FromSeconds_MaxValue ()
580 TimeSpan.FromSeconds (Double.MaxValue);
584 [ExpectedException (typeof (ArgumentException))]
585 public void FromSeconds_NaN ()
587 TimeSpan.FromSeconds (Double.NaN);
591 [ExpectedException (typeof (OverflowException))]
592 public void FromSeconds_PositiveInfinity ()
594 // LAMESPEC: Document to return TimeSpan.MaxValue
595 Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.FromSeconds (Double.PositiveInfinity));
599 [ExpectedException (typeof (OverflowException))]
600 public void FromSeconds_NegativeInfinity ()
602 // LAMESPEC: Document to return TimeSpan.MinValue
603 Assert.AreEqual (TimeSpan.MinValue, TimeSpan.FromSeconds (Double.NegativeInfinity));
607 public void TestGetHashCode ()
609 Assert.AreEqual (77, new TimeSpan (77).GetHashCode (), "A1");
612 private void ParseHelper (string s, bool expectFormat, bool expectOverflow, string expect)
614 bool formatException = false;
615 bool overflowException = false;
616 string result = "junk ";
619 result = TimeSpan.Parse (s).ToString ();
621 catch (OverflowException) {
622 overflowException = true;
624 catch (FormatException) {
625 formatException = true;
627 Assert.AreEqual (expectFormat, formatException, "A1 [" + s + "]");
628 Assert.AreEqual (expectOverflow, overflowException, "A2 " + s + "]");
630 if (!expectOverflow && !expectFormat) {
631 Assert.AreEqual (expect, result, "A3 [" + s + "]");
636 public void TestParse ()
638 ParseHelper (" 13:45:15 ",false, false, "13:45:15");
639 ParseHelper (" -1:2:3 ", false, false, "-01:02:03");
642 // In 4.0 when the first part is out of range, it parses it as day.
643 ParseHelper (" 25:11:12 ", false, false, "25.11:12:00");
644 ParseHelper (" 24:11:12 ", false, false, "24.11:12:00");
645 ParseHelper (" 23:11:12 ", false, false, "23:11:12");
647 ParseHelper (" 25:0:0 ",false, true, "dontcare");
650 ParseHelper ("-21.23:59:59.9999999", false, false, "-21.23:59:59.9999999");
651 ParseHelper ("10:12 ", false, false, "10:12:00");
652 ParseHelper ("aaa", true, false, "dontcare");
654 ParseHelper ("100000000000000.1:1:1", false, true, "dontcare");
655 ParseHelper ("24:60:60", false, true, "dontcare");
656 ParseHelper ("0001:0002:0003.12 ", false, false, "01:02:03.1200000");
659 // In 4.0 when a section has more than 7 digits an OverflowException is thrown.
660 ParseHelper (" 1:2:3:12345678 ", false, true, "dontcare");
662 ParseHelper (" 1:2:3:12345678 ", true, false, "dontcare");
666 ParseHelper ("10:11:12:13", false, false, "10.11:12:13"); // Days using : instead of . as separator
667 ParseHelper ("10.11", true, false, "dontcare"); // days+hours is invalid
669 // Force the use of french culture -which is using a non common NumberDecimalSeparator-
670 // as current culture, to show that the Parse method is *actually* being culture sensitive
671 // *and* also keeping the compatibility with '.'
672 CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
673 CultureInfo prev_culture = CultureInfo.CurrentCulture;
675 Thread.CurrentThread.CurrentCulture = french_culture;
676 ParseHelper ("10:10:10,006", false, false, "10:10:10.0060000");
677 ParseHelper ("10:10:10.006", false, false, "10:10:10.0060000");
680 Thread.CurrentThread.CurrentCulture = prev_culture;
684 ParseHelper ("00:00:00", false, false, "00:00:00");
685 ParseHelper ("00:10:00", false, false, "00:10:00");
688 // LAMESPEC: timespan in documentation is wrong - hh:mm:ss isn't mandatory
690 public void Parse_Days_WithoutColon ()
692 TimeSpan ts = TimeSpan.Parse ("1");
693 Assert.AreEqual (1, ts.Days, "Days");
697 public void TestSubstract ()
699 TimeSpan t1 = new TimeSpan (2,3,4,5,6);
700 TimeSpan t2 = new TimeSpan (1,2,3,4,5);
701 TimeSpan t3 = t1 - t2;
702 TimeSpan t4 = t1.Subtract (t2);
706 Assert.AreEqual ("1.01:01:01.0010000", t3.ToString (), "A1");
707 Assert.AreEqual ("1.01:01:01.0010000", t4.ToString (), "A2");
709 t5 = TimeSpan.MinValue - new TimeSpan (1);
712 catch (OverflowException) {
715 Assert.IsTrue (exception, "A3");
719 public void TestToString ()
721 TimeSpan t1 = new TimeSpan (1,2,3,4,5);
724 Assert.AreEqual ("1.02:03:04.0050000", t1.ToString (), "A1");
725 Assert.AreEqual ("-1.02:03:04.0050000", t2.ToString (), "A2");
726 Assert.AreEqual ("10675199.02:48:05.4775807", TimeSpan.MaxValue.ToString (), "A3");
727 Assert.AreEqual ("-10675199.02:48:05.4775808", TimeSpan.MinValue.ToString (), "A4");
731 public void ToString_Constants ()
733 Assert.AreEqual ("00:00:00", TimeSpan.Zero.ToString (), "Zero");
734 Assert.AreEqual ("10675199.02:48:05.4775807", TimeSpan.MaxValue.ToString (), "MaxValue");
735 Assert.AreEqual ("-10675199.02:48:05.4775808", TimeSpan.MinValue.ToString (), "MinValue");
739 public void Parse_InvalidValuesAndFormat_ExceptionOrder ()
741 // hours should be between 0 and 23 but format is also invalid (too many dots)
742 // In 2.0 overflow as precedence over format, but not in 4.0
745 TimeSpan.Parse ("0.99.99.0");
747 } catch (FormatException) {
751 TimeSpan.Parse ("0.99.99.0");
753 } catch (OverflowException) {
757 TimeSpan.Parse ("0.999999999999.99.0");
759 } catch (OverflowException) {
764 public void Parse_MinMaxValues ()
766 Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.Parse ("10675199.02:48:05.4775807"), "MaxValue");
767 Assert.AreEqual (TimeSpan.MinValue, TimeSpan.Parse ("-10675199.02:48:05.4775808"), "MinValue");
771 [ExpectedException (typeof (OverflowException))]
772 public void Parse_OverMaxValue()
774 TimeSpan.Parse ("10675199.02:48:05.4775808");
778 [ExpectedException (typeof (OverflowException))]
779 public void Parse_UnderMinValue()
781 TimeSpan.Parse ("-10675199.02:48:05.4775809");
785 public void ParseMissingSeconds ()
787 // as seen in ML for http://resources.esri.com/arcgisserver/apis/silverlight/
788 TimeSpan ts = TimeSpan.Parse ("0:0:.75");
790 Assert.AreEqual (0, ts.Days, "Days");
791 Assert.AreEqual (0, ts.Hours, "Hours");
792 Assert.AreEqual (750, ts.Milliseconds, "Milliseconds");
793 Assert.AreEqual (0, ts.Minutes, "Minutes");
794 Assert.AreEqual (0, ts.Seconds, "Seconds");
795 Assert.AreEqual (7500000, ts.Ticks, "Ticks");
796 Assert.AreEqual (0.0000086805555555555555, ts.TotalDays, 0.00000000000000001, "TotalDays");
797 Assert.AreEqual (0.00020833333333333332, ts.TotalHours, 0.00000000000000001, "TotalHours");
798 Assert.AreEqual (750.0, ts.TotalMilliseconds, "TotalMilliseconds");
799 Assert.AreEqual (0.0125, ts.TotalMinutes, "TotalMinutes");
800 Assert.AreEqual (0.75, ts.TotalSeconds, "TotalSeconds");
803 // 'Ported' the Parse test to use TryParse
805 public void TryParse ()
809 Assert.AreEqual (true, TimeSpan.TryParse (" 13:45:15 ", out result), "#A1");
810 Assert.AreEqual ("13:45:15", result.ToString (), "#A2");
812 Assert.AreEqual (true, TimeSpan.TryParse (" -1:2:3 ", out result), "#B1");
813 Assert.AreEqual ("-01:02:03", result.ToString (), "#B2");
815 Assert.AreEqual (false, TimeSpan.TryParse ("aaa", out result), "#C2");
817 Assert.AreEqual (true, TimeSpan.TryParse ("-21.23:59:59.9999999", out result), "#D1");
818 Assert.AreEqual ("-21.23:59:59.9999999", result.ToString (), "#D2");
820 Assert.AreEqual (false, TimeSpan.TryParse ("100000000000000.1:1:1", out result), "#E1");
821 Assert.AreEqual (false, TimeSpan.TryParse ("24:60:60", out result), "#E2");
824 Assert.AreEqual (true, TimeSpan.TryParse ("0001:0002:0003.12 ", out result), "#F1");
826 Assert.AreEqual (true, TimeSpan.TryParse ("0001:0002:0003.12 ", out result), "#F1");
827 Assert.AreEqual ("01:02:03.1200000", result.ToString (), "#F2");
830 Assert.AreEqual (false, TimeSpan.TryParse (" 1:2:3:12345678 ", out result), "#G1");
832 // Min and Max values
833 Assert.AreEqual (true, TimeSpan.TryParse ("10675199.02:48:05.4775807", out result), "MaxValue#1");
834 Assert.AreEqual (TimeSpan.MaxValue, result, "MaxValue#2");
835 Assert.AreEqual (true, TimeSpan.TryParse ("-10675199.02:48:05.4775808", out result), "MinValue#1");
836 Assert.AreEqual (TimeSpan.MinValue, result, "MinValue#2");
839 // Force the use of french culture -which is using a non common NumberDecimalSeparator-
840 // as current culture, to show that the Parse method is *actually* being culture sensitive
841 CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
842 CultureInfo prev_culture = CultureInfo.CurrentCulture;
843 result = new TimeSpan (0, 10, 10, 10, 6);
845 Thread.CurrentThread.CurrentCulture = french_culture;
846 Assert.AreEqual (true, TimeSpan.TryParse ("10:10:10,006", out result), "#CultureSensitive1");
847 Assert.AreEqual ("10:10:10.0060000", result.ToString (), "#CultureSensitive2");
850 Thread.CurrentThread.CurrentCulture = prev_culture;
856 public void TryParseErrors ()
860 Assert.AreEqual (false, TimeSpan.TryParse ("0.99.99.0", out result), "Format#1");
861 Assert.AreEqual (false, TimeSpan.TryParse ("10675199.02:48:05.4775808", out result), "OverMaxValue");
862 Assert.AreEqual (false, TimeSpan.TryParse ("-10675199.02:48:05.4775809", out result), "UnderMinValue");
867 public void TryParseOverloads ()
871 // We use fr-FR culture since its NumericDecimalSeparator is not the same used by
872 // most cultures - including the invariant one.
873 CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
874 Assert.AreEqual (true, TimeSpan.TryParse ("11:50:50,006", french_culture, out result), "#A1");
876 // LAMESPEC - msdn states that an instance of DateTimeFormatInfo is retrieved to
877 // obtain culture sensitive information, but at least in the betas that's false
878 DateTimeFormatInfo format_info = new DateTimeFormatInfo ();
879 format_info.TimeSeparator = ";";
880 Assert.AreEqual (false, TimeSpan.TryParse ("11;50;50", format_info, out result), "#B1");
881 Assert.AreEqual (true, TimeSpan.TryParse ("11:50:50", format_info, out result), "#B2");
885 public void ParseExact ()
887 CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
888 CultureInfo us_culture = CultureInfo.GetCultureInfo ("en-US");
890 // At this point we are only missing the style bites and then we are
891 // pretty much done with the standard formats.
894 // 'g' format - this is the short and culture sensitive format
896 string [] g_format = new string [] { "g" };
897 ParseExactHelper ("12", g_format, false, false, "12.00:00:00");
898 ParseExactHelper ("11:12", g_format, false, false, "11:12:00");
899 ParseExactHelper ("-11:12", g_format, false, false, "-11:12:00");
900 ParseExactHelper ("25:13", g_format, true, false, "dontcare");
901 ParseExactHelper ("11:66", g_format, true, false, "dontcare"); // I'd have expected OverflowExc here
902 ParseExactHelper ("11:12:13", g_format, false, false, "11:12:13");
903 ParseExactHelper ("-11:12:13", g_format, false, false, "-11:12:13");
904 ParseExactHelper ("10.11:12:13", g_format, true, false, "dontcare"); // this should work as well
905 ParseExactHelper ("10.11:12:13", g_format, true, false, "dontcare", us_culture);
906 ParseExactHelper ("10.11:12:13", g_format, true, false, "dontcare", CultureInfo.InvariantCulture);
907 ParseExactHelper ("10:11:12:66", g_format, true, false, "dontcare");
908 ParseExactHelper ("10:11:12:13", g_format, false, false, "10.11:12:13");
909 ParseExactHelper ("11:12:13.6", g_format, false, false, "11:12:13.6000000", CultureInfo.InvariantCulture);
910 ParseExactHelper ("11:12:13,6", g_format, false, false, "11:12:13.6000000", french_culture);
911 ParseExactHelper ("10:11:12:13.6", g_format, false, false, "10.11:12:13.6000000", us_culture);
912 ParseExactHelper (" 10:11:12:13.6 ", g_format, false, false, "10.11:12:13.6000000", us_culture);
913 ParseExactHelper ("10:11", g_format, false, false, "10:11:00", null, TimeSpanStyles.None);
914 ParseExactHelper ("10:11", g_format, false, false, "10:11:00", null, TimeSpanStyles.AssumeNegative); // no effect
919 string [] G_format = new string [] { "G" };
920 ParseExactHelper ("9:10:12", G_format, true, false, "dontcare");
921 ParseExactHelper ("9:10:12.6", G_format, true, false, "dontcare");
922 ParseExactHelper ("3.9:10:12", G_format, true, false, "dontcare");
923 ParseExactHelper ("3.9:10:12.153", G_format, true, false, "dontcare"); // this should be valid...
924 ParseExactHelper ("3:9:10:12.153", G_format, false, false, "3.09:10:12.1530000", us_culture);
925 ParseExactHelper ("0:9:10:12.153", G_format, false, false, "09:10:12.1530000", us_culture);
926 ParseExactHelper ("03:09:10:12.153", G_format, false, false, "3.09:10:12.1530000", us_culture);
927 ParseExactHelper ("003:009:0010:0012.00153", G_format, false, false, "3.09:10:12.0015300", us_culture);
928 ParseExactHelper ("3:9:10:66.153", G_format, true, false, "dontcare"); // seconds out of range
929 ParseExactHelper ("3:9:10:12.153", G_format, true, false, "dontcare", french_culture); // fr-FR uses ',' as decimal separator
930 ParseExactHelper ("3:9:10:12,153", G_format, false, false, "3.09:10:12.1530000", french_culture);
931 ParseExactHelper (" 3:9:10:12.153 ", G_format, false, false, "3.09:10:12.1530000", us_culture);
932 ParseExactHelper ("3:9:10:13.153", G_format, false, false, "3.09:10:13.1530000", us_culture, TimeSpanStyles.AssumeNegative);
935 string [] c_format = new string [] { "c" };
936 ParseExactHelper ("12", c_format, false, false, "12.00:00:00");
937 ParseExactHelper ("12:11", c_format, false, false, "12:11:00");
938 ParseExactHelper ("12:66", c_format, true, false, "dontcare");
939 ParseExactHelper ("10.11:12", c_format, false, false, "10.11:12:00");
940 ParseExactHelper ("10.11:12:13", c_format, false, false, "10.11:12:13");
941 ParseExactHelper ("10:11:12:13", c_format, true, false, "dontcare"); // this is normally accepted in the Parse method
942 ParseExactHelper ("10.11:12:13.6", c_format, false, false, "10.11:12:13.6000000");
943 ParseExactHelper ("10:11:12,6", c_format, true, false, "dontcare");
944 ParseExactHelper ("10:11:12,6", c_format, true, false, "dontcare", french_culture);
945 ParseExactHelper (" 10:11:12.6 ", c_format, false, false, "10:11:12.6000000");
946 ParseExactHelper ("10:12", c_format, false, false, "10:12:00", null, TimeSpanStyles.AssumeNegative);
947 ParseExactHelper ("10:123456789999", c_format, true, false, "dontcare");
949 ParseExactHelper ("10:12", new string [0], true, false, "dontcare");
950 ParseExactHelper ("10:12", new string [] { String.Empty }, true, false, "dontcare");
951 ParseExactHelper ("10:12", new string [] { null }, true, false, "dontcare");
955 public void ParseExactMultipleFormats ()
957 ParseExactHelper ("10:12", new string [] { "G", "g" }, false, false, "10:12:00");
958 ParseExactHelper ("10:12", new string [] { "g", "G" }, false, false, "10:12:00");
959 ParseExactHelper ("7.8:9:10", new string [] { "G", "g" }, true, false, "dontcare");
960 ParseExactHelper ("7.8:9:10", new string [] { "G", "g", "c" }, false, false, "7.08:09:10");
961 ParseExactHelper ("7:8:9:10", new string [] { "c", "g" }, false, false, "7.08:09:10");
962 ParseExactHelper ("7:8:9:10", new string [] { "c", "G" }, true, false, "dontcare");
963 ParseExactHelper ("7.123456789:1", new string [] { "c", "G", "g" }, true, false, "dontcare");
964 ParseExactHelper ("7.123456789:1", new string [] { "G", "g", "c" }, true, false, "dontcare");
965 ParseExactHelper ("1234567890123456", new string [] { "c", "g" }, true, false, "dontcare"); // I'd expect an OverflowException
966 ParseExactHelper ("10:12", new string [] { null, "c", "g" }, true, false, "10:12:00");
967 ParseExactHelper ("10:12", new string [] { String.Empty, "c", "g" }, true, false, "10:12:00");
971 public void ParseExactCustomFormats ()
974 ParseExactHelper ("33", new string [] { "%d" }, false, false, "33.00:00:00");
975 ParseExactHelper ("00", new string [] { "%d" }, false, false, "00:00:00");
976 ParseExactHelper ("33", new string [] { "%dd" }, false, false, "33.00:00:00");
977 ParseExactHelper ("3333", new string [] { "%d" }, false, false, "3333.00:00:00");
978 ParseExactHelper ("3333", new string [] { "%ddd" }, true, false, "3333.00:00:00"); // 'dd' mismatch the digit count
979 ParseExactHelper ("3333", new string [] { "%dddd" }, false, false, "3333.00:00:00");
980 ParseExactHelper ("00033", new string [] { "%ddddd" }, false, false, "33.00:00:00");
981 ParseExactHelper ("00033", new string [] { "%d" }, false, false, "33.00:00:00");
982 ParseExactHelper ("00000003", new string [] { "%dddddddd" }, false, false, "3.00:00:00"); // up to 8 'd'
983 ParseExactHelper ("000000003", new string [] { "%ddddddddd" }, true, false, "dontcare");
984 ParseExactHelper ("33", new string [] { "d" }, true, false, "33.00:00:00"); // This is sort of weird.
985 ParseExactHelper ("33", new string [] { "dd" }, false, false, "33.00:00:00");
986 ParseExactHelper ("-33", new string [] { "%d" }, true, false, "dontcare");
987 ParseExactHelper ("33", new string [] { "%d" }, false, false, "-33.00:00:00", null, TimeSpanStyles.AssumeNegative);
990 ParseExactHelper ("12", new string [] { "%h" }, false, false, "12:00:00");
991 ParseExactHelper ("00", new string [] { "%h" }, false, false, "00:00:00");
992 ParseExactHelper ("012", new string [] { "%h" }, true, false, "dontcare"); // more than 2 digits
993 ParseExactHelper ("00012", new string [] { "%hhhhh" }, true, false, "dontcare");
994 ParseExactHelper ("15", new string [] { "%h" }, false, false, "15:00:00");
995 ParseExactHelper ("24", new string [] { "%h" }, true, false, "dontcare");
996 ParseExactHelper ("15", new string [] { "%hh" }, false, false, "15:00:00");
997 ParseExactHelper ("1", new string [] { "%hh" }, true, false, "dontcare"); // 'hh' but a single digit
998 ParseExactHelper ("01", new string [] { "%hh" }, false, false, "01:00:00");
999 ParseExactHelper ("015", new string [] { "%hhh" }, true, false, "dontcare"); // Too many 'h'
1000 ParseExactHelper ("12", new string [] { "h" }, true, false, "dontcare");
1001 ParseExactHelper ("12", new string [] { "hh" }, false, false, "12:00:00");
1002 ParseExactHelper ("-15", new string [] {"%h"}, true, false, "dontcare"); // Explicit - not accepted
1003 ParseExactHelper ("15", new string [] { "%h" }, false, false, "-15:00:00", null, TimeSpanStyles.AssumeNegative);
1004 ParseExactHelper ("15", new string [] { "%H" }, true, false, "dontcare"); // Uppercase is not accepted
1007 ParseExactHelper ("12", new string [] { "%m" }, false, false, "00:12:00");
1008 ParseExactHelper ("00", new string [] { "%m" }, false, false, "00:00:00");
1009 ParseExactHelper ("60", new string [] { "%m" }, true, false, "dontcare");
1010 ParseExactHelper ("12", new string [] { "%mm" }, false, false, "00:12:00");
1011 ParseExactHelper ("1", new string [] { "%mm" }, true, false, "dontcare");
1012 ParseExactHelper ("12", new string [] { "%mmm" }, true, false, "dontcare");
1013 ParseExactHelper ("12", new string [] { "m" }, true, false, "dontcare");
1014 ParseExactHelper ("12", new string [] { "mm" }, false, false, "00:12:00");
1015 ParseExactHelper ("-12", new string [] { "%m" }, true, false, "dontcare");
1016 ParseExactHelper ("12", new string [] { "%m" }, false, false, "-00:12:00", null, TimeSpanStyles.AssumeNegative);
1017 ParseExactHelper ("12", new string [] { "%M" }, true, false, "dontcare");
1020 ParseExactHelper ("12", new string [] { "%s" }, false, false, "00:00:12");
1021 ParseExactHelper ("00", new string [] { "%s" }, false, false, "00:00:00");
1022 ParseExactHelper ("000", new string [] { "%s" }, true, false, "dontcare");
1023 ParseExactHelper ("12", new string [] { "%ss" }, false, false, "00:00:12");
1024 ParseExactHelper ("12", new string [] { "%sss" }, true, false, "dontcare");
1025 ParseExactHelper ("60", new string [] { "%s" }, true, false, "dontcare");
1026 ParseExactHelper ("-12", new string [] { "%s" }, true, false, "dontcare");
1027 ParseExactHelper ("12", new string [] { "%s" }, false, false, "-00:00:12", null, TimeSpanStyles.AssumeNegative);
1029 // Fractions of seconds - f
1030 ParseExactHelper ("3", new string [] { "%f" }, false, false, "00:00:00.3000000");
1031 ParseExactHelper ("0", new string [] { "%f" }, false, false, "00:00:00");
1032 ParseExactHelper ("03", new string [] { "%f" }, true, false, "dontcare"); // This would work for other elements
1033 ParseExactHelper ("10", new string [] { "%f" }, true, false, "dontcare"); // Only a digit is accepted with '%f'
1034 ParseExactHelper ("3", new string [] { "%ff" }, true, false, "dontcare");
1035 ParseExactHelper ("12", new string [] { "%ff" }, false, false, "00:00:00.1200000");
1036 ParseExactHelper ("123", new string [] { "%ff" }, true, false, "dontcare");
1037 ParseExactHelper ("123", new string [] { "%fff" }, false, false, "00:00:00.1230000");
1038 ParseExactHelper ("1234", new string [] { "%ffff" }, false, false, "00:00:00.1234000");
1039 ParseExactHelper ("1234567", new string [] { "%fffffff" }, false, false, "00:00:00.1234567");
1040 ParseExactHelper ("1234567", new string [] { "%FfFFFFF" }, true, false, "dontcare"); // Mixed f and M
1041 ParseExactHelper ("12345678", new string [] { "%ffffffff" }, true, false, "dontcare");
1042 ParseExactHelper ("0000000", new string [] { "%fffffff" }, false, false, "00:00:00");
1044 // Fractions of second - F
1045 ParseExactHelper ("3", new string [] { "%F" }, false, false, "00:00:00.3000000");
1046 ParseExactHelper ("333", new string [] { "%FFFFF" }, false, false, "00:00:00.3330000");
1047 ParseExactHelper ("1234567", new string [] { "%FFFFFFF" }, false, false, "00:00:00.1234567");
1050 ParseExactHelper ("9:10", new string [] { @"h\:m" }, false, false, "09:10:00");
1051 ParseExactHelper ("9;10", new string [] { @"h\;m" }, false, false, "09:10:00");
1052 ParseExactHelper ("10:9", new string [] { @"m\:h" }, false, false, "09:10:00");
1053 ParseExactHelper ("10:9", new string [] { @"%m\:%h" }, false, false, "09:10:00");
1054 ParseExactHelper ("9 10", new string [] { @"h\ m" }, false, false, "09:10:00");
1055 ParseExactHelper ("9 10", new string [] { @"h\ \ \ m" }, false, false, "09:10:00");
1056 ParseExactHelper (" 9:10 ", new string [] { @"h\:m" }, true, false, "dontcare");
1057 ParseExactHelper ("9:10:11", new string [] { @"h\:m\:s" }, false, false, "09:10:11");
1058 ParseExactHelper ("9:10:11:6", new string [] { @"h\:m\:s\:f" }, false, false, "09:10:11.6000000");
1059 ParseExactHelper ("9:10:11:666", new string [] { @"h\:m\:s\:f" }, true, false, "dontcare"); // fff with 1 digit
1060 ParseExactHelper ("9:10:11:", new string [] { @"h\:m\:s\:F" }, false, false, "09:10:11"); // optional frac of seconds
1061 ParseExactHelper ("9:10:11:", new string [] { @"h\:m\:s\:FF" }, false, false, "09:10:11");
1062 ParseExactHelper ("9:10:11::", new string [] { @"h\:m\:s\:F\:" }, false, false, "09:10:11");
1063 ParseExactHelper ("8:9:10:11:6666666", new string [] { @"d\:h\:m\:s\:fffffff" }, false, false, "8.09:10:11.6666666");
1064 ParseExactHelper ("8:9:10:11:6666666", new string [] { @"d\:h\:m\:s\:fffffff" }, false, false, "-8.09:10:11.6666666",
1065 null, TimeSpanStyles.AssumeNegative);
1066 ParseExactHelper ("9:10", new string [] { @"h\:h" }, true, false, "dontcare"); // Repeated element
1069 ParseExactHelper (" 0 ", new string [] { "%d" }, true, false, "dontcare");
1070 ParseExactHelper (" 0 ", new string [] { " %d " }, true, false, "dontcare");
1071 ParseExactHelper ("0", new string [] { " %d " }, true, false, "dontcare");
1072 ParseExactHelper ("::", new string [] { @"\:\:" }, false, false, "00:00:00"); // funny
1073 ParseExactHelper ("::", new string [] { @"\:\:" }, false, false, "00:00:00", null, TimeSpanStyles.AssumeNegative);
1074 ParseExactHelper (" 0", new string [] { @"\ d" }, false, false, "00:00:00");
1075 ParseExactHelper ("Interval = 12:13:14", new string [] { @"'Interval = 'h\:m\:s" }, false, false, "12:13:14");
1078 void ParseExactHelper (string input, string [] formats, bool format_error, bool overflow_error, string expected,
1079 IFormatProvider formatProvider = null, TimeSpanStyles timeSpanStyles = TimeSpanStyles.None)
1081 bool overflow_exc = false;
1082 bool format_exc = false;
1083 TimeSpan result = TimeSpan.Zero;
1086 result = TimeSpan.ParseExact (input, formats, formatProvider, timeSpanStyles);
1087 } catch (OverflowException) {
1088 overflow_exc = true;
1089 } catch (FormatException) {
1093 Assert.AreEqual (format_error, format_exc, "A1");
1094 Assert.AreEqual (overflow_error, overflow_exc, "A2");
1095 if (!overflow_exc && !format_exc)
1096 Assert.AreEqual (expected, result.ToString ());
1099 // 'Ported' the ParseExact test to use TryParseExact instead.
1101 public void TryParseExact ()
1103 CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
1104 CultureInfo us_culture = CultureInfo.GetCultureInfo ("en-US");
1107 // 'g' format - this is the short and culture sensitive format
1109 string [] g_format = new string [] { "g" };
1110 TryParseExactHelper ("12", g_format, false, "12.00:00:00");
1111 TryParseExactHelper ("11:12", g_format, false, "11:12:00");
1112 TryParseExactHelper ("-11:12", g_format, false, "-11:12:00");
1113 TryParseExactHelper ("25:13", g_format, true, "dontcare");
1114 TryParseExactHelper ("11:66", g_format, true, "dontcare"); // I'd have expected OverflowExc here
1115 TryParseExactHelper ("11:12:13", g_format, false, "11:12:13");
1116 TryParseExactHelper ("-11:12:13", g_format, false, "-11:12:13");
1117 TryParseExactHelper ("10.11:12:13", g_format, true, "dontcare"); // this should work as well
1118 TryParseExactHelper ("10.11:12:13", g_format, true, "dontcare", us_culture);
1119 TryParseExactHelper ("10.11:12:13", g_format, true, "dontcare", CultureInfo.InvariantCulture);
1120 TryParseExactHelper ("10:11:12:66", g_format, true, "dontcare");
1121 TryParseExactHelper ("10:11:12:13", g_format, false, "10.11:12:13");
1122 TryParseExactHelper ("11:12:13.6", g_format, false, "11:12:13.6000000", CultureInfo.InvariantCulture);
1123 TryParseExactHelper ("11:12:13,6", g_format, false, "11:12:13.6000000", french_culture);
1124 TryParseExactHelper ("10:11:12:13.6", g_format, false, "10.11:12:13.6000000", us_culture);
1125 TryParseExactHelper (" 10:11:12:13.6 ", g_format, false, "10.11:12:13.6000000", us_culture);
1126 TryParseExactHelper ("10:11", g_format, false, "10:11:00", null, TimeSpanStyles.None);
1127 TryParseExactHelper ("10:11", g_format, false, "10:11:00", null, TimeSpanStyles.AssumeNegative); // no effect
1132 string [] G_format = new string [] { "G" };
1133 TryParseExactHelper ("9:10:12", G_format, true, "dontcare");
1134 TryParseExactHelper ("9:10:12.6", G_format, true, "dontcare");
1135 TryParseExactHelper ("3.9:10:12", G_format, true, "dontcare");
1136 TryParseExactHelper ("3.9:10:12.153", G_format, true, "dontcare"); // this should be valid...
1137 TryParseExactHelper ("3:9:10:12.153", G_format, false, "3.09:10:12.1530000", us_culture);
1138 TryParseExactHelper ("0:9:10:12.153", G_format, false, "09:10:12.1530000", us_culture);
1139 TryParseExactHelper ("03:09:10:12.153", G_format, false, "3.09:10:12.1530000", us_culture);
1140 TryParseExactHelper ("003:009:0010:0012.00153", G_format, false, "3.09:10:12.0015300", us_culture);
1141 TryParseExactHelper ("3:9:10:66.153", G_format, true, "dontcare"); // seconds out of range
1142 TryParseExactHelper ("3:9:10:12.153", G_format, true, "dontcare", french_culture); // fr-FR uses ',' as decimal separator
1143 TryParseExactHelper ("3:9:10:12,153", G_format, false, "3.09:10:12.1530000", french_culture);
1144 TryParseExactHelper (" 3:9:10:12.153 ", G_format, false, "3.09:10:12.1530000", us_culture);
1145 TryParseExactHelper ("3:9:10:13.153", G_format, false, "3.09:10:13.1530000", us_culture, TimeSpanStyles.AssumeNegative);
1148 string [] c_format = new string [] { "c" };
1149 TryParseExactHelper ("12", c_format, false, "12.00:00:00");
1150 TryParseExactHelper ("12:11", c_format, false, "12:11:00");
1151 TryParseExactHelper ("12:66", c_format, true, "dontcare");
1152 TryParseExactHelper ("10.11:12", c_format, false, "10.11:12:00");
1153 TryParseExactHelper ("10.11:12:13", c_format, false, "10.11:12:13");
1154 TryParseExactHelper ("10:11:12:13", c_format, true, "dontcare"); // this is normally accepted in the Parse method
1155 TryParseExactHelper ("10.11:12:13.6", c_format, false, "10.11:12:13.6000000");
1156 TryParseExactHelper ("10:11:12,6", c_format, true, "dontcare");
1157 TryParseExactHelper ("10:11:12,6", c_format, true, "dontcare", french_culture);
1158 TryParseExactHelper (" 10:11:12.6 ", c_format, false, "10:11:12.6000000");
1159 TryParseExactHelper ("10:12", c_format, false, "10:12:00", null, TimeSpanStyles.AssumeNegative);
1160 TryParseExactHelper ("10:123456789999", c_format, true, "dontcare");
1162 TryParseExactHelper ("10:12", new string [0], true, "dontcare");
1163 TryParseExactHelper ("10:12", new string [] { String.Empty }, true, "dontcare");
1164 TryParseExactHelper ("10:12", new string [] { null }, true, "dontcare");
1166 TryParseExactHelper (null, new string [] { null }, true, "dontcare");
1169 void TryParseExactHelper (string input, string [] formats, bool error, string expected, IFormatProvider formatProvider = null,
1170 TimeSpanStyles styles = TimeSpanStyles.None)
1175 success = TimeSpan.TryParseExact (input, formats, formatProvider, styles, out result);
1176 Assert.AreEqual (!error, success);
1178 Assert.AreEqual (expected, result.ToString ());
1182 public void ParseExactExceptions ()
1185 TimeSpan.ParseExact (null, "g", null);
1186 Assert.Fail ("#A1");
1187 } catch (ArgumentNullException) {
1191 TimeSpan.ParseExact ("10:12", (string)null, null);
1192 Assert.Fail ("#A2");
1193 } catch (ArgumentNullException) {
1197 TimeSpan.ParseExact ("10:12", (string [])null, null);
1198 Assert.Fail ("#A3");
1199 } catch (ArgumentNullException) {
1204 public void ToStringOverloads ()
1206 TimeSpan ts = new TimeSpan (1, 2, 3, 4, 6);
1208 // Simple version - culture invariant
1209 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString (), "#A1");
1210 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString ("c"), "#A2");
1211 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString (null), "#A3");
1212 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString (String.Empty), "#A4");
1215 // IFormatProvider ones - use a culture changing numeric format.
1216 // Also, we use fr-FR as culture, since it uses some elements different to invariant culture
1218 CultureInfo culture = CultureInfo.GetCultureInfo ("fr-FR");
1220 Assert.AreEqual ("1:2:03:04,006", ts.ToString ("g", culture), "#B1");
1221 Assert.AreEqual ("1:02:03:04,0060000", ts.ToString ("G", culture), "#B2");
1222 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString ("c", culture), "#B3"); // 'c' format ignores CultureInfo
1223 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString ("t", culture), "#B4"); // 't' and 'T' are the same as 'c'
1224 Assert.AreEqual("1.02:03:04.0060000", ts.ToString("T", culture), "#B5");
1226 ts = new TimeSpan (4, 5, 6);
1227 Assert.AreEqual ("4:05:06", ts.ToString ("g", culture), "#C1");
1228 Assert.AreEqual ("0:04:05:06,0000000", ts.ToString ("G", culture), "#C2");
1232 public void ToStringCustomFormats ()
1234 TimeSpan ts = new TimeSpan (1, 3, 5, 7);
1236 Assert.AreEqual ("1", ts.ToString ("%d"), "#A0");
1237 Assert.AreEqual ("3", ts.ToString ("%h"), "#A1");
1238 Assert.AreEqual ("5", ts.ToString ("%m"), "#A2");
1239 Assert.AreEqual ("7", ts.ToString ("%s"), "#A3");
1240 Assert.AreEqual ("0", ts.ToString ("%f"), "#A4");
1241 Assert.AreEqual (String.Empty, ts.ToString ("%F"), "#A5"); // Nothing to display
1243 Assert.AreEqual ("01", ts.ToString ("dd"), "#B0");
1244 Assert.AreEqual ("00000001", ts.ToString ("dddddddd"), "#B1");
1245 Assert.AreEqual ("03", ts.ToString ("hh"), "#B2");
1246 Assert.AreEqual ("05", ts.ToString ("mm"), "#B3");
1247 Assert.AreEqual ("07", ts.ToString ("ss"), "#B4");
1248 Assert.AreEqual ("00", ts.ToString ("ff"), "#B5");
1249 Assert.AreEqual ("0000000", ts.ToString ("fffffff"), "#B6");
1250 Assert.AreEqual (String.Empty, ts.ToString ("FF"), "#B7");
1252 Assert.AreEqual ("01;03;05", ts.ToString (@"dd\;hh\;mm"), "#C0");
1253 Assert.AreEqual ("05 07", ts.ToString (@"mm\ ss"), "#C1");
1254 Assert.AreEqual ("05 07 ", ts.ToString (@"mm\ ss\ FF"), "#C2");
1255 Assert.AreEqual ("Result = 3 hours with 5 minutes and 7 seconds",
1256 ts.ToString (@"'Result = 'h' hours with 'm' minutes and 's' seconds'"), "#C3");
1257 Assert.AreEqual (" ", ts.ToString (@"\ \ "), "#C4");
1259 ts = new TimeSpan (1, 3, 5, 7, 153);
1260 Assert.AreEqual ("1", ts.ToString ("%F"), "#D0");
1261 Assert.AreEqual ("15", ts.ToString ("FF"), "#D1"); // Don't use %, as the parser gets confused here
1262 Assert.AreEqual ("153", ts.ToString ("FFFFFFF"), "#D2");
1264 // Negative values are shown without sign
1265 ts = new TimeSpan (-1, -3, -5);
1266 Assert.AreEqual ("1", ts.ToString ("%h"), "#E0");
1267 Assert.AreEqual ("3", ts.ToString ("%m"), "#E1");
1268 Assert.AreEqual ("5", ts.ToString ("%s"), "#E2");
1270 ts = new TimeSpan (123456789);
1271 Assert.AreEqual ("12.3", ts.ToString ("s\\.f"), "#F0");
1272 Assert.AreEqual ("12.3", ts.ToString ("s\\.F"), "#F1");
1273 Assert.AreEqual ("12.3456789", ts.ToString ("s\\.fffffff"), "#F2");
1274 Assert.AreEqual ("12.345678", ts.ToString ("s\\.ffffff"), "#F3");
1276 ts = new TimeSpan (1234);
1277 Assert.AreEqual ("0.000123", ts.ToString ("s\\.ffffff"), "#G0");
1278 Assert.AreEqual ("0.0001", ts.ToString ("s\\.ffff"), "#G1");
1279 Assert.AreEqual ("0.", ts.ToString ("s\\.F"), "#G2");
1280 Assert.AreEqual ("0.", ts.ToString ("s\\.FFF"), "#G3");
1282 ts = TimeSpan.FromSeconds (0.05);
1283 Assert.AreEqual (".0", ts.ToString ("\\.f"), "#H0");
1284 Assert.AreEqual (".", ts.ToString ("\\.F"), "#H1");
1288 public void ToStringOverloadsErrors ()
1290 TimeSpan ts = new TimeSpan (10, 10, 10);
1294 result = ts.ToString ("non-valid");
1296 } catch (FormatException) {
1300 result = ts.ToString ("C");
1302 } catch (FormatException) {
1309 } catch (FormatException) {
1314 ts.ToString ("d"); // Missing % for single char
1316 } catch (FormatException)
1322 ts.ToString ("ddddddddd");
1324 } catch (FormatException)
1330 ts.ToString ("hhh");
1332 } catch (FormatException)
1338 ts.ToString ("ffffffff");
1340 } catch (FormatException)