[LoongArch64] Part-5:add loongarch support in some files for LoongArch64. (#21769)
[mono-project.git] / mcs / class / corlib / Test / System / TimeSpanTest.cs
blob926c9c5738d5e59769674bc84fc67885291ac18d
1 //
2 // TimeSpanTest.cs - NUnit Test Cases for the System.TimeSpan struct
3 //
4 // Authors:
5 // Duco Fijma (duco@lorentz.xs4all.nl)
6 // Sebastien Pouliot <sebastien@ximian.com>
7 //
8 // (C) 2001 Duco Fijma
9 // Copyright (C) 2004 Novell (http://www.novell.com)
12 using NUnit.Framework;
13 using System;
14 using System.Globalization;
15 using System.Threading;
17 namespace MonoTests.System
20 [TestFixture]
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 [Test]
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");
51 [Test]
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);
59 [Test]
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");
75 [Test]
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");
88 [Test]
89 [ExpectedException (typeof (ArgumentOutOfRangeException))]
90 public void MaxDays ()
92 new TimeSpan (Int32.MaxValue, 0, 0, 0, 0);
95 [Test]
96 [ExpectedException (typeof (ArgumentOutOfRangeException))]
97 public void MinDays ()
99 new TimeSpan (Int32.MinValue, 0, 0, 0, 0);
102 [Test]
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");
124 [Test]
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");
137 [Test]
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");
149 [Test]
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");
162 [Test]
163 public void MaxMinutes ()
165 TimeSpan ts;
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");
175 [Test]
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");
188 [Test]
189 public void MinMinutes ()
191 TimeSpan ts;
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");
201 [Test]
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");
213 [Test]
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");
225 [Test]
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");
237 [Test]
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");
249 [Test]
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");
261 [Test]
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");
273 [Test]
274 public void TestProperties ()
276 TimeSpan t1 = new TimeSpan (1,2,3,4,5);
277 TimeSpan t2 = -t1;
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");
291 [Test]
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);
298 TimeSpan t5;
299 bool exception;
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);
310 exception = false;
312 catch (OverflowException)
314 exception = true;
316 Assert.IsTrue (exception, "A7");
319 [Test]
320 public void TestCompare ()
322 TimeSpan t1 = new TimeSpan (-1);
323 TimeSpan t2 = new TimeSpan (1);
324 int res;
325 bool exception;
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("");
341 exception = false;
343 catch (ArgumentException)
345 exception = true;
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");
357 [Test]
358 [ExpectedException (typeof (OverflowException))]
359 public void NoNegateMinValue() {
360 TimeSpan t1 = TimeSpan.MinValue.Negate ();
363 [Test]
364 public void TestNegateAndDuration ()
366 TimeSpan t1;
367 bool exception;
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 ();
375 exception = false;
377 catch (OverflowException) {
378 exception = true;
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");
386 [Test]
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");
405 [Test]
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");
421 [Test]
422 [ExpectedException (typeof (OverflowException))]
423 public void FromDays_MinValue ()
425 TimeSpan.FromDays (Double.MinValue);
428 [Test]
429 [ExpectedException (typeof (OverflowException))]
430 public void FromDays_MaxValue ()
432 TimeSpan.FromDays (Double.MaxValue);
435 [Test]
436 [ExpectedException (typeof (ArgumentException))]
437 public void FromDays_NaN ()
439 TimeSpan.FromDays (Double.NaN);
442 [Test]
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));
450 [Test]
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));
458 [Test]
459 [ExpectedException (typeof (OverflowException))]
460 public void FromHours_MinValue ()
462 TimeSpan.FromHours (Double.MinValue);
465 [Test]
466 [ExpectedException (typeof (OverflowException))]
467 public void FromHours_MaxValue ()
469 TimeSpan.FromHours (Double.MaxValue);
472 [Test]
473 [ExpectedException (typeof (ArgumentException))]
474 public void FromHours_NaN ()
476 TimeSpan.FromHours (Double.NaN);
479 [Test]
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));
487 [Test]
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));
495 [Test]
496 [ExpectedException (typeof (OverflowException))]
497 public void FromMilliseconds_MinValue ()
499 TimeSpan.FromMilliseconds (Double.MinValue);
502 [Test]
503 [ExpectedException (typeof (OverflowException))]
504 public void FromMilliseconds_MaxValue ()
506 TimeSpan.FromMilliseconds (Double.MaxValue);
509 [Test]
510 [ExpectedException (typeof (ArgumentException))]
511 public void FromMilliseconds_NaN ()
513 TimeSpan.FromMilliseconds (Double.NaN);
516 [Test]
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));
524 [Test]
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));
532 [Test]
533 [ExpectedException (typeof (OverflowException))]
534 public void FromMinutes_MinValue ()
536 TimeSpan.FromMinutes (Double.MinValue);
539 [Test]
540 [ExpectedException (typeof (OverflowException))]
541 public void FromMinutes_MaxValue ()
543 TimeSpan.FromMinutes (Double.MaxValue);
546 [Test]
547 [ExpectedException (typeof (ArgumentException))]
548 public void FromMinutes_NaN ()
550 TimeSpan.FromMinutes (Double.NaN);
553 [Test]
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));
561 [Test]
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));
569 [Test]
570 [ExpectedException (typeof (OverflowException))]
571 public void FromSeconds_MinValue ()
573 TimeSpan.FromSeconds (Double.MinValue);
576 [Test]
577 [ExpectedException (typeof (OverflowException))]
578 public void FromSeconds_MaxValue ()
580 TimeSpan.FromSeconds (Double.MaxValue);
583 [Test]
584 [ExpectedException (typeof (ArgumentException))]
585 public void FromSeconds_NaN ()
587 TimeSpan.FromSeconds (Double.NaN);
590 [Test]
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));
598 [Test]
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));
606 [Test]
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 ";
618 try {
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 + "]");
635 [Test]
636 public void TestParse ()
638 ParseHelper (" 13:45:15 ",false, false, "13:45:15");
639 ParseHelper (" -1:2:3 ", false, false, "-01:02:03");
641 // In 4.0 when the first part is out of range, it parses it as day.
642 ParseHelper (" 25:11:12 ", false, false, "25.11:12:00");
643 ParseHelper (" 24:11:12 ", false, false, "24.11:12:00");
644 ParseHelper (" 23:11:12 ", false, false, "23:11:12");
646 ParseHelper ("-21.23:59:59.9999999", false, false, "-21.23:59:59.9999999");
647 ParseHelper ("10:12 ", false, false, "10:12:00");
648 ParseHelper ("aaa", true, false, "dontcare");
650 ParseHelper ("100000000000000.1:1:1", false, true, "dontcare");
651 ParseHelper ("24:60:60", false, true, "dontcare");
652 ParseHelper ("0001:0002:0003.12 ", false, false, "01:02:03.1200000");
654 // In 4.0 when a section has more than 7 digits an OverflowException is thrown.
655 ParseHelper (" 1:2:3:12345678 ", false, true, "dontcare");
657 ParseHelper ("10:11:12:13", false, false, "10.11:12:13"); // Days using : instead of . as separator
658 ParseHelper ("10.11", true, false, "dontcare"); // days+hours is invalid
660 if (!GlobalizationMode.Invariant) {
661 // Force the use of french culture -which is using a non common NumberDecimalSeparator-
662 // as current culture, to show that the Parse method is *actually* being culture sensitive
663 // *and* also keeping the compatibility with '.'
664 CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
665 CultureInfo prev_culture = CultureInfo.CurrentCulture;
666 try {
667 Thread.CurrentThread.CurrentCulture = french_culture;
668 ParseHelper ("10:10:10,006", false, false, "10:10:10.0060000");
669 ParseHelper ("10:10:10.006", false, false, "10:10:10.0060000");
670 } finally {
671 // restore culture
672 Thread.CurrentThread.CurrentCulture = prev_culture;
676 ParseHelper ("00:00:00", false, false, "00:00:00");
677 ParseHelper ("00:10:00", false, false, "00:10:00");
680 // LAMESPEC: timespan in documentation is wrong - hh:mm:ss isn't mandatory
681 [Test]
682 public void Parse_Days_WithoutColon ()
684 TimeSpan ts = TimeSpan.Parse ("1");
685 Assert.AreEqual (1, ts.Days, "Days");
688 [Test]
689 public void TestSubstract ()
691 TimeSpan t1 = new TimeSpan (2,3,4,5,6);
692 TimeSpan t2 = new TimeSpan (1,2,3,4,5);
693 TimeSpan t3 = t1 - t2;
694 TimeSpan t4 = t1.Subtract (t2);
695 TimeSpan t5;
696 bool exception;
698 Assert.AreEqual ("1.01:01:01.0010000", t3.ToString (), "A1");
699 Assert.AreEqual ("1.01:01:01.0010000", t4.ToString (), "A2");
700 try {
701 t5 = TimeSpan.MinValue - new TimeSpan (1);
702 exception = false;
704 catch (OverflowException) {
705 exception = true;
707 Assert.IsTrue (exception, "A3");
710 [Test]
711 public void TestToString ()
713 TimeSpan t1 = new TimeSpan (1,2,3,4,5);
714 TimeSpan t2 = -t1;
716 Assert.AreEqual ("1.02:03:04.0050000", t1.ToString (), "A1");
717 Assert.AreEqual ("-1.02:03:04.0050000", t2.ToString (), "A2");
718 Assert.AreEqual ("10675199.02:48:05.4775807", TimeSpan.MaxValue.ToString (), "A3");
719 Assert.AreEqual ("-10675199.02:48:05.4775808", TimeSpan.MinValue.ToString (), "A4");
722 [Test]
723 public void ToString_Constants ()
725 Assert.AreEqual ("00:00:00", TimeSpan.Zero.ToString (), "Zero");
726 Assert.AreEqual ("10675199.02:48:05.4775807", TimeSpan.MaxValue.ToString (), "MaxValue");
727 Assert.AreEqual ("-10675199.02:48:05.4775808", TimeSpan.MinValue.ToString (), "MinValue");
730 [Test]
731 public void Parse_InvalidValuesAndFormat_ExceptionOrder ()
733 // hours should be between 0 and 23 but format is also invalid (too many dots)
734 // In 2.0 overflow as precedence over format, but not in 4.0
735 try {
736 TimeSpan.Parse ("0.99.99.0");
737 Assert.Fail ("#A1");
738 } catch (FormatException) {
740 try {
741 TimeSpan.Parse ("0.999999999999.99.0");
742 Assert.Fail ("#A2");
743 } catch (OverflowException) {
747 [Test]
748 public void Parse_MinMaxValues ()
750 Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.Parse ("10675199.02:48:05.4775807"), "MaxValue");
751 Assert.AreEqual (TimeSpan.MinValue, TimeSpan.Parse ("-10675199.02:48:05.4775808"), "MinValue");
754 [Test]
755 [ExpectedException (typeof (OverflowException))]
756 public void Parse_OverMaxValue()
758 TimeSpan.Parse ("10675199.02:48:05.4775808");
761 [Test]
762 [ExpectedException (typeof (OverflowException))]
763 public void Parse_UnderMinValue()
765 TimeSpan.Parse ("-10675199.02:48:05.4775809");
768 [Test]
769 public void ParseMissingSeconds ()
771 // as seen in ML for http://resources.esri.com/arcgisserver/apis/silverlight/
772 TimeSpan ts = TimeSpan.Parse ("0:0:.75");
774 Assert.AreEqual (0, ts.Days, "Days");
775 Assert.AreEqual (0, ts.Hours, "Hours");
776 Assert.AreEqual (750, ts.Milliseconds, "Milliseconds");
777 Assert.AreEqual (0, ts.Minutes, "Minutes");
778 Assert.AreEqual (0, ts.Seconds, "Seconds");
779 Assert.AreEqual (7500000, ts.Ticks, "Ticks");
780 Assert.AreEqual (0.0000086805555555555555, ts.TotalDays, 0.00000000000000001, "TotalDays");
781 Assert.AreEqual (0.00020833333333333332, ts.TotalHours, 0.00000000000000001, "TotalHours");
782 Assert.AreEqual (750.0, ts.TotalMilliseconds, "TotalMilliseconds");
783 Assert.AreEqual (0.0125, ts.TotalMinutes, "TotalMinutes");
784 Assert.AreEqual (0.75, ts.TotalSeconds, "TotalSeconds");
787 // 'Ported' the Parse test to use TryParse
788 [Test]
789 public void TryParse ()
791 TimeSpan result;
793 Assert.AreEqual (true, TimeSpan.TryParse (" 13:45:15 ", out result), "#A1");
794 Assert.AreEqual ("13:45:15", result.ToString (), "#A2");
796 Assert.AreEqual (true, TimeSpan.TryParse (" -1:2:3 ", out result), "#B1");
797 Assert.AreEqual ("-01:02:03", result.ToString (), "#B2");
799 Assert.AreEqual (false, TimeSpan.TryParse ("aaa", out result), "#C2");
801 Assert.AreEqual (true, TimeSpan.TryParse ("-21.23:59:59.9999999", out result), "#D1");
802 Assert.AreEqual ("-21.23:59:59.9999999", result.ToString (), "#D2");
804 Assert.AreEqual (false, TimeSpan.TryParse ("100000000000000.1:1:1", out result), "#E1");
805 Assert.AreEqual (false, TimeSpan.TryParse ("24:60:60", out result), "#E2");
807 Assert.AreEqual (true, TimeSpan.TryParse ("0001:0002:0003.12 ", out result), "#F1");
809 Assert.AreEqual (false, TimeSpan.TryParse (" 1:2:3:12345678 ", out result), "#G1");
811 // Min and Max values
812 Assert.AreEqual (true, TimeSpan.TryParse ("10675199.02:48:05.4775807", out result), "MaxValue#1");
813 Assert.AreEqual (TimeSpan.MaxValue, result, "MaxValue#2");
814 Assert.AreEqual (true, TimeSpan.TryParse ("-10675199.02:48:05.4775808", out result), "MinValue#1");
815 Assert.AreEqual (TimeSpan.MinValue, result, "MinValue#2");
817 if (!GlobalizationMode.Invariant) {
818 // Force the use of french culture -which is using a non common NumberDecimalSeparator-
819 // as current culture, to show that the Parse method is *actually* being culture sensitive
820 CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
821 CultureInfo prev_culture = CultureInfo.CurrentCulture;
822 result = new TimeSpan (0, 10, 10, 10, 6);
823 try {
824 Thread.CurrentThread.CurrentCulture = french_culture;
825 Assert.AreEqual (true, TimeSpan.TryParse ("10:10:10,006", out result), "#CultureSensitive1");
826 Assert.AreEqual ("10:10:10.0060000", result.ToString (), "#CultureSensitive2");
827 } finally {
828 // restore culture
829 Thread.CurrentThread.CurrentCulture = prev_culture;
834 [Test]
835 public void TryParseErrors ()
837 TimeSpan result;
839 Assert.AreEqual (false, TimeSpan.TryParse ("0.99.99.0", out result), "Format#1");
840 Assert.AreEqual (false, TimeSpan.TryParse ("10675199.02:48:05.4775808", out result), "OverMaxValue");
841 Assert.AreEqual (false, TimeSpan.TryParse ("-10675199.02:48:05.4775809", out result), "UnderMinValue");
844 [Test]
845 public void TryParseOverloads ()
847 TimeSpan result;
849 if (!GlobalizationMode.Invariant) {
850 // We use fr-FR culture since its NumericDecimalSeparator is not the same used by
851 // most cultures - including the invariant one.
852 CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
853 Assert.AreEqual (true, TimeSpan.TryParse ("11:50:50,006", french_culture, out result), "#A1");
856 // LAMESPEC - msdn states that an instance of DateTimeFormatInfo is retrieved to
857 // obtain culture sensitive information, but at least in the betas that's false
858 DateTimeFormatInfo format_info = new DateTimeFormatInfo ();
859 format_info.TimeSeparator = ";";
860 Assert.AreEqual (false, TimeSpan.TryParse ("11;50;50", format_info, out result), "#B1");
861 Assert.AreEqual (true, TimeSpan.TryParse ("11:50:50", format_info, out result), "#B2");
864 [Test]
865 public void ParseExact ()
867 // At this point we are only missing the style bites and then we are
868 // pretty much done with the standard formats.
871 // 'g' format - this is the short and culture sensitive format
873 string [] g_format = new string [] { "g" };
874 ParseExactHelper ("12", g_format, false, false, "12.00:00:00");
875 ParseExactHelper ("11:12", g_format, false, false, "11:12:00");
876 ParseExactHelper ("-11:12", g_format, false, false, "-11:12:00");
877 ParseExactHelper ("25:13", g_format, true, false, "dontcare");
878 ParseExactHelper ("11:66", g_format, true, false, "dontcare"); // I'd have expected OverflowExc here
879 ParseExactHelper ("11:12:13", g_format, false, false, "11:12:13");
880 ParseExactHelper ("-11:12:13", g_format, false, false, "-11:12:13");
881 ParseExactHelper ("10.11:12:13", g_format, true, false, "dontcare"); // this should work as well
882 ParseExactHelper ("10.11:12:13", g_format, true, false, "dontcare", CultureInfo.InvariantCulture);
883 ParseExactHelper ("10:11:12:66", g_format, true, false, "dontcare");
884 ParseExactHelper ("10:11:12:13", g_format, false, false, "10.11:12:13");
885 ParseExactHelper ("11:12:13.6", g_format, false, false, "11:12:13.6000000", CultureInfo.InvariantCulture);
886 ParseExactHelper ("10:11", g_format, false, false, "10:11:00", null, TimeSpanStyles.None);
887 ParseExactHelper ("10:11", g_format, false, false, "10:11:00", null, TimeSpanStyles.AssumeNegative); // no effect
889 if (!GlobalizationMode.Invariant) {
890 CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
891 CultureInfo us_culture = CultureInfo.GetCultureInfo ("en-US");
892 ParseExactHelper ("10.11:12:13", g_format, true, false, "dontcare", us_culture);
893 ParseExactHelper ("11:12:13,6", g_format, false, false, "11:12:13.6000000", french_culture);
894 ParseExactHelper ("10:11:12:13.6", g_format, false, false, "10.11:12:13.6000000", us_culture);
895 ParseExactHelper (" 10:11:12:13.6 ", g_format, false, false, "10.11:12:13.6000000", us_culture);
899 // G format
901 string [] G_format = new string [] { "G" };
902 ParseExactHelper ("9:10:12", G_format, true, false, "dontcare");
903 ParseExactHelper ("9:10:12.6", G_format, true, false, "dontcare");
904 ParseExactHelper ("3.9:10:12", G_format, true, false, "dontcare");
905 ParseExactHelper ("3.9:10:12.153", G_format, true, false, "dontcare"); // this should be valid...
906 ParseExactHelper ("3:9:10:66.153", G_format, true, false, "dontcare"); // seconds out of range
908 if (!GlobalizationMode.Invariant) {
909 CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
910 CultureInfo us_culture = CultureInfo.GetCultureInfo ("en-US");
911 ParseExactHelper ("3:9:10:12.153", G_format, false, false, "3.09:10:12.1530000", us_culture);
912 ParseExactHelper ("0:9:10:12.153", G_format, false, false, "09:10:12.1530000", us_culture);
913 ParseExactHelper ("03:09:10:12.153", G_format, false, false, "3.09:10:12.1530000", us_culture);
914 ParseExactHelper ("003:009:0010:0012.00153", G_format, false, false, "3.09:10:12.0015300", us_culture);
915 ParseExactHelper ("3:9:10:12.153", G_format, true, false, "dontcare", french_culture); // fr-FR uses ',' as decimal separator
916 ParseExactHelper ("3:9:10:12,153", G_format, false, false, "3.09:10:12.1530000", french_culture);
917 ParseExactHelper (" 3:9:10:12.153 ", G_format, false, false, "3.09:10:12.1530000", us_culture);
918 ParseExactHelper ("3:9:10:13.153", G_format, false, false, "3.09:10:13.1530000", us_culture, TimeSpanStyles.AssumeNegative);
921 // c format
922 string [] c_format = new string [] { "c" };
923 ParseExactHelper ("12", c_format, false, false, "12.00:00:00");
924 ParseExactHelper ("12:11", c_format, false, false, "12:11:00");
925 ParseExactHelper ("12:66", c_format, true, false, "dontcare");
926 ParseExactHelper ("10.11:12", c_format, false, false, "10.11:12:00");
927 ParseExactHelper ("10.11:12:13", c_format, false, false, "10.11:12:13");
928 ParseExactHelper ("10:11:12:13", c_format, true, false, "dontcare"); // this is normally accepted in the Parse method
929 ParseExactHelper ("10.11:12:13.6", c_format, false, false, "10.11:12:13.6000000");
930 ParseExactHelper ("10:11:12,6", c_format, true, false, "dontcare");
931 ParseExactHelper (" 10:11:12.6 ", c_format, false, false, "10:11:12.6000000");
932 ParseExactHelper ("10:12", c_format, false, false, "10:12:00", null, TimeSpanStyles.AssumeNegative);
933 ParseExactHelper ("10:123456789999", c_format, true, false, "dontcare");
935 ParseExactHelper ("10:12", new string [0], true, false, "dontcare");
936 ParseExactHelper ("10:12", new string [] { String.Empty }, true, false, "dontcare");
937 ParseExactHelper ("10:12", new string [] { null }, true, false, "dontcare");
939 if (!GlobalizationMode.Invariant) {
940 CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
941 ParseExactHelper ("10:11:12,6", c_format, true, false, "dontcare", french_culture);
945 [Test]
946 public void ParseExactMultipleFormats ()
948 ParseExactHelper ("10:12", new string [] { "G", "g" }, false, false, "10:12:00");
949 ParseExactHelper ("10:12", new string [] { "g", "G" }, false, false, "10:12:00");
950 ParseExactHelper ("7.8:9:10", new string [] { "G", "g" }, true, false, "dontcare");
951 ParseExactHelper ("7.8:9:10", new string [] { "G", "g", "c" }, false, false, "7.08:09:10");
952 ParseExactHelper ("7:8:9:10", new string [] { "c", "g" }, false, false, "7.08:09:10");
953 ParseExactHelper ("7:8:9:10", new string [] { "c", "G" }, true, false, "dontcare");
954 ParseExactHelper ("7.123456789:1", new string [] { "c", "G", "g" }, true, false, "dontcare");
955 ParseExactHelper ("7.123456789:1", new string [] { "G", "g", "c" }, true, false, "dontcare");
956 ParseExactHelper ("1234567890123456", new string [] { "c", "g" }, true, false, "dontcare"); // I'd expect an OverflowException
957 ParseExactHelper ("10:12", new string [] { null, "c", "g" }, true, false, "10:12:00");
958 ParseExactHelper ("10:12", new string [] { String.Empty, "c", "g" }, true, false, "10:12:00");
961 [Test]
962 public void ParseExactCustomFormats ()
964 // Days
965 ParseExactHelper ("33", new string [] { "%d" }, false, false, "33.00:00:00");
966 ParseExactHelper ("00", new string [] { "%d" }, false, false, "00:00:00");
967 ParseExactHelper ("33", new string [] { "%dd" }, false, false, "33.00:00:00");
968 ParseExactHelper ("3333", new string [] { "%d" }, false, false, "3333.00:00:00");
969 ParseExactHelper ("3333", new string [] { "%ddd" }, true, false, "3333.00:00:00"); // 'dd' mismatch the digit count
970 ParseExactHelper ("3333", new string [] { "%dddd" }, false, false, "3333.00:00:00");
971 ParseExactHelper ("00033", new string [] { "%ddddd" }, false, false, "33.00:00:00");
972 ParseExactHelper ("00033", new string [] { "%d" }, false, false, "33.00:00:00");
973 ParseExactHelper ("00000003", new string [] { "%dddddddd" }, false, false, "3.00:00:00"); // up to 8 'd'
974 ParseExactHelper ("000000003", new string [] { "%ddddddddd" }, true, false, "dontcare");
975 ParseExactHelper ("33", new string [] { "d" }, true, false, "33.00:00:00"); // This is sort of weird.
976 ParseExactHelper ("33", new string [] { "dd" }, false, false, "33.00:00:00");
977 ParseExactHelper ("-33", new string [] { "%d" }, true, false, "dontcare");
978 ParseExactHelper ("33", new string [] { "%d" }, false, false, "-33.00:00:00", null, TimeSpanStyles.AssumeNegative);
980 // Hours
981 ParseExactHelper ("12", new string [] { "%h" }, false, false, "12:00:00");
982 ParseExactHelper ("00", new string [] { "%h" }, false, false, "00:00:00");
983 ParseExactHelper ("012", new string [] { "%h" }, true, false, "dontcare"); // more than 2 digits
984 ParseExactHelper ("00012", new string [] { "%hhhhh" }, true, false, "dontcare");
985 ParseExactHelper ("15", new string [] { "%h" }, false, false, "15:00:00");
986 ParseExactHelper ("24", new string [] { "%h" }, true, false, "dontcare");
987 ParseExactHelper ("15", new string [] { "%hh" }, false, false, "15:00:00");
988 ParseExactHelper ("1", new string [] { "%hh" }, true, false, "dontcare"); // 'hh' but a single digit
989 ParseExactHelper ("01", new string [] { "%hh" }, false, false, "01:00:00");
990 ParseExactHelper ("015", new string [] { "%hhh" }, true, false, "dontcare"); // Too many 'h'
991 ParseExactHelper ("12", new string [] { "h" }, true, false, "dontcare");
992 ParseExactHelper ("12", new string [] { "hh" }, false, false, "12:00:00");
993 ParseExactHelper ("-15", new string [] {"%h"}, true, false, "dontcare"); // Explicit - not accepted
994 ParseExactHelper ("15", new string [] { "%h" }, false, false, "-15:00:00", null, TimeSpanStyles.AssumeNegative);
995 ParseExactHelper ("15", new string [] { "%H" }, true, false, "dontcare"); // Uppercase is not accepted
997 // Minutes
998 ParseExactHelper ("12", new string [] { "%m" }, false, false, "00:12:00");
999 ParseExactHelper ("00", new string [] { "%m" }, false, false, "00:00:00");
1000 ParseExactHelper ("60", new string [] { "%m" }, true, false, "dontcare");
1001 ParseExactHelper ("12", new string [] { "%mm" }, false, false, "00:12:00");
1002 ParseExactHelper ("1", new string [] { "%mm" }, true, false, "dontcare");
1003 ParseExactHelper ("12", new string [] { "%mmm" }, true, false, "dontcare");
1004 ParseExactHelper ("12", new string [] { "m" }, true, false, "dontcare");
1005 ParseExactHelper ("12", new string [] { "mm" }, false, false, "00:12:00");
1006 ParseExactHelper ("-12", new string [] { "%m" }, true, false, "dontcare");
1007 ParseExactHelper ("12", new string [] { "%m" }, false, false, "-00:12:00", null, TimeSpanStyles.AssumeNegative);
1008 ParseExactHelper ("12", new string [] { "%M" }, true, false, "dontcare");
1010 // Seconds
1011 ParseExactHelper ("12", new string [] { "%s" }, false, false, "00:00:12");
1012 ParseExactHelper ("00", new string [] { "%s" }, false, false, "00:00:00");
1013 ParseExactHelper ("000", new string [] { "%s" }, true, false, "dontcare");
1014 ParseExactHelper ("12", new string [] { "%ss" }, false, false, "00:00:12");
1015 ParseExactHelper ("12", new string [] { "%sss" }, true, false, "dontcare");
1016 ParseExactHelper ("60", new string [] { "%s" }, true, false, "dontcare");
1017 ParseExactHelper ("-12", new string [] { "%s" }, true, false, "dontcare");
1018 ParseExactHelper ("12", new string [] { "%s" }, false, false, "-00:00:12", null, TimeSpanStyles.AssumeNegative);
1020 // Fractions of seconds - f
1021 ParseExactHelper ("3", new string [] { "%f" }, false, false, "00:00:00.3000000");
1022 ParseExactHelper ("0", new string [] { "%f" }, false, false, "00:00:00");
1023 ParseExactHelper ("03", new string [] { "%f" }, true, false, "dontcare"); // This would work for other elements
1024 ParseExactHelper ("10", new string [] { "%f" }, true, false, "dontcare"); // Only a digit is accepted with '%f'
1025 ParseExactHelper ("3", new string [] { "%ff" }, true, false, "dontcare");
1026 ParseExactHelper ("12", new string [] { "%ff" }, false, false, "00:00:00.1200000");
1027 ParseExactHelper ("123", new string [] { "%ff" }, true, false, "dontcare");
1028 ParseExactHelper ("123", new string [] { "%fff" }, false, false, "00:00:00.1230000");
1029 ParseExactHelper ("1234", new string [] { "%ffff" }, false, false, "00:00:00.1234000");
1030 ParseExactHelper ("1234567", new string [] { "%fffffff" }, false, false, "00:00:00.1234567");
1031 ParseExactHelper ("1234567", new string [] { "%FfFFFFF" }, true, false, "dontcare"); // Mixed f and M
1032 ParseExactHelper ("12345678", new string [] { "%ffffffff" }, true, false, "dontcare");
1033 ParseExactHelper ("0000000", new string [] { "%fffffff" }, false, false, "00:00:00");
1035 // Fractions of second - F
1036 ParseExactHelper ("3", new string [] { "%F" }, false, false, "00:00:00.3000000");
1037 ParseExactHelper ("333", new string [] { "%FFFFF" }, false, false, "00:00:00.3330000");
1038 ParseExactHelper ("1234567", new string [] { "%FFFFFFF" }, false, false, "00:00:00.1234567");
1040 // Multiple symbols
1041 ParseExactHelper ("9:10", new string [] { @"h\:m" }, false, false, "09:10:00");
1042 ParseExactHelper ("9;10", new string [] { @"h\;m" }, false, false, "09:10:00");
1043 ParseExactHelper ("10:9", new string [] { @"m\:h" }, false, false, "09:10:00");
1044 ParseExactHelper ("10:9", new string [] { @"%m\:%h" }, false, false, "09:10:00");
1045 ParseExactHelper ("9 10", new string [] { @"h\ m" }, false, false, "09:10:00");
1046 ParseExactHelper ("9 10", new string [] { @"h\ \ \ m" }, false, false, "09:10:00");
1047 ParseExactHelper (" 9:10 ", new string [] { @"h\:m" }, true, false, "dontcare");
1048 ParseExactHelper ("9:10:11", new string [] { @"h\:m\:s" }, false, false, "09:10:11");
1049 ParseExactHelper ("9:10:11:6", new string [] { @"h\:m\:s\:f" }, false, false, "09:10:11.6000000");
1050 ParseExactHelper ("9:10:11:666", new string [] { @"h\:m\:s\:f" }, true, false, "dontcare"); // fff with 1 digit
1051 ParseExactHelper ("9:10:11:", new string [] { @"h\:m\:s\:F" }, false, false, "09:10:11"); // optional frac of seconds
1052 ParseExactHelper ("9:10:11:", new string [] { @"h\:m\:s\:FF" }, false, false, "09:10:11");
1053 ParseExactHelper ("9:10:11::", new string [] { @"h\:m\:s\:F\:" }, false, false, "09:10:11");
1054 ParseExactHelper ("8:9:10:11:6666666", new string [] { @"d\:h\:m\:s\:fffffff" }, false, false, "8.09:10:11.6666666");
1055 ParseExactHelper ("8:9:10:11:6666666", new string [] { @"d\:h\:m\:s\:fffffff" }, false, false, "-8.09:10:11.6666666",
1056 null, TimeSpanStyles.AssumeNegative);
1057 ParseExactHelper ("9:10", new string [] { @"h\:h" }, true, false, "dontcare"); // Repeated element
1059 // Misc
1060 ParseExactHelper (" 0 ", new string [] { "%d" }, true, false, "dontcare");
1061 ParseExactHelper (" 0 ", new string [] { " %d " }, true, false, "dontcare");
1062 ParseExactHelper ("0", new string [] { " %d " }, true, false, "dontcare");
1063 ParseExactHelper ("::", new string [] { @"\:\:" }, false, false, "00:00:00"); // funny
1064 ParseExactHelper ("::", new string [] { @"\:\:" }, false, false, "00:00:00", null, TimeSpanStyles.AssumeNegative);
1065 ParseExactHelper (" 0", new string [] { @"\ d" }, false, false, "00:00:00");
1066 ParseExactHelper ("Interval = 12:13:14", new string [] { @"'Interval = 'h\:m\:s" }, false, false, "12:13:14");
1069 void ParseExactHelper (string input, string [] formats, bool format_error, bool overflow_error, string expected,
1070 IFormatProvider formatProvider = null, TimeSpanStyles timeSpanStyles = TimeSpanStyles.None)
1072 bool overflow_exc = false;
1073 bool format_exc = false;
1074 TimeSpan result = TimeSpan.Zero;
1076 try {
1077 result = TimeSpan.ParseExact (input, formats, formatProvider, timeSpanStyles);
1078 } catch (OverflowException) {
1079 overflow_exc = true;
1080 } catch (FormatException) {
1081 format_exc = true;
1084 Assert.AreEqual (format_error, format_exc, "A1");
1085 Assert.AreEqual (overflow_error, overflow_exc, "A2");
1086 if (!overflow_exc && !format_exc)
1087 Assert.AreEqual (expected, result.ToString ());
1090 // 'Ported' the ParseExact test to use TryParseExact instead.
1091 [Test]
1092 [Category ("Calendars")]
1093 public void TryParseExact ()
1095 CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
1096 CultureInfo us_culture = CultureInfo.GetCultureInfo ("en-US");
1099 // 'g' format - this is the short and culture sensitive format
1101 string [] g_format = new string [] { "g" };
1102 TryParseExactHelper ("12", g_format, false, "12.00:00:00");
1103 TryParseExactHelper ("11:12", g_format, false, "11:12:00");
1104 TryParseExactHelper ("-11:12", g_format, false, "-11:12:00");
1105 TryParseExactHelper ("25:13", g_format, true, "dontcare");
1106 TryParseExactHelper ("11:66", g_format, true, "dontcare"); // I'd have expected OverflowExc here
1107 TryParseExactHelper ("11:12:13", g_format, false, "11:12:13");
1108 TryParseExactHelper ("-11:12:13", g_format, false, "-11:12:13");
1109 TryParseExactHelper ("10.11:12:13", g_format, true, "dontcare"); // this should work as well
1110 TryParseExactHelper ("10.11:12:13", g_format, true, "dontcare", us_culture);
1111 TryParseExactHelper ("10.11:12:13", g_format, true, "dontcare", CultureInfo.InvariantCulture);
1112 TryParseExactHelper ("10:11:12:66", g_format, true, "dontcare");
1113 TryParseExactHelper ("10:11:12:13", g_format, false, "10.11:12:13");
1114 TryParseExactHelper ("11:12:13.6", g_format, false, "11:12:13.6000000", CultureInfo.InvariantCulture);
1115 TryParseExactHelper ("11:12:13,6", g_format, false, "11:12:13.6000000", french_culture);
1116 TryParseExactHelper ("10:11:12:13.6", g_format, false, "10.11:12:13.6000000", us_culture);
1117 TryParseExactHelper (" 10:11:12:13.6 ", g_format, false, "10.11:12:13.6000000", us_culture);
1118 TryParseExactHelper ("10:11", g_format, false, "10:11:00", null, TimeSpanStyles.None);
1119 TryParseExactHelper ("10:11", g_format, false, "10:11:00", null, TimeSpanStyles.AssumeNegative); // no effect
1122 // G format
1124 string [] G_format = new string [] { "G" };
1125 TryParseExactHelper ("9:10:12", G_format, true, "dontcare");
1126 TryParseExactHelper ("9:10:12.6", G_format, true, "dontcare");
1127 TryParseExactHelper ("3.9:10:12", G_format, true, "dontcare");
1128 TryParseExactHelper ("3.9:10:12.153", G_format, true, "dontcare"); // this should be valid...
1129 TryParseExactHelper ("3:9:10:12.153", G_format, false, "3.09:10:12.1530000", us_culture);
1130 TryParseExactHelper ("0:9:10:12.153", G_format, false, "09:10:12.1530000", us_culture);
1131 TryParseExactHelper ("03:09:10:12.153", G_format, false, "3.09:10:12.1530000", us_culture);
1132 TryParseExactHelper ("003:009:0010:0012.00153", G_format, false, "3.09:10:12.0015300", us_culture);
1133 TryParseExactHelper ("3:9:10:66.153", G_format, true, "dontcare"); // seconds out of range
1134 TryParseExactHelper ("3:9:10:12.153", G_format, true, "dontcare", french_culture); // fr-FR uses ',' as decimal separator
1135 TryParseExactHelper ("3:9:10:12,153", G_format, false, "3.09:10:12.1530000", french_culture);
1136 TryParseExactHelper (" 3:9:10:12.153 ", G_format, false, "3.09:10:12.1530000", us_culture);
1137 TryParseExactHelper ("3:9:10:13.153", G_format, false, "3.09:10:13.1530000", us_culture, TimeSpanStyles.AssumeNegative);
1139 // c format
1140 string [] c_format = new string [] { "c" };
1141 TryParseExactHelper ("12", c_format, false, "12.00:00:00");
1142 TryParseExactHelper ("12:11", c_format, false, "12:11:00");
1143 TryParseExactHelper ("12:66", c_format, true, "dontcare");
1144 TryParseExactHelper ("10.11:12", c_format, false, "10.11:12:00");
1145 TryParseExactHelper ("10.11:12:13", c_format, false, "10.11:12:13");
1146 TryParseExactHelper ("10:11:12:13", c_format, true, "dontcare"); // this is normally accepted in the Parse method
1147 TryParseExactHelper ("10.11:12:13.6", c_format, false, "10.11:12:13.6000000");
1148 TryParseExactHelper ("10:11:12,6", c_format, true, "dontcare");
1149 TryParseExactHelper ("10:11:12,6", c_format, true, "dontcare", french_culture);
1150 TryParseExactHelper (" 10:11:12.6 ", c_format, false, "10:11:12.6000000");
1151 TryParseExactHelper ("10:12", c_format, false, "10:12:00", null, TimeSpanStyles.AssumeNegative);
1152 TryParseExactHelper ("10:123456789999", c_format, true, "dontcare");
1154 TryParseExactHelper ("10:12", new string [0], true, "dontcare");
1155 TryParseExactHelper ("10:12", new string [] { String.Empty }, true, "dontcare");
1156 TryParseExactHelper ("10:12", new string [] { null }, true, "dontcare");
1158 TryParseExactHelper (null, new string [] { null }, true, "dontcare");
1161 void TryParseExactHelper (string input, string [] formats, bool error, string expected, IFormatProvider formatProvider = null,
1162 TimeSpanStyles styles = TimeSpanStyles.None)
1164 TimeSpan result;
1165 bool success;
1167 success = TimeSpan.TryParseExact (input, formats, formatProvider, styles, out result);
1168 Assert.AreEqual (!error, success);
1169 if (!error)
1170 Assert.AreEqual (expected, result.ToString ());
1173 [Test]
1174 public void ParseExactExceptions ()
1176 try {
1177 TimeSpan.ParseExact (null, "g", null);
1178 Assert.Fail ("#A1");
1179 } catch (ArgumentNullException) {
1182 try {
1183 TimeSpan.ParseExact ("10:12", (string)null, null);
1184 Assert.Fail ("#A2");
1185 } catch (ArgumentNullException) {
1188 try {
1189 TimeSpan.ParseExact ("10:12", (string [])null, null);
1190 Assert.Fail ("#A3");
1191 } catch (ArgumentNullException) {
1195 [Test]
1196 public void ToStringOverloads ()
1198 TimeSpan ts = new TimeSpan (1, 2, 3, 4, 6);
1200 // Simple version - culture invariant
1201 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString (), "#A1");
1202 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString ("c"), "#A2");
1203 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString (null), "#A3");
1204 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString (String.Empty), "#A4");
1206 if (!GlobalizationMode.Invariant) {
1208 // IFormatProvider ones - use a culture changing numeric format.
1209 // Also, we use fr-FR as culture, since it uses some elements different to invariant culture
1211 CultureInfo culture = CultureInfo.GetCultureInfo ("fr-FR");
1213 Assert.AreEqual ("1:2:03:04,006", ts.ToString ("g", culture), "#B1");
1214 Assert.AreEqual ("1:02:03:04,0060000", ts.ToString ("G", culture), "#B2");
1215 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString ("c", culture), "#B3"); // 'c' format ignores CultureInfo
1216 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString ("t", culture), "#B4"); // 't' and 'T' are the same as 'c'
1217 Assert.AreEqual("1.02:03:04.0060000", ts.ToString("T", culture), "#B5");
1219 ts = new TimeSpan (4, 5, 6);
1220 Assert.AreEqual ("4:05:06", ts.ToString ("g", culture), "#C1");
1221 Assert.AreEqual ("0:04:05:06,0000000", ts.ToString ("G", culture), "#C2");
1225 [Test]
1226 public void ToStringCustomFormats ()
1228 TimeSpan ts = new TimeSpan (1, 3, 5, 7);
1230 Assert.AreEqual ("1", ts.ToString ("%d"), "#A0");
1231 Assert.AreEqual ("3", ts.ToString ("%h"), "#A1");
1232 Assert.AreEqual ("5", ts.ToString ("%m"), "#A2");
1233 Assert.AreEqual ("7", ts.ToString ("%s"), "#A3");
1234 Assert.AreEqual ("0", ts.ToString ("%f"), "#A4");
1235 Assert.AreEqual (String.Empty, ts.ToString ("%F"), "#A5"); // Nothing to display
1237 Assert.AreEqual ("01", ts.ToString ("dd"), "#B0");
1238 Assert.AreEqual ("00000001", ts.ToString ("dddddddd"), "#B1");
1239 Assert.AreEqual ("03", ts.ToString ("hh"), "#B2");
1240 Assert.AreEqual ("05", ts.ToString ("mm"), "#B3");
1241 Assert.AreEqual ("07", ts.ToString ("ss"), "#B4");
1242 Assert.AreEqual ("00", ts.ToString ("ff"), "#B5");
1243 Assert.AreEqual ("0000000", ts.ToString ("fffffff"), "#B6");
1244 Assert.AreEqual (String.Empty, ts.ToString ("FF"), "#B7");
1246 Assert.AreEqual ("01;03;05", ts.ToString (@"dd\;hh\;mm"), "#C0");
1247 Assert.AreEqual ("05 07", ts.ToString (@"mm\ ss"), "#C1");
1248 Assert.AreEqual ("05 07 ", ts.ToString (@"mm\ ss\ FF"), "#C2");
1249 Assert.AreEqual ("Result = 3 hours with 5 minutes and 7 seconds",
1250 ts.ToString (@"'Result = 'h' hours with 'm' minutes and 's' seconds'"), "#C3");
1251 Assert.AreEqual (" ", ts.ToString (@"\ \ "), "#C4");
1253 ts = new TimeSpan (1, 3, 5, 7, 153);
1254 Assert.AreEqual ("1", ts.ToString ("%F"), "#D0");
1255 Assert.AreEqual ("15", ts.ToString ("FF"), "#D1"); // Don't use %, as the parser gets confused here
1256 Assert.AreEqual ("153", ts.ToString ("FFFFFFF"), "#D2");
1258 // Negative values are shown without sign
1259 ts = new TimeSpan (-1, -3, -5);
1260 Assert.AreEqual ("1", ts.ToString ("%h"), "#E0");
1261 Assert.AreEqual ("3", ts.ToString ("%m"), "#E1");
1262 Assert.AreEqual ("5", ts.ToString ("%s"), "#E2");
1264 ts = new TimeSpan (123456789);
1265 Assert.AreEqual ("12.3", ts.ToString ("s\\.f"), "#F0");
1266 Assert.AreEqual ("12.3", ts.ToString ("s\\.F"), "#F1");
1267 Assert.AreEqual ("12.3456789", ts.ToString ("s\\.fffffff"), "#F2");
1268 Assert.AreEqual ("12.345678", ts.ToString ("s\\.ffffff"), "#F3");
1270 ts = new TimeSpan (1234);
1271 Assert.AreEqual ("0.000123", ts.ToString ("s\\.ffffff"), "#G0");
1272 Assert.AreEqual ("0.0001", ts.ToString ("s\\.ffff"), "#G1");
1273 Assert.AreEqual ("0.", ts.ToString ("s\\.F"), "#G2");
1274 Assert.AreEqual ("0.", ts.ToString ("s\\.FFF"), "#G3");
1276 ts = TimeSpan.FromSeconds (0.05);
1277 Assert.AreEqual (".0", ts.ToString ("\\.f"), "#H0");
1278 Assert.AreEqual (".", ts.ToString ("\\.F"), "#H1");
1281 [Test]
1282 public void ToStringOverloadsErrors ()
1284 TimeSpan ts = new TimeSpan (10, 10, 10);
1285 string result;
1287 try {
1288 result = ts.ToString ("non-valid");
1289 Assert.Fail ("#1");
1290 } catch (FormatException) {
1293 try {
1294 result = ts.ToString ("C");
1295 Assert.Fail ("#2");
1296 } catch (FormatException) {
1301 ts.ToString ("m");
1302 Assert.Fail ("#3");
1303 } catch (FormatException) {
1308 ts.ToString ("d"); // Missing % for single char
1309 Assert.Fail ("#4");
1310 } catch (FormatException)
1316 ts.ToString ("ddddddddd");
1317 Assert.Fail ("#5");
1318 } catch (FormatException)
1324 ts.ToString ("hhh");
1325 Assert.Fail ("#5");
1326 } catch (FormatException)
1332 ts.ToString ("ffffffff");
1333 Assert.Fail ("6");
1334 } catch (FormatException)