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);
33 public void TestCtors ()
35 TimeSpan t1 = new TimeSpan (1234567890);
37 Assert.AreEqual ("00:02:03.4567890", t1.ToString (), "A1");
38 t1 = new TimeSpan (1,2,3);
39 Assert.AreEqual ("01:02:03", t1.ToString (), "A2");
40 t1 = new TimeSpan (1,2,3,4);
41 Assert.AreEqual ("1.02:03:04", t1.ToString (), "A3");
42 t1 = new TimeSpan (1,2,3,4,5);
43 Assert.AreEqual ("1.02:03:04.0050000", t1.ToString (), "A4");
44 t1 = new TimeSpan (-1,2,-3,4,-5);
45 Assert.AreEqual ("-22:02:56.0050000", t1.ToString (), "A5");
46 t1 = new TimeSpan (0,25,0,0,0);
47 Assert.AreEqual ("1.01:00:00", t1.ToString (), "A6");
51 [ExpectedException (typeof (ArgumentOutOfRangeException))]
52 public void DaysOverflow ()
54 int days = (int) (Int64.MaxValue / TimeSpan.TicksPerDay) + 1;
55 TimeSpan ts = new TimeSpan (days, 0, 0, 0, 0);
60 [ExpectedException (typeof (ArgumentOutOfRangeException))]
61 [Category ("NotWorking")]
63 public void TemporaryOverflow ()
65 // calculating part of this results in overflow (days)
66 // but the negative hours, minutes, seconds & ms correct this
67 int days = (int) (Int64.MaxValue / TimeSpan.TicksPerDay) + 1;
68 TimeSpan ts = new TimeSpan (days, Int32.MinValue, Int32.MinValue, Int32.MinValue, Int32.MinValue);
69 Assert.AreEqual (10650320, ts.Days, "Days");
70 Assert.AreEqual (0, ts.Hours, "Hours");
71 Assert.AreEqual (14, ts.Minutes, "Minutes");
72 Assert.AreEqual (28, ts.Seconds, "Seconds");
73 Assert.AreEqual (352, ts.Milliseconds, "Milliseconds");
74 Assert.AreEqual (9201876488683520000, ts.Ticks, "Ticks");
79 [ExpectedException (typeof (ArgumentOutOfRangeException))]
80 [Category ("NotWorking")]
82 public void NoOverflowInHoursMinsSecondsMS ()
84 TimeSpan ts = new TimeSpan (0, Int32.MaxValue, Int32.MaxValue, Int32.MaxValue, Int32.MaxValue);
85 Assert.AreEqual (24879, ts.Days, "Days");
86 Assert.AreEqual (22, ts.Hours, "Hours");
87 Assert.AreEqual (44, ts.Minutes, "Minutes");
88 Assert.AreEqual (30, ts.Seconds, "Seconds");
89 Assert.AreEqual (647, ts.Milliseconds, "Milliseconds");
90 Assert.AreEqual (21496274706470000, ts.Ticks, "Ticks");
94 [ExpectedException (typeof (ArgumentOutOfRangeException))]
95 public void MaxDays ()
97 new TimeSpan (Int32.MaxValue, 0, 0, 0, 0);
101 [ExpectedException (typeof (ArgumentOutOfRangeException))]
102 public void MinDays ()
104 new TimeSpan (Int32.MinValue, 0, 0, 0, 0);
108 [Ignore ("too long")]
109 public void MaxHours_TooLong ()
111 // LAMESPEC: the highest hours are "special"
112 for (int i=0; i < 596523; i++) {
113 TimeSpan ts = new TimeSpan (0, Int32.MaxValue - i, 0, 0, 0);
115 string prefix = i.ToString () + '-';
116 Assert.AreEqual (-(h / 24), ts.Days, prefix + "Days");
117 Assert.AreEqual (-(h % 24), ts.Hours, prefix + "Hours");
118 Assert.AreEqual (0, ts.Minutes, prefix + "Minutes");
119 Assert.AreEqual (0, ts.Seconds, prefix + "Seconds");
120 Assert.AreEqual (0, ts.Milliseconds, prefix + "Milliseconds");
121 Assert.AreEqual (-36000000000 * h, ts.Ticks, prefix + "Ticks");
127 [ExpectedException (typeof (ArgumentOutOfRangeException))]
128 [Category ("NotWorking")]
130 public void MaxHours ()
132 // LAMESPEC: the highest hours are "special"
133 TimeSpan ts = new TimeSpan (0, Int32.MaxValue, 0, 0, 0);
134 Assert.AreEqual (0, ts.Days, "Max-Days");
135 Assert.AreEqual (-1, ts.Hours, "Max-Hours");
136 Assert.AreEqual (0, ts.Minutes, "Max-Minutes");
137 Assert.AreEqual (0, ts.Seconds, "Max-Seconds");
138 Assert.AreEqual (0, ts.Milliseconds, "Max-Milliseconds");
139 Assert.AreEqual (-36000000000, ts.Ticks, "Max-Ticks");
141 ts = new TimeSpan (0, Int32.MaxValue - 596522, 0, 0, 0);
142 Assert.AreEqual (-24855, ts.Days, "Days");
143 Assert.AreEqual (-3, ts.Hours, "Hours");
144 Assert.AreEqual (0, ts.Minutes, "Minutes");
145 Assert.AreEqual (0, ts.Seconds, "Seconds");
146 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
147 Assert.AreEqual (-21474828000000000, ts.Ticks, "Ticks");
152 [ExpectedException (typeof (ArgumentOutOfRangeException))]
153 [Category ("NotWorking")]
155 public void MaxHours_BreakPoint ()
157 TimeSpan ts = new TimeSpan (0, Int32.MaxValue - 596523, 0, 0, 0);
158 Assert.AreEqual (24855, ts.Days, "Days");
159 Assert.AreEqual (2, ts.Hours, "Hours");
160 Assert.AreEqual (28, ts.Minutes, "Minutes");
161 Assert.AreEqual (16, ts.Seconds, "Seconds");
162 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
163 Assert.AreEqual (21474808960000000, ts.Ticks, "Ticks");
167 [Ignore ("too long")]
168 public void MinHours_TooLong ()
170 // LAMESPEC: the lowest hours are "special"
171 for (int i=Int32.MinValue; i < -2146887124; i++) {
172 TimeSpan ts = new TimeSpan (0, i, 0, 0, 0);
173 int h = i + Int32.MaxValue + 1;
174 string prefix = i.ToString () + '-';
175 Assert.AreEqual ((h / 24), ts.Days, prefix + "Days");
176 Assert.AreEqual ((h % 24), ts.Hours, prefix + "Hours");
177 Assert.AreEqual (0, ts.Minutes, prefix + "Minutes");
178 Assert.AreEqual (0, ts.Seconds, prefix + "Seconds");
179 Assert.AreEqual (0, ts.Milliseconds, prefix + "Milliseconds");
180 Assert.AreEqual (36000000000 * h, ts.Ticks, prefix + "Ticks");
186 [Category ("NotWorking")]
188 public void MinHours ()
191 TimeSpan ts = new TimeSpan (0, -256204778, 0, 0, 0);
192 Assert.AreEqual (-10675199, ts.Days, "Days");
193 Assert.AreEqual (-2, ts.Hours, "Hours");
194 Assert.AreEqual (0, ts.Minutes, "Minutes");
195 Assert.AreEqual (0, ts.Seconds, "Seconds");
196 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
197 Assert.AreEqual (-9223372008000000000, ts.Ticks, "Ticks");
199 // LAMESPEC: the lowest hours are "special"
200 TimeSpan ts = new TimeSpan (0, Int32.MinValue, 0, 0, 0);
201 Assert.AreEqual (0, ts.Days, "Min-Days");
202 Assert.AreEqual (0, ts.Hours, "Min-Hours");
203 Assert.AreEqual (0, ts.Minutes, "Min-Minutes");
204 Assert.AreEqual (0, ts.Seconds, "Min-Seconds");
205 Assert.AreEqual (0, ts.Milliseconds, "Min-Milliseconds");
206 Assert.AreEqual (0, ts.Ticks, "Min-Ticks");
208 ts = new TimeSpan (0, -2146887125, 0, 0, 0);
209 Assert.AreEqual (24855, ts.Days, "Days");
210 Assert.AreEqual (3, ts.Hours, "Hours");
211 Assert.AreEqual (0, ts.Minutes, "Minutes");
212 Assert.AreEqual (0, ts.Seconds, "Seconds");
213 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
214 Assert.AreEqual (21474828000000000, ts.Ticks, "Ticks");
220 [ExpectedException (typeof (ArgumentOutOfRangeException))]
221 [Category ("NotWorking")]
223 public void MinHours_BreakPoint ()
225 TimeSpan ts = new TimeSpan (0, -2146887124, 0, 0, 0);
226 Assert.AreEqual (-24855, ts.Days, "Days");
227 Assert.AreEqual (-2, ts.Hours, "Hours");
228 Assert.AreEqual (-28, ts.Minutes, "Minutes");
229 Assert.AreEqual (-16, ts.Seconds, "Seconds");
230 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
231 Assert.AreEqual (-21474808960000000, ts.Ticks, "Ticks");
235 [Ignore ("too long")]
236 public void MaxMinutes_TooLong ()
238 // LAMESPEC: the highest minutes are "special"
239 for (int i=0; i < 35791394; i++) {
240 TimeSpan ts = new TimeSpan (0, 0, Int32.MaxValue - i, 0, 0);
242 string prefix = i.ToString () + '-';
243 Assert.AreEqual ((h / 1440), ts.Days, prefix + "Days");
244 Assert.AreEqual (((h / 60) % 24), ts.Hours, prefix + "Hours");
245 Assert.AreEqual ((h % 60), ts.Minutes, prefix + "Minutes");
246 Assert.AreEqual (0, ts.Seconds, prefix + "Seconds");
247 Assert.AreEqual (0, ts.Milliseconds, prefix + "Milliseconds");
248 Assert.AreEqual ((600000000L * h), ts.Ticks, prefix + "Ticks");
254 [Category ("NotWorking")]
256 public void MaxMinutes ()
260 ts = new TimeSpan (0, 0, 256204778, 0, 0);
261 Assert.AreEqual (177919, ts.Days, "Max-Days");
262 Assert.AreEqual (23, ts.Hours, "Max-Hours");
263 Assert.AreEqual (38, ts.Minutes, "Max-Minutes");
264 Assert.AreEqual (0, ts.Seconds, "Max-Seconds");
265 Assert.AreEqual (0, ts.Milliseconds, "Max-Milliseconds");
266 Assert.AreEqual (153722866800000000, ts.Ticks, "Max-Ticks");
268 // LAMESPEC: the highest minutes are "special"
269 ts = new TimeSpan (0, 0, Int32.MaxValue, 0, 0);
270 Assert.AreEqual (0, ts.Days, "Max-Days");
271 Assert.AreEqual (0, ts.Hours, "Max-Hours");
272 Assert.AreEqual (-1, ts.Minutes, "Max-Minutes");
273 Assert.AreEqual (0, ts.Seconds, "Max-Seconds");
274 Assert.AreEqual (0, ts.Milliseconds, "Max-Milliseconds");
275 Assert.AreEqual (-600000000, ts.Ticks, "Max-Ticks");
277 ts = new TimeSpan (0, 0, Int32.MaxValue - 35791393, 0, 0);
278 Assert.AreEqual (-24855, ts.Days, "Days");
279 Assert.AreEqual (-3, ts.Hours, "Hours");
280 Assert.AreEqual (-14, ts.Minutes, "Minutes");
281 Assert.AreEqual (0, ts.Seconds, "Seconds");
282 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
283 Assert.AreEqual (-21474836400000000, ts.Ticks, "Ticks");
289 [ExpectedException (typeof (ArgumentOutOfRangeException))]
290 [Category ("NotWorking")]
292 public void MaxMinutes_BreakPoint ()
294 TimeSpan ts = new TimeSpan (0, Int32.MaxValue - 35791394, 0, 0, 0);
295 Assert.AreEqual (0, ts.Days, "Days");
296 Assert.AreEqual (0, ts.Hours, "Hours");
297 Assert.AreEqual (-52, ts.Minutes, "Minutes");
298 Assert.AreEqual (0, ts.Seconds, "Seconds");
299 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
300 Assert.AreEqual (-31200000000, ts.Ticks, "Ticks");
304 [Ignore ("too long")]
305 public void MinMinutes_TooLong ()
307 // LAMESPEC: the highest minutes are "special"
308 for (int i=Int32.MinValue; i < -2111692253; i++) {
309 TimeSpan ts = new TimeSpan (0, 0, i, 0, 0);
310 long h = i + Int32.MaxValue + 1;
311 string prefix = i.ToString () + '-';
312 Assert.AreEqual ((h / 1440), ts.Days, prefix + "Days");
313 Assert.AreEqual (((h / 60) % 24), ts.Hours, prefix + "Hours");
314 Assert.AreEqual ((h % 60), ts.Minutes, prefix + "Minutes");
315 Assert.AreEqual (0, ts.Seconds, prefix + "Seconds");
316 Assert.AreEqual (0, ts.Milliseconds, prefix + "Milliseconds");
317 Assert.AreEqual ((600000000L * h), ts.Ticks, prefix + "Ticks");
323 [Category ("NotWorking")]
325 public void MinMinutes ()
329 ts = new TimeSpan (0, 0, Int32.MinValue, 0, 0);
330 Assert.AreEqual (-1491308, ts.Days, "Days");
331 Assert.AreEqual (-2, ts.Hours, "Hours");
332 Assert.AreEqual (-8, ts.Minutes, "Minutes");
333 Assert.AreEqual (0, ts.Seconds, "Seconds");
334 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
335 Assert.AreEqual (-1288490188800000000, ts.Ticks, "Ticks");
337 // LAMESPEC: the highest minutes are "special"
338 ts = new TimeSpan (0, 0, Int32.MinValue, 0, 0);
339 Assert.AreEqual (0, ts.Days, "Min-Days");
340 Assert.AreEqual (0, ts.Hours, "Min-Hours");
341 Assert.AreEqual (0, ts.Minutes, "Min-Minutes");
342 Assert.AreEqual (0, ts.Seconds, "Min-Seconds");
343 Assert.AreEqual (0, ts.Milliseconds, "Min-Milliseconds");
344 Assert.AreEqual (0, ts.Ticks, "Min-Ticks");
346 ts = new TimeSpan (0, 0, -2111692254, 0, 0);
347 Assert.AreEqual (24855, ts.Days, "Days");
348 Assert.AreEqual (3, ts.Hours, "Hours");
349 Assert.AreEqual (14, ts.Minutes, "Minutes");
350 Assert.AreEqual (0, ts.Seconds, "Seconds");
351 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
352 Assert.AreEqual (21474836400000000, ts.Ticks, "Ticks");
358 [Category ("NotWorking")]
360 public void MinMinutes_BreakPoint ()
363 TimeSpan ts = new TimeSpan (0, 0, -2111692253, 0, 0);
364 Assert.AreEqual (-1466452, ts.Days, "Days");
365 Assert.AreEqual (-22, ts.Hours, "Hours");
366 Assert.AreEqual (-53, ts.Minutes, "Minutes");
367 Assert.AreEqual (-0, ts.Seconds, "Seconds");
368 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
369 Assert.AreEqual (-1267015351800000000, ts.Ticks, "Ticks");
371 TimeSpan ts = new TimeSpan (0, 0, -2111692253, 0, 0);
372 Assert.AreEqual (-24855, ts.Days, "Days");
373 Assert.AreEqual (-3, ts.Hours, "Hours");
374 Assert.AreEqual (-13, ts.Minutes, "Minutes");
375 Assert.AreEqual (-16, ts.Seconds, "Seconds");
376 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
377 Assert.AreEqual (-21474835960000000, ts.Ticks, "Ticks");
382 public void MaxSeconds ()
384 TimeSpan ts = new TimeSpan (0, 0, 0, Int32.MaxValue, 0);
385 Assert.AreEqual (24855, ts.Days, "Days");
386 Assert.AreEqual (3, ts.Hours, "Hours");
387 Assert.AreEqual (14, ts.Minutes, "Minutes");
388 Assert.AreEqual (7, ts.Seconds, "Seconds");
389 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
390 Assert.AreEqual (21474836470000000, ts.Ticks, "Ticks");
394 public void MinSeconds ()
396 TimeSpan ts = new TimeSpan (0, 0, 0, Int32.MinValue, 0);
397 Assert.AreEqual (-24855, ts.Days, "Days");
398 Assert.AreEqual (-3, ts.Hours, "Hours");
399 Assert.AreEqual (-14, ts.Minutes, "Minutes");
400 Assert.AreEqual (-8, ts.Seconds, "Seconds");
401 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
402 Assert.AreEqual (-21474836480000000, ts.Ticks, "Ticks");
406 public void MaxMilliseconds ()
408 TimeSpan ts = new TimeSpan (0, 0, 0, 0, Int32.MaxValue);
409 Assert.AreEqual (24, ts.Days, "Days");
410 Assert.AreEqual (20, ts.Hours, "Hours");
411 Assert.AreEqual (31, ts.Minutes, "Minutes");
412 Assert.AreEqual (23, ts.Seconds, "Seconds");
413 Assert.AreEqual (647, ts.Milliseconds, "Milliseconds");
414 Assert.AreEqual (21474836470000, ts.Ticks, "Ticks");
418 public void MinMilliseconds ()
420 TimeSpan ts = new TimeSpan (0, 0, 0, 0, Int32.MinValue);
421 Assert.AreEqual (-24, ts.Days, "Days");
422 Assert.AreEqual (-20, ts.Hours, "Hours");
423 Assert.AreEqual (-31, ts.Minutes, "Minutes");
424 Assert.AreEqual (-23, ts.Seconds, "Seconds");
425 Assert.AreEqual (-648, ts.Milliseconds, "Milliseconds");
426 Assert.AreEqual (-21474836480000, ts.Ticks, "Ticks");
430 public void NegativeTimeSpan ()
432 TimeSpan ts = new TimeSpan (-23, -59, -59);
433 Assert.AreEqual (0, ts.Days, "Days");
434 Assert.AreEqual (-23, ts.Hours, "Hours");
435 Assert.AreEqual (-59, ts.Minutes, "Minutes");
436 Assert.AreEqual (-59, ts.Seconds, "Seconds");
437 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
438 Assert.AreEqual (-863990000000, ts.Ticks, "Ticks");
441 public void TestProperties ()
443 TimeSpan t1 = new TimeSpan (1,2,3,4,5);
446 Assert.AreEqual (1, t1.Days, "A1");
447 Assert.AreEqual (2, t1.Hours, "A2");
448 Assert.AreEqual (3, t1.Minutes, "A3");
449 Assert.AreEqual (4, t1.Seconds, "A4");
450 Assert.AreEqual (5, t1.Milliseconds, "A5");
451 Assert.AreEqual (-1, t2.Days, "A6");
452 Assert.AreEqual (-2, t2.Hours, "A7");
453 Assert.AreEqual (-3, t2.Minutes, "A8");
454 Assert.AreEqual (-4, t2.Seconds, "A9");
455 Assert.AreEqual (-5, t2.Milliseconds, "A10");
458 public void TestAdd ()
460 TimeSpan t1 = new TimeSpan (2,3,4,5,6);
461 TimeSpan t2 = new TimeSpan (1,2,3,4,5);
462 TimeSpan t3 = t1 + t2;
463 TimeSpan t4 = t1.Add (t2);
467 Assert.AreEqual (3, t3.Days, "A1");
468 Assert.AreEqual (5, t3.Hours, "A2");
469 Assert.AreEqual (7, t3.Minutes, "A3");
470 Assert.AreEqual (9, t3.Seconds, "A4");
471 Assert.AreEqual (11, t3.Milliseconds, "A5");
472 Assert.AreEqual ("3.05:07:09.0110000", t4.ToString (), "A6");
475 t5 = TimeSpan.MaxValue + new TimeSpan (1);
478 catch (OverflowException)
482 Assert.IsTrue (exception, "A7");
485 public void TestCompare ()
487 TimeSpan t1 = new TimeSpan (-1);
488 TimeSpan t2 = new TimeSpan (1);
492 Assert.AreEqual (-1, TimeSpan.Compare (t1, t2), "A1");
493 Assert.AreEqual (1, TimeSpan.Compare (t2, t1), "A2");
494 Assert.AreEqual (0, TimeSpan.Compare (t2, t2), "A3");
495 Assert.AreEqual (-1, TimeSpan.Compare (TimeSpan.MinValue, TimeSpan.MaxValue), "A4");
496 Assert.AreEqual (-1, t1.CompareTo (t2), "A5");
497 Assert.AreEqual (1, t2.CompareTo (t1), "A6");
498 Assert.AreEqual (0, t2.CompareTo (t2), "A7");
499 Assert.AreEqual (-1, TimeSpan.Compare (TimeSpan.MinValue, TimeSpan.MaxValue), "A8");
501 Assert.AreEqual (1, TimeSpan.Zero.CompareTo (null), "A9");
505 res = TimeSpan.Zero.CompareTo("");
508 catch (ArgumentException)
512 Assert.IsTrue (exception, "A10");
514 Assert.AreEqual (false, t1 == t2, "A11");
515 Assert.AreEqual (false, t1 > t2, "A12");
516 Assert.AreEqual (false, t1 >= t2, "A13");
517 Assert.AreEqual (true, t1 != t2, "A14");
518 Assert.AreEqual (true, t1 < t2, "A15");
519 Assert.AreEqual (true, t1 <= t2, "A16");
523 [ExpectedException (typeof (OverflowException))]
524 public void NoNegateMinValue() {
525 TimeSpan t1 = TimeSpan.MinValue.Negate ();
528 public void TestNegateAndDuration ()
533 Assert.AreEqual ("-00:00:00.0012345", new TimeSpan (12345).Negate ().ToString (), "A1");
534 Assert.AreEqual ("00:00:00.0012345", new TimeSpan (-12345).Duration ().ToString (), "A2");
538 t1 = TimeSpan.MinValue.Duration ();
541 catch (OverflowException) {
544 Assert.IsTrue (exception, "A4");
546 Assert.AreEqual ("-00:00:00.0000077", (-(new TimeSpan (77))).ToString (), "A5");
547 Assert.AreEqual ("00:00:00.0000077", (+(new TimeSpan(77))).ToString(), "A6");
550 public void TestEquals ()
552 TimeSpan t1 = new TimeSpan (1);
553 TimeSpan t2 = new TimeSpan (2);
554 string s = "justastring";
556 Assert.AreEqual (true, t1.Equals (t1), "A1");
557 Assert.AreEqual (false, t1.Equals (t2), "A2");
558 Assert.AreEqual (false, t1.Equals (s), "A3");
559 Assert.AreEqual (false, t1.Equals (null), "A4");
560 Assert.AreEqual (true, TimeSpan.Equals (t1, t1), "A5");
561 Assert.AreEqual (false, TimeSpan.Equals (t1, t2), "A6");
562 Assert.AreEqual (false, TimeSpan.Equals (t1, null), "A7");
563 Assert.AreEqual (false, TimeSpan.Equals (t1, s), "A8");
564 Assert.AreEqual (false, TimeSpan.Equals (s, t2), "A9");
565 Assert.AreEqual (true, TimeSpan.Equals (null, null), "A10");
568 public void TestFromXXXX ()
570 Assert.AreEqual ("12.08:16:48", TimeSpan.FromDays (12.345).ToString (), "A1");
571 Assert.AreEqual ("12:20:42", TimeSpan.FromHours (12.345).ToString (), "A2");
572 Assert.AreEqual ("00:12:20.7000000", TimeSpan.FromMinutes (12.345).ToString (), "A3");
573 Assert.AreEqual ("00:00:12.3450000", TimeSpan.FromSeconds (12.345).ToString (), "A4");
574 Assert.AreEqual ("00:00:00.0120000", TimeSpan.FromMilliseconds (12.345).ToString (), "A5");
575 Assert.AreEqual ("00:00:00.0012345", TimeSpan.FromTicks (12345).ToString (), "A6");
579 [ExpectedException (typeof (OverflowException))]
580 public void FromDays_MinValue ()
582 TimeSpan.FromDays (Double.MinValue);
586 [ExpectedException (typeof (OverflowException))]
587 public void FromDays_MaxValue ()
589 TimeSpan.FromDays (Double.MaxValue);
593 [ExpectedException (typeof (ArgumentException))]
594 public void FromDays_NaN ()
596 TimeSpan.FromDays (Double.NaN);
600 [ExpectedException (typeof (OverflowException))]
601 public void FromDays_PositiveInfinity ()
603 // LAMESPEC: Document to return TimeSpan.MaxValue
604 Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.FromDays (Double.PositiveInfinity));
608 [ExpectedException (typeof (OverflowException))]
609 public void FromDays_NegativeInfinity ()
611 // LAMESPEC: Document to return TimeSpan.MinValue
612 Assert.AreEqual (TimeSpan.MinValue, TimeSpan.FromDays (Double.NegativeInfinity));
616 [ExpectedException (typeof (OverflowException))]
617 public void FromHours_MinValue ()
619 TimeSpan.FromHours (Double.MinValue);
623 [ExpectedException (typeof (OverflowException))]
624 public void FromHours_MaxValue ()
626 TimeSpan.FromHours (Double.MaxValue);
630 [ExpectedException (typeof (ArgumentException))]
631 public void FromHours_NaN ()
633 TimeSpan.FromHours (Double.NaN);
637 [ExpectedException (typeof (OverflowException))]
638 public void FromHours_PositiveInfinity ()
640 // LAMESPEC: Document to return TimeSpan.MaxValue
641 Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.FromHours (Double.PositiveInfinity));
645 [ExpectedException (typeof (OverflowException))]
646 public void FromHours_NegativeInfinity ()
648 // LAMESPEC: Document to return TimeSpan.MinValue
649 Assert.AreEqual (TimeSpan.MinValue, TimeSpan.FromHours (Double.NegativeInfinity));
653 [ExpectedException (typeof (OverflowException))]
654 public void FromMilliseconds_MinValue ()
656 TimeSpan.FromMilliseconds (Double.MinValue);
660 [ExpectedException (typeof (OverflowException))]
661 public void FromMilliseconds_MaxValue ()
663 TimeSpan.FromMilliseconds (Double.MaxValue);
667 [ExpectedException (typeof (ArgumentException))]
668 public void FromMilliseconds_NaN ()
670 TimeSpan.FromMilliseconds (Double.NaN);
674 [ExpectedException (typeof (OverflowException))]
675 public void FromMilliseconds_PositiveInfinity ()
677 // LAMESPEC: Document to return TimeSpan.MaxValue
678 Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.FromMilliseconds (Double.PositiveInfinity));
682 [ExpectedException (typeof (OverflowException))]
683 public void FromMilliseconds_NegativeInfinity ()
685 // LAMESPEC: Document to return TimeSpan.MinValue
686 Assert.AreEqual (TimeSpan.MinValue, TimeSpan.FromMilliseconds (Double.NegativeInfinity));
690 [ExpectedException (typeof (OverflowException))]
691 public void FromMinutes_MinValue ()
693 TimeSpan.FromMinutes (Double.MinValue);
697 [ExpectedException (typeof (OverflowException))]
698 public void FromMinutes_MaxValue ()
700 TimeSpan.FromMinutes (Double.MaxValue);
704 [ExpectedException (typeof (ArgumentException))]
705 public void FromMinutes_NaN ()
707 TimeSpan.FromMinutes (Double.NaN);
711 [ExpectedException (typeof (OverflowException))]
712 public void FromMinutes_PositiveInfinity ()
714 // LAMESPEC: Document to return TimeSpan.MaxValue
715 Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.FromMinutes (Double.PositiveInfinity));
719 [ExpectedException (typeof (OverflowException))]
720 public void FromMinutes_NegativeInfinity ()
722 // LAMESPEC: Document to return TimeSpan.MinValue
723 Assert.AreEqual (TimeSpan.MinValue, TimeSpan.FromMinutes (Double.NegativeInfinity));
727 [ExpectedException (typeof (OverflowException))]
728 public void FromSeconds_MinValue ()
730 TimeSpan.FromSeconds (Double.MinValue);
734 [ExpectedException (typeof (OverflowException))]
735 public void FromSeconds_MaxValue ()
737 TimeSpan.FromSeconds (Double.MaxValue);
741 [ExpectedException (typeof (ArgumentException))]
742 public void FromSeconds_NaN ()
744 TimeSpan.FromSeconds (Double.NaN);
748 [ExpectedException (typeof (OverflowException))]
749 public void FromSeconds_PositiveInfinity ()
751 // LAMESPEC: Document to return TimeSpan.MaxValue
752 Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.FromSeconds (Double.PositiveInfinity));
756 [ExpectedException (typeof (OverflowException))]
757 public void FromSeconds_NegativeInfinity ()
759 // LAMESPEC: Document to return TimeSpan.MinValue
760 Assert.AreEqual (TimeSpan.MinValue, TimeSpan.FromSeconds (Double.NegativeInfinity));
763 public void TestGetHashCode ()
765 Assert.AreEqual (77, new TimeSpan (77).GetHashCode (), "A1");
768 private void ParseHelper (string s, bool expectFormat, bool expectOverflow, string expect)
770 bool formatException = false;
771 bool overflowException = false;
772 string result = "junk ";
775 result = TimeSpan.Parse (s).ToString ();
777 catch (OverflowException) {
778 overflowException = true;
780 catch (FormatException) {
781 formatException = true;
783 Assert.AreEqual (expectFormat, formatException, "A1 [" + s + "]");
784 Assert.AreEqual (expectOverflow, overflowException, "A2 " + s + "]");
786 if (!expectOverflow && !expectFormat) {
787 Assert.AreEqual (expect, result, "A3 [" + s + "]");
792 public void TestParse ()
794 ParseHelper (" 13:45:15 ",false, false, "13:45:15");
795 ParseHelper (" -1:2:3 ", false, false, "-01:02:03");
798 // In 4.0 when the first part is out of range, it parses it as day.
799 ParseHelper (" 25:11:12 ", false, false, "25.11:12:00");
800 ParseHelper (" 24:11:12 ", false, false, "24.11:12:00");
801 ParseHelper (" 23:11:12 ", false, false, "23:11:12");
803 ParseHelper (" 25:0:0 ",false, true, "dontcare");
806 ParseHelper ("-21.23:59:59.9999999", false, false, "-21.23:59:59.9999999");
807 ParseHelper ("10:12 ", false, false, "10:12:00");
808 ParseHelper ("aaa", true, false, "dontcare");
810 ParseHelper ("100000000000000.1:1:1", false, true, "dontcare");
811 ParseHelper ("24:60:60", false, true, "dontcare");
812 ParseHelper ("0001:0002:0003.12 ", false, false, "01:02:03.1200000");
815 // In 4.0 when a section has more than 7 digits an OverflowException is thrown.
816 ParseHelper (" 1:2:3:12345678 ", false, true, "dontcare");
818 ParseHelper (" 1:2:3:12345678 ", true, false, "dontcare");
822 ParseHelper ("10:11:12:13", false, false, "10.11:12:13"); // Days using : instead of . as separator
823 ParseHelper ("10.11", true, false, "dontcare"); // days+hours is invalid
825 // Force the use of french culture -which is using a non common NumberDecimalSeparator-
826 // as current culture, to show that the Parse method is *actually* being culture sensitive
827 // *and* also keeping the compatibility with '.'
828 CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
829 CultureInfo prev_culture = CultureInfo.CurrentCulture;
831 Thread.CurrentThread.CurrentCulture = french_culture;
832 ParseHelper ("10:10:10,006", false, false, "10:10:10.0060000");
833 ParseHelper ("10:10:10.006", false, false, "10:10:10.0060000");
836 Thread.CurrentThread.CurrentCulture = prev_culture;
840 ParseHelper ("00:00:00", false, false, "00:00:00");
841 ParseHelper ("00:10:00", false, false, "00:10:00");
844 // LAMESPEC: timespan in documentation is wrong - hh:mm:ss isn't mandatory
846 public void Parse_Days_WithoutColon ()
848 TimeSpan ts = TimeSpan.Parse ("1");
849 Assert.AreEqual (1, ts.Days, "Days");
852 public void TestSubstract ()
854 TimeSpan t1 = new TimeSpan (2,3,4,5,6);
855 TimeSpan t2 = new TimeSpan (1,2,3,4,5);
856 TimeSpan t3 = t1 - t2;
857 TimeSpan t4 = t1.Subtract (t2);
861 Assert.AreEqual ("1.01:01:01.0010000", t3.ToString (), "A1");
862 Assert.AreEqual ("1.01:01:01.0010000", t4.ToString (), "A2");
864 t5 = TimeSpan.MinValue - new TimeSpan (1);
867 catch (OverflowException) {
870 Assert.IsTrue (exception, "A3");
873 public void TestToString ()
875 TimeSpan t1 = new TimeSpan (1,2,3,4,5);
878 Assert.AreEqual ("1.02:03:04.0050000", t1.ToString (), "A1");
879 Assert.AreEqual ("-1.02:03:04.0050000", t2.ToString (), "A2");
880 Assert.AreEqual ("10675199.02:48:05.4775807", TimeSpan.MaxValue.ToString (), "A3");
881 Assert.AreEqual ("-10675199.02:48:05.4775808", TimeSpan.MinValue.ToString (), "A4");
885 public void ToString_Constants ()
887 Assert.AreEqual ("00:00:00", TimeSpan.Zero.ToString (), "Zero");
888 Assert.AreEqual ("10675199.02:48:05.4775807", TimeSpan.MaxValue.ToString (), "MaxValue");
889 Assert.AreEqual ("-10675199.02:48:05.4775808", TimeSpan.MinValue.ToString (), "MinValue");
893 public void Parse_InvalidValuesAndFormat_ExceptionOrder ()
895 // hours should be between 0 and 23 but format is also invalid (too many dots)
896 // In 2.0 overflow as precedence over format, but not in 4.0
899 TimeSpan.Parse ("0.99.99.0");
901 } catch (FormatException) {
905 TimeSpan.Parse ("0.99.99.0");
907 } catch (OverflowException) {
911 TimeSpan.Parse ("0.999999999999.99.0");
913 } catch (OverflowException) {
918 public void Parse_MinMaxValues ()
920 Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.Parse ("10675199.02:48:05.4775807"), "MaxValue");
921 Assert.AreEqual (TimeSpan.MinValue, TimeSpan.Parse ("-10675199.02:48:05.4775808"), "MinValue");
925 [ExpectedException (typeof (OverflowException))]
926 public void Parse_OverMaxValue()
928 TimeSpan.Parse ("10675199.02:48:05.4775808");
932 [ExpectedException (typeof (OverflowException))]
933 public void Parse_UnderMinValue()
935 TimeSpan.Parse ("-10675199.02:48:05.4775809");
939 public void ParseMissingSeconds ()
941 // as seen in ML for http://resources.esri.com/arcgisserver/apis/silverlight/
942 TimeSpan ts = TimeSpan.Parse ("0:0:.75");
944 Assert.AreEqual (0, ts.Days, "Days");
945 Assert.AreEqual (0, ts.Hours, "Hours");
946 Assert.AreEqual (750, ts.Milliseconds, "Milliseconds");
947 Assert.AreEqual (0, ts.Minutes, "Minutes");
948 Assert.AreEqual (0, ts.Seconds, "Seconds");
949 Assert.AreEqual (7500000, ts.Ticks, "Ticks");
950 Assert.AreEqual (0.0000086805555555555555, ts.TotalDays, 0.00000000000000001, "TotalDays");
951 Assert.AreEqual (0.00020833333333333332, ts.TotalHours, 0.00000000000000001, "TotalHours");
952 Assert.AreEqual (750.0, ts.TotalMilliseconds, "TotalMilliseconds");
953 Assert.AreEqual (0.0125, ts.TotalMinutes, "TotalMinutes");
954 Assert.AreEqual (0.75, ts.TotalSeconds, "TotalSeconds");
957 // 'Ported' the Parse test to use TryParse
959 public void TryParse ()
963 Assert.AreEqual (true, TimeSpan.TryParse (" 13:45:15 ", out result), "#A1");
964 Assert.AreEqual ("13:45:15", result.ToString (), "#A2");
966 Assert.AreEqual (true, TimeSpan.TryParse (" -1:2:3 ", out result), "#B1");
967 Assert.AreEqual ("-01:02:03", result.ToString (), "#B2");
969 Assert.AreEqual (false, TimeSpan.TryParse ("aaa", out result), "#C2");
971 Assert.AreEqual (true, TimeSpan.TryParse ("-21.23:59:59.9999999", out result), "#D1");
972 Assert.AreEqual ("-21.23:59:59.9999999", result.ToString (), "#D2");
974 Assert.AreEqual (false, TimeSpan.TryParse ("100000000000000.1:1:1", out result), "#E1");
975 Assert.AreEqual (false, TimeSpan.TryParse ("24:60:60", out result), "#E2");
978 Assert.AreEqual (true, TimeSpan.TryParse ("0001:0002:0003.12 ", out result), "#F1");
980 Assert.AreEqual (true, TimeSpan.TryParse ("0001:0002:0003.12 ", out result), "#F1");
981 Assert.AreEqual ("01:02:03.1200000", result.ToString (), "#F2");
984 Assert.AreEqual (false, TimeSpan.TryParse (" 1:2:3:12345678 ", out result), "#G1");
986 // Min and Max values
987 Assert.AreEqual (true, TimeSpan.TryParse ("10675199.02:48:05.4775807", out result), "MaxValue#1");
988 Assert.AreEqual (TimeSpan.MaxValue, result, "MaxValue#2");
989 Assert.AreEqual (true, TimeSpan.TryParse ("-10675199.02:48:05.4775808", out result), "MinValue#1");
990 Assert.AreEqual (TimeSpan.MinValue, result, "MinValue#2");
993 // Force the use of french culture -which is using a non common NumberDecimalSeparator-
994 // as current culture, to show that the Parse method is *actually* being culture sensitive
995 CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
996 CultureInfo prev_culture = CultureInfo.CurrentCulture;
997 result = new TimeSpan (0, 10, 10, 10, 6);
999 Thread.CurrentThread.CurrentCulture = french_culture;
1000 Assert.AreEqual (true, TimeSpan.TryParse ("10:10:10,006", out result), "#CultureSensitive1");
1001 Assert.AreEqual ("10:10:10.0060000", result.ToString (), "#CultureSensitive2");
1004 Thread.CurrentThread.CurrentCulture = prev_culture;
1010 public void TryParseErrors ()
1014 Assert.AreEqual (false, TimeSpan.TryParse ("0.99.99.0", out result), "Format#1");
1015 Assert.AreEqual (false, TimeSpan.TryParse ("10675199.02:48:05.4775808", out result), "OverMaxValue");
1016 Assert.AreEqual (false, TimeSpan.TryParse ("-10675199.02:48:05.4775809", out result), "UnderMinValue");
1021 public void TryParseOverloads ()
1025 // We use fr-FR culture since its NumericDecimalSeparator is not the same used by
1026 // most cultures - including the invariant one.
1027 CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
1028 Assert.AreEqual (true, TimeSpan.TryParse ("11:50:50,006", french_culture, out result), "#A1");
1030 // LAMESPEC - msdn states that an instance of DateTimeFormatInfo is retrieved to
1031 // obtain culture sensitive information, but at least in the betas that's false
1032 DateTimeFormatInfo format_info = new DateTimeFormatInfo ();
1033 format_info.TimeSeparator = ";";
1034 Assert.AreEqual (false, TimeSpan.TryParse ("11;50;50", format_info, out result), "#B1");
1035 Assert.AreEqual (true, TimeSpan.TryParse ("11:50:50", format_info, out result), "#B2");
1039 public void ParseExact ()
1041 CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
1042 CultureInfo us_culture = CultureInfo.GetCultureInfo ("en-US");
1044 // At this point we are only missing the style bites and then we are
1045 // pretty much done with the standard formats.
1048 // 'g' format - this is the short and culture sensitive format
1050 string [] g_format = new string [] { "g" };
1051 ParseExactHelper ("12", g_format, false, false, "12.00:00:00");
1052 ParseExactHelper ("11:12", g_format, false, false, "11:12:00");
1053 ParseExactHelper ("-11:12", g_format, false, false, "-11:12:00");
1054 ParseExactHelper ("25:13", g_format, true, false, "dontcare");
1055 ParseExactHelper ("11:66", g_format, true, false, "dontcare"); // I'd have expected OverflowExc here
1056 ParseExactHelper ("11:12:13", g_format, false, false, "11:12:13");
1057 ParseExactHelper ("-11:12:13", g_format, false, false, "-11:12:13");
1058 ParseExactHelper ("10.11:12:13", g_format, true, false, "dontcare"); // this should work as well
1059 ParseExactHelper ("10.11:12:13", g_format, true, false, "dontcare", us_culture);
1060 ParseExactHelper ("10.11:12:13", g_format, true, false, "dontcare", CultureInfo.InvariantCulture);
1061 ParseExactHelper ("10:11:12:66", g_format, true, false, "dontcare");
1062 ParseExactHelper ("10:11:12:13", g_format, false, false, "10.11:12:13");
1063 ParseExactHelper ("11:12:13.6", g_format, false, false, "11:12:13.6000000", CultureInfo.InvariantCulture);
1064 ParseExactHelper ("11:12:13,6", g_format, false, false, "11:12:13.6000000", french_culture);
1065 ParseExactHelper ("10:11:12:13.6", g_format, false, false, "10.11:12:13.6000000", us_culture);
1066 ParseExactHelper (" 10:11:12:13.6 ", g_format, false, false, "10.11:12:13.6000000", us_culture);
1067 ParseExactHelper ("10:11", g_format, false, false, "10:11:00", null, TimeSpanStyles.None);
1068 ParseExactHelper ("10:11", g_format, false, false, "10:11:00", null, TimeSpanStyles.AssumeNegative); // no effect
1073 string [] G_format = new string [] { "G" };
1074 ParseExactHelper ("9:10:12", G_format, true, false, "dontcare");
1075 ParseExactHelper ("9:10:12.6", G_format, true, false, "dontcare");
1076 ParseExactHelper ("3.9:10:12", G_format, true, false, "dontcare");
1077 ParseExactHelper ("3.9:10:12.153", G_format, true, false, "dontcare"); // this should be valid...
1078 ParseExactHelper ("3:9:10:12.153", G_format, false, false, "3.09:10:12.1530000", us_culture);
1079 ParseExactHelper ("0:9:10:12.153", G_format, false, false, "09:10:12.1530000", us_culture);
1080 ParseExactHelper ("03:09:10:12.153", G_format, false, false, "3.09:10:12.1530000", us_culture);
1081 ParseExactHelper ("003:009:0010:0012.00153", G_format, false, false, "3.09:10:12.0015300", us_culture);
1082 ParseExactHelper ("3:9:10:66.153", G_format, true, false, "dontcare"); // seconds out of range
1083 ParseExactHelper ("3:9:10:12.153", G_format, true, false, "dontcare", french_culture); // fr-FR uses ',' as decimal separator
1084 ParseExactHelper ("3:9:10:12,153", G_format, false, false, "3.09:10:12.1530000", french_culture);
1085 ParseExactHelper (" 3:9:10:12.153 ", G_format, false, false, "3.09:10:12.1530000", us_culture);
1086 ParseExactHelper ("3:9:10:13.153", G_format, false, false, "3.09:10:13.1530000", us_culture, TimeSpanStyles.AssumeNegative);
1089 string [] c_format = new string [] { "c" };
1090 ParseExactHelper ("12", c_format, false, false, "12.00:00:00");
1091 ParseExactHelper ("12:11", c_format, false, false, "12:11:00");
1092 ParseExactHelper ("12:66", c_format, true, false, "dontcare");
1093 ParseExactHelper ("10.11:12", c_format, false, false, "10.11:12:00");
1094 ParseExactHelper ("10.11:12:13", c_format, false, false, "10.11:12:13");
1095 ParseExactHelper ("10:11:12:13", c_format, true, false, "dontcare"); // this is normally accepted in the Parse method
1096 ParseExactHelper ("10.11:12:13.6", c_format, false, false, "10.11:12:13.6000000");
1097 ParseExactHelper ("10:11:12,6", c_format, true, false, "dontcare");
1098 ParseExactHelper ("10:11:12,6", c_format, true, false, "dontcare", french_culture);
1099 ParseExactHelper (" 10:11:12.6 ", c_format, false, false, "10:11:12.6000000");
1100 ParseExactHelper ("10:12", c_format, false, false, "10:12:00", null, TimeSpanStyles.AssumeNegative);
1101 ParseExactHelper ("10:123456789999", c_format, true, false, "dontcare");
1103 ParseExactHelper ("10:12", new string [0], true, false, "dontcare");
1104 ParseExactHelper ("10:12", new string [] { String.Empty }, true, false, "dontcare");
1105 ParseExactHelper ("10:12", new string [] { null }, true, false, "dontcare");
1109 public void ParseExactMultipleFormats ()
1111 ParseExactHelper ("10:12", new string [] { "G", "g" }, false, false, "10:12:00");
1112 ParseExactHelper ("10:12", new string [] { "g", "G" }, false, false, "10:12:00");
1113 ParseExactHelper ("7.8:9:10", new string [] { "G", "g" }, true, false, "dontcare");
1114 ParseExactHelper ("7.8:9:10", new string [] { "G", "g", "c" }, false, false, "7.08:09:10");
1115 ParseExactHelper ("7:8:9:10", new string [] { "c", "g" }, false, false, "7.08:09:10");
1116 ParseExactHelper ("7:8:9:10", new string [] { "c", "G" }, true, false, "dontcare");
1117 ParseExactHelper ("7.123456789:1", new string [] { "c", "G", "g" }, true, false, "dontcare");
1118 ParseExactHelper ("7.123456789:1", new string [] { "G", "g", "c" }, true, false, "dontcare");
1119 ParseExactHelper ("1234567890123456", new string [] { "c", "g" }, true, false, "dontcare"); // I'd expect an OverflowException
1120 ParseExactHelper ("10:12", new string [] { null, "c", "g" }, true, false, "10:12:00");
1121 ParseExactHelper ("10:12", new string [] { String.Empty, "c", "g" }, true, false, "10:12:00");
1125 public void ParseExactCustomFormats ()
1128 ParseExactHelper ("33", new string [] { "%d" }, false, false, "33.00:00:00");
1129 ParseExactHelper ("00", new string [] { "%d" }, false, false, "00:00:00");
1130 ParseExactHelper ("33", new string [] { "%dd" }, false, false, "33.00:00:00");
1131 ParseExactHelper ("3333", new string [] { "%d" }, false, false, "3333.00:00:00");
1132 ParseExactHelper ("3333", new string [] { "%ddd" }, true, false, "3333.00:00:00"); // 'dd' mismatch the digit count
1133 ParseExactHelper ("3333", new string [] { "%dddd" }, false, false, "3333.00:00:00");
1134 ParseExactHelper ("00033", new string [] { "%ddddd" }, false, false, "33.00:00:00");
1135 ParseExactHelper ("00033", new string [] { "%d" }, false, false, "33.00:00:00");
1136 ParseExactHelper ("00000003", new string [] { "%dddddddd" }, false, false, "3.00:00:00"); // up to 8 'd'
1137 ParseExactHelper ("000000003", new string [] { "%ddddddddd" }, true, false, "dontcare");
1138 ParseExactHelper ("33", new string [] { "d" }, true, false, "33.00:00:00"); // This is sort of weird.
1139 ParseExactHelper ("33", new string [] { "dd" }, false, false, "33.00:00:00");
1140 ParseExactHelper ("-33", new string [] { "%d" }, true, false, "dontcare");
1141 ParseExactHelper ("33", new string [] { "%d" }, false, false, "-33.00:00:00", null, TimeSpanStyles.AssumeNegative);
1144 ParseExactHelper ("12", new string [] { "%h" }, false, false, "12:00:00");
1145 ParseExactHelper ("00", new string [] { "%h" }, false, false, "00:00:00");
1146 ParseExactHelper ("012", new string [] { "%h" }, true, false, "dontcare"); // more than 2 digits
1147 ParseExactHelper ("00012", new string [] { "%hhhhh" }, true, false, "dontcare");
1148 ParseExactHelper ("15", new string [] { "%h" }, false, false, "15:00:00");
1149 ParseExactHelper ("24", new string [] { "%h" }, true, false, "dontcare");
1150 ParseExactHelper ("15", new string [] { "%hh" }, false, false, "15:00:00");
1151 ParseExactHelper ("1", new string [] { "%hh" }, true, false, "dontcare"); // 'hh' but a single digit
1152 ParseExactHelper ("01", new string [] { "%hh" }, false, false, "01:00:00");
1153 ParseExactHelper ("015", new string [] { "%hhh" }, true, false, "dontcare"); // Too many 'h'
1154 ParseExactHelper ("12", new string [] { "h" }, true, false, "dontcare");
1155 ParseExactHelper ("12", new string [] { "hh" }, false, false, "12:00:00");
1156 ParseExactHelper ("-15", new string [] {"%h"}, true, false, "dontcare"); // Explicit - not accepted
1157 ParseExactHelper ("15", new string [] { "%h" }, false, false, "-15:00:00", null, TimeSpanStyles.AssumeNegative);
1158 ParseExactHelper ("15", new string [] { "%H" }, true, false, "dontcare"); // Uppercase is not accepted
1161 ParseExactHelper ("12", new string [] { "%m" }, false, false, "00:12:00");
1162 ParseExactHelper ("00", new string [] { "%m" }, false, false, "00:00:00");
1163 ParseExactHelper ("60", new string [] { "%m" }, true, false, "dontcare");
1164 ParseExactHelper ("12", new string [] { "%mm" }, false, false, "00:12:00");
1165 ParseExactHelper ("1", new string [] { "%mm" }, true, false, "dontcare");
1166 ParseExactHelper ("12", new string [] { "%mmm" }, true, false, "dontcare");
1167 ParseExactHelper ("12", new string [] { "m" }, true, false, "dontcare");
1168 ParseExactHelper ("12", new string [] { "mm" }, false, false, "00:12:00");
1169 ParseExactHelper ("-12", new string [] { "%m" }, true, false, "dontcare");
1170 ParseExactHelper ("12", new string [] { "%m" }, false, false, "-00:12:00", null, TimeSpanStyles.AssumeNegative);
1171 ParseExactHelper ("12", new string [] { "%M" }, true, false, "dontcare");
1174 ParseExactHelper ("12", new string [] { "%s" }, false, false, "00:00:12");
1175 ParseExactHelper ("00", new string [] { "%s" }, false, false, "00:00:00");
1176 ParseExactHelper ("000", new string [] { "%s" }, true, false, "dontcare");
1177 ParseExactHelper ("12", new string [] { "%ss" }, false, false, "00:00:12");
1178 ParseExactHelper ("12", new string [] { "%sss" }, true, false, "dontcare");
1179 ParseExactHelper ("60", new string [] { "%s" }, true, false, "dontcare");
1180 ParseExactHelper ("-12", new string [] { "%s" }, true, false, "dontcare");
1181 ParseExactHelper ("12", new string [] { "%s" }, false, false, "-00:00:12", null, TimeSpanStyles.AssumeNegative);
1183 // Fractions of seconds - f
1184 ParseExactHelper ("3", new string [] { "%f" }, false, false, "00:00:00.3000000");
1185 ParseExactHelper ("0", new string [] { "%f" }, false, false, "00:00:00");
1186 ParseExactHelper ("03", new string [] { "%f" }, true, false, "dontcare"); // This would work for other elements
1187 ParseExactHelper ("10", new string [] { "%f" }, true, false, "dontcare"); // Only a digit is accepted with '%f'
1188 ParseExactHelper ("3", new string [] { "%ff" }, true, false, "dontcare");
1189 ParseExactHelper ("12", new string [] { "%ff" }, false, false, "00:00:00.1200000");
1190 ParseExactHelper ("123", new string [] { "%ff" }, true, false, "dontcare");
1191 ParseExactHelper ("123", new string [] { "%fff" }, false, false, "00:00:00.1230000");
1192 ParseExactHelper ("1234", new string [] { "%ffff" }, false, false, "00:00:00.1234000");
1193 ParseExactHelper ("1234567", new string [] { "%fffffff" }, false, false, "00:00:00.1234567");
1194 ParseExactHelper ("1234567", new string [] { "%FfFFFFF" }, true, false, "dontcare"); // Mixed f and M
1195 ParseExactHelper ("12345678", new string [] { "%ffffffff" }, true, false, "dontcare");
1196 ParseExactHelper ("0000000", new string [] { "%fffffff" }, false, false, "00:00:00");
1198 // Fractions of second - F
1199 ParseExactHelper ("3", new string [] { "%F" }, false, false, "00:00:00.3000000");
1200 ParseExactHelper ("333", new string [] { "%FFFFF" }, false, false, "00:00:00.3330000");
1201 ParseExactHelper ("1234567", new string [] { "%FFFFFFF" }, false, false, "00:00:00.1234567");
1204 ParseExactHelper ("9:10", new string [] { @"h\:m" }, false, false, "09:10:00");
1205 ParseExactHelper ("9;10", new string [] { @"h\;m" }, false, false, "09:10:00");
1206 ParseExactHelper ("10:9", new string [] { @"m\:h" }, false, false, "09:10:00");
1207 ParseExactHelper ("10:9", new string [] { @"%m\:%h" }, false, false, "09:10:00");
1208 ParseExactHelper ("9 10", new string [] { @"h\ m" }, false, false, "09:10:00");
1209 ParseExactHelper ("9 10", new string [] { @"h\ \ \ m" }, false, false, "09:10:00");
1210 ParseExactHelper (" 9:10 ", new string [] { @"h\:m" }, true, false, "dontcare");
1211 ParseExactHelper ("9:10:11", new string [] { @"h\:m\:s" }, false, false, "09:10:11");
1212 ParseExactHelper ("9:10:11:6", new string [] { @"h\:m\:s\:f" }, false, false, "09:10:11.6000000");
1213 ParseExactHelper ("9:10:11:666", new string [] { @"h\:m\:s\:f" }, true, false, "dontcare"); // fff with 1 digit
1214 ParseExactHelper ("9:10:11:", new string [] { @"h\:m\:s\:F" }, false, false, "09:10:11"); // optional frac of seconds
1215 ParseExactHelper ("9:10:11:", new string [] { @"h\:m\:s\:FF" }, false, false, "09:10:11");
1216 ParseExactHelper ("9:10:11::", new string [] { @"h\:m\:s\:F\:" }, false, false, "09:10:11");
1217 ParseExactHelper ("8:9:10:11:6666666", new string [] { @"d\:h\:m\:s\:fffffff" }, false, false, "8.09:10:11.6666666");
1218 ParseExactHelper ("8:9:10:11:6666666", new string [] { @"d\:h\:m\:s\:fffffff" }, false, false, "-8.09:10:11.6666666",
1219 null, TimeSpanStyles.AssumeNegative);
1220 ParseExactHelper ("9:10", new string [] { @"h\:h" }, true, false, "dontcare"); // Repeated element
1223 ParseExactHelper (" 0 ", new string [] { "%d" }, true, false, "dontcare");
1224 ParseExactHelper (" 0 ", new string [] { " %d " }, true, false, "dontcare");
1225 ParseExactHelper ("0", new string [] { " %d " }, true, false, "dontcare");
1226 ParseExactHelper ("::", new string [] { @"\:\:" }, false, false, "00:00:00"); // funny
1227 ParseExactHelper ("::", new string [] { @"\:\:" }, false, false, "00:00:00", null, TimeSpanStyles.AssumeNegative);
1228 ParseExactHelper (" 0", new string [] { @"\ d" }, false, false, "00:00:00");
1229 ParseExactHelper ("Interval = 12:13:14", new string [] { @"'Interval = 'h\:m\:s" }, false, false, "12:13:14");
1232 void ParseExactHelper (string input, string [] formats, bool format_error, bool overflow_error, string expected,
1233 IFormatProvider formatProvider = null, TimeSpanStyles timeSpanStyles = TimeSpanStyles.None)
1235 bool overflow_exc = false;
1236 bool format_exc = false;
1237 TimeSpan result = TimeSpan.Zero;
1240 result = TimeSpan.ParseExact (input, formats, formatProvider, timeSpanStyles);
1241 } catch (OverflowException) {
1242 overflow_exc = true;
1243 } catch (FormatException) {
1247 Assert.AreEqual (format_error, format_exc, "A1");
1248 Assert.AreEqual (overflow_error, overflow_exc, "A2");
1249 if (!overflow_exc && !format_exc)
1250 Assert.AreEqual (expected, result.ToString ());
1253 // 'Ported' the ParseExact test to use TryParseExact instead.
1255 public void TryParseExact ()
1257 CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
1258 CultureInfo us_culture = CultureInfo.GetCultureInfo ("en-US");
1261 // 'g' format - this is the short and culture sensitive format
1263 string [] g_format = new string [] { "g" };
1264 TryParseExactHelper ("12", g_format, false, "12.00:00:00");
1265 TryParseExactHelper ("11:12", g_format, false, "11:12:00");
1266 TryParseExactHelper ("-11:12", g_format, false, "-11:12:00");
1267 TryParseExactHelper ("25:13", g_format, true, "dontcare");
1268 TryParseExactHelper ("11:66", g_format, true, "dontcare"); // I'd have expected OverflowExc here
1269 TryParseExactHelper ("11:12:13", g_format, false, "11:12:13");
1270 TryParseExactHelper ("-11:12:13", g_format, false, "-11:12:13");
1271 TryParseExactHelper ("10.11:12:13", g_format, true, "dontcare"); // this should work as well
1272 TryParseExactHelper ("10.11:12:13", g_format, true, "dontcare", us_culture);
1273 TryParseExactHelper ("10.11:12:13", g_format, true, "dontcare", CultureInfo.InvariantCulture);
1274 TryParseExactHelper ("10:11:12:66", g_format, true, "dontcare");
1275 TryParseExactHelper ("10:11:12:13", g_format, false, "10.11:12:13");
1276 TryParseExactHelper ("11:12:13.6", g_format, false, "11:12:13.6000000", CultureInfo.InvariantCulture);
1277 TryParseExactHelper ("11:12:13,6", g_format, false, "11:12:13.6000000", french_culture);
1278 TryParseExactHelper ("10:11:12:13.6", g_format, false, "10.11:12:13.6000000", us_culture);
1279 TryParseExactHelper (" 10:11:12:13.6 ", g_format, false, "10.11:12:13.6000000", us_culture);
1280 TryParseExactHelper ("10:11", g_format, false, "10:11:00", null, TimeSpanStyles.None);
1281 TryParseExactHelper ("10:11", g_format, false, "10:11:00", null, TimeSpanStyles.AssumeNegative); // no effect
1286 string [] G_format = new string [] { "G" };
1287 TryParseExactHelper ("9:10:12", G_format, true, "dontcare");
1288 TryParseExactHelper ("9:10:12.6", G_format, true, "dontcare");
1289 TryParseExactHelper ("3.9:10:12", G_format, true, "dontcare");
1290 TryParseExactHelper ("3.9:10:12.153", G_format, true, "dontcare"); // this should be valid...
1291 TryParseExactHelper ("3:9:10:12.153", G_format, false, "3.09:10:12.1530000", us_culture);
1292 TryParseExactHelper ("0:9:10:12.153", G_format, false, "09:10:12.1530000", us_culture);
1293 TryParseExactHelper ("03:09:10:12.153", G_format, false, "3.09:10:12.1530000", us_culture);
1294 TryParseExactHelper ("003:009:0010:0012.00153", G_format, false, "3.09:10:12.0015300", us_culture);
1295 TryParseExactHelper ("3:9:10:66.153", G_format, true, "dontcare"); // seconds out of range
1296 TryParseExactHelper ("3:9:10:12.153", G_format, true, "dontcare", french_culture); // fr-FR uses ',' as decimal separator
1297 TryParseExactHelper ("3:9:10:12,153", G_format, false, "3.09:10:12.1530000", french_culture);
1298 TryParseExactHelper (" 3:9:10:12.153 ", G_format, false, "3.09:10:12.1530000", us_culture);
1299 TryParseExactHelper ("3:9:10:13.153", G_format, false, "3.09:10:13.1530000", us_culture, TimeSpanStyles.AssumeNegative);
1302 string [] c_format = new string [] { "c" };
1303 TryParseExactHelper ("12", c_format, false, "12.00:00:00");
1304 TryParseExactHelper ("12:11", c_format, false, "12:11:00");
1305 TryParseExactHelper ("12:66", c_format, true, "dontcare");
1306 TryParseExactHelper ("10.11:12", c_format, false, "10.11:12:00");
1307 TryParseExactHelper ("10.11:12:13", c_format, false, "10.11:12:13");
1308 TryParseExactHelper ("10:11:12:13", c_format, true, "dontcare"); // this is normally accepted in the Parse method
1309 TryParseExactHelper ("10.11:12:13.6", c_format, false, "10.11:12:13.6000000");
1310 TryParseExactHelper ("10:11:12,6", c_format, true, "dontcare");
1311 TryParseExactHelper ("10:11:12,6", c_format, true, "dontcare", french_culture);
1312 TryParseExactHelper (" 10:11:12.6 ", c_format, false, "10:11:12.6000000");
1313 TryParseExactHelper ("10:12", c_format, false, "10:12:00", null, TimeSpanStyles.AssumeNegative);
1314 TryParseExactHelper ("10:123456789999", c_format, true, "dontcare");
1316 TryParseExactHelper ("10:12", new string [0], true, "dontcare");
1317 TryParseExactHelper ("10:12", new string [] { String.Empty }, true, "dontcare");
1318 TryParseExactHelper ("10:12", new string [] { null }, true, "dontcare");
1321 void TryParseExactHelper (string input, string [] formats, bool error, string expected, IFormatProvider formatProvider = null,
1322 TimeSpanStyles styles = TimeSpanStyles.None)
1327 success = TimeSpan.TryParseExact (input, formats, formatProvider, styles, out result);
1328 Assert.AreEqual (!error, success);
1330 Assert.AreEqual (expected, result.ToString ());
1334 public void ParseExactExceptions ()
1337 TimeSpan.ParseExact (null, "g", null);
1338 Assert.Fail ("#A1");
1339 } catch (ArgumentNullException) {
1343 TimeSpan.ParseExact ("10:12", (string)null, null);
1344 Assert.Fail ("#A2");
1345 } catch (ArgumentNullException) {
1349 TimeSpan.ParseExact ("10:12", (string [])null, null);
1350 Assert.Fail ("#A3");
1351 } catch (ArgumentNullException) {
1356 public void ToStringOverloads ()
1358 TimeSpan ts = new TimeSpan (1, 2, 3, 4, 6);
1360 // Simple version - culture invariant
1361 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString (), "#A1");
1362 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString ("c"), "#A2");
1363 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString (null), "#A3");
1364 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString (String.Empty), "#A4");
1367 // IFormatProvider ones - use a culture changing numeric format.
1368 // Also, we use fr-FR as culture, since it uses some elements different to invariant culture
1370 CultureInfo culture = CultureInfo.GetCultureInfo ("fr-FR");
1372 Assert.AreEqual ("1:2:03:04,006", ts.ToString ("g", culture), "#B1");
1373 Assert.AreEqual ("1:02:03:04,0060000", ts.ToString ("G", culture), "#B2");
1374 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString ("c", culture), "#B3"); // 'c' format ignores CultureInfo
1375 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString ("t", culture), "#B4"); // 't' and 'T' are the same as 'c'
1376 Assert.AreEqual("1.02:03:04.0060000", ts.ToString("T", culture), "#B5");
1378 ts = new TimeSpan (4, 5, 6);
1379 Assert.AreEqual ("4:05:06", ts.ToString ("g", culture), "#C1");
1380 Assert.AreEqual ("0:04:05:06,0000000", ts.ToString ("G", culture), "#C2");
1384 public void ToStringCustomFormats ()
1386 TimeSpan ts = new TimeSpan (1, 3, 5, 7);
1388 Assert.AreEqual ("1", ts.ToString ("%d"), "#A0");
1389 Assert.AreEqual ("3", ts.ToString ("%h"), "#A1");
1390 Assert.AreEqual ("5", ts.ToString ("%m"), "#A2");
1391 Assert.AreEqual ("7", ts.ToString ("%s"), "#A3");
1392 Assert.AreEqual ("0", ts.ToString ("%f"), "#A4");
1393 Assert.AreEqual (String.Empty, ts.ToString ("%F"), "#A5"); // Nothing to display
1395 Assert.AreEqual ("01", ts.ToString ("dd"), "#B0");
1396 Assert.AreEqual ("00000001", ts.ToString ("dddddddd"), "#B1");
1397 Assert.AreEqual ("03", ts.ToString ("hh"), "#B2");
1398 Assert.AreEqual ("05", ts.ToString ("mm"), "#B3");
1399 Assert.AreEqual ("07", ts.ToString ("ss"), "#B4");
1400 Assert.AreEqual ("00", ts.ToString ("ff"), "#B5");
1401 Assert.AreEqual ("0000000", ts.ToString ("fffffff"), "#B6");
1402 Assert.AreEqual (String.Empty, ts.ToString ("FF"), "#B7");
1404 Assert.AreEqual ("01;03;05", ts.ToString (@"dd\;hh\;mm"), "#C0");
1405 Assert.AreEqual ("05 07", ts.ToString (@"mm\ ss"), "#C1");
1406 Assert.AreEqual ("05 07 ", ts.ToString (@"mm\ ss\ FF"), "#C2");
1407 Assert.AreEqual ("Result = 3 hours with 5 minutes and 7 seconds",
1408 ts.ToString (@"'Result = 'h' hours with 'm' minutes and 's' seconds'"), "#C3");
1409 Assert.AreEqual (" ", ts.ToString (@"\ \ "), "#C4");
1411 ts = new TimeSpan (1, 3, 5, 7, 153);
1412 Assert.AreEqual ("1", ts.ToString ("%F"), "#D0");
1413 Assert.AreEqual ("15", ts.ToString ("FF"), "#D1"); // Don't use %, as the parser gets confused here
1414 Assert.AreEqual ("153", ts.ToString ("FFFFFFF"), "#D2");
1416 // Negative values are shown without sign
1417 ts = new TimeSpan (-1, -3, -5);
1418 Assert.AreEqual ("1", ts.ToString ("%h"), "#E0");
1419 Assert.AreEqual ("3", ts.ToString ("%m"), "#E1");
1420 Assert.AreEqual ("5", ts.ToString ("%s"), "#E2");
1424 public void ToStringOverloadsErrors ()
1426 TimeSpan ts = new TimeSpan (10, 10, 10);
1430 result = ts.ToString ("non-valid");
1432 } catch (FormatException) {
1436 result = ts.ToString ("C");
1438 } catch (FormatException) {
1445 } catch (FormatException) {
1450 ts.ToString ("d"); // Missing % for single char
1452 } catch (FormatException)
1458 ts.ToString ("ddddddddd");
1460 } catch (FormatException)
1466 ts.ToString ("hhh");
1468 } catch (FormatException)
1474 ts.ToString ("ffffffff");
1476 } catch (FormatException)