2 // TimeSpanTest.cs - NUnit Test Cases for the System.TimeSpan struct
5 // Duco Fijma (duco@lorentz.xs4all.nl)
6 // Sebastien Pouliot <sebastien@ximian.com>
9 // Copyright (C) 2004 Novell (http://www.novell.com)
12 using NUnit
.Framework
;
14 using System
.Globalization
;
15 using System
.Threading
;
17 namespace MonoTests
.System
21 public class TimeSpanTest
{
23 private void Debug (TimeSpan ts
)
25 Console
.Out
.WriteLine ("Days {0}", ts
.Days
);
26 Console
.Out
.WriteLine ("Hours {0}", ts
.Hours
);
27 Console
.Out
.WriteLine ("Minutes {0}", ts
.Minutes
);
28 Console
.Out
.WriteLine ("Seconds {0}", ts
.Seconds
);
29 Console
.Out
.WriteLine ("Milliseconds {0}", ts
.Milliseconds
);
30 Console
.Out
.WriteLine ("Ticks {0}", ts
.Ticks
);
34 public void TestCtors ()
36 TimeSpan t1
= new TimeSpan (1234567890);
38 Assert
.AreEqual ("00:02:03.4567890", t1
.ToString (), "A1");
39 t1
= new TimeSpan (1,2,3);
40 Assert
.AreEqual ("01:02:03", t1
.ToString (), "A2");
41 t1
= new TimeSpan (1,2,3,4);
42 Assert
.AreEqual ("1.02:03:04", t1
.ToString (), "A3");
43 t1
= new TimeSpan (1,2,3,4,5);
44 Assert
.AreEqual ("1.02:03:04.0050000", t1
.ToString (), "A4");
45 t1
= new TimeSpan (-1,2,-3,4,-5);
46 Assert
.AreEqual ("-22:02:56.0050000", t1
.ToString (), "A5");
47 t1
= new TimeSpan (0,25,0,0,0);
48 Assert
.AreEqual ("1.01:00:00", t1
.ToString (), "A6");
52 [ExpectedException (typeof (ArgumentOutOfRangeException
))]
53 public void DaysOverflow ()
55 int days
= (int) (Int64
.MaxValue
/ TimeSpan
.TicksPerDay
) + 1;
56 TimeSpan ts
= new TimeSpan (days
, 0, 0, 0, 0);
60 [ExpectedException (typeof (ArgumentOutOfRangeException
))]
61 public void TemporaryOverflow ()
63 // calculating part of this results in overflow (days)
64 // but the negative hours, minutes, seconds & ms correct this
65 int days
= (int) (Int64
.MaxValue
/ TimeSpan
.TicksPerDay
) + 1;
66 TimeSpan ts
= new TimeSpan (days
, Int32
.MinValue
, Int32
.MinValue
, Int32
.MinValue
, Int32
.MinValue
);
67 Assert
.AreEqual (10650320, ts
.Days
, "Days");
68 Assert
.AreEqual (0, ts
.Hours
, "Hours");
69 Assert
.AreEqual (14, ts
.Minutes
, "Minutes");
70 Assert
.AreEqual (28, ts
.Seconds
, "Seconds");
71 Assert
.AreEqual (352, ts
.Milliseconds
, "Milliseconds");
72 Assert
.AreEqual (9201876488683520000, ts
.Ticks
, "Ticks");
76 [ExpectedException (typeof (ArgumentOutOfRangeException
))]
77 public void NoOverflowInHoursMinsSecondsMS ()
79 TimeSpan ts
= new TimeSpan (0, Int32
.MaxValue
, Int32
.MaxValue
, Int32
.MaxValue
, Int32
.MaxValue
);
80 Assert
.AreEqual (24879, ts
.Days
, "Days");
81 Assert
.AreEqual (22, ts
.Hours
, "Hours");
82 Assert
.AreEqual (44, ts
.Minutes
, "Minutes");
83 Assert
.AreEqual (30, ts
.Seconds
, "Seconds");
84 Assert
.AreEqual (647, ts
.Milliseconds
, "Milliseconds");
85 Assert
.AreEqual (21496274706470000, ts
.Ticks
, "Ticks");
89 [ExpectedException (typeof (ArgumentOutOfRangeException
))]
90 public void MaxDays ()
92 new TimeSpan (Int32
.MaxValue
, 0, 0, 0, 0);
96 [ExpectedException (typeof (ArgumentOutOfRangeException
))]
97 public void MinDays ()
99 new TimeSpan (Int32
.MinValue
, 0, 0, 0, 0);
103 [ExpectedException (typeof (ArgumentOutOfRangeException
))]
104 public void MaxHours ()
106 // LAMESPEC: the highest hours are "special"
107 TimeSpan ts
= new TimeSpan (0, Int32
.MaxValue
, 0, 0, 0);
108 Assert
.AreEqual (0, ts
.Days
, "Max-Days");
109 Assert
.AreEqual (-1, ts
.Hours
, "Max-Hours");
110 Assert
.AreEqual (0, ts
.Minutes
, "Max-Minutes");
111 Assert
.AreEqual (0, ts
.Seconds
, "Max-Seconds");
112 Assert
.AreEqual (0, ts
.Milliseconds
, "Max-Milliseconds");
113 Assert
.AreEqual (-36000000000, ts
.Ticks
, "Max-Ticks");
115 ts
= new TimeSpan (0, Int32
.MaxValue
- 596522, 0, 0, 0);
116 Assert
.AreEqual (-24855, ts
.Days
, "Days");
117 Assert
.AreEqual (-3, ts
.Hours
, "Hours");
118 Assert
.AreEqual (0, ts
.Minutes
, "Minutes");
119 Assert
.AreEqual (0, ts
.Seconds
, "Seconds");
120 Assert
.AreEqual (0, ts
.Milliseconds
, "Milliseconds");
121 Assert
.AreEqual (-21474828000000000, ts
.Ticks
, "Ticks");
125 [ExpectedException (typeof (ArgumentOutOfRangeException
))]
126 public void MaxHours_BreakPoint ()
128 TimeSpan ts
= new TimeSpan (0, Int32
.MaxValue
- 596523, 0, 0, 0);
129 Assert
.AreEqual (24855, ts
.Days
, "Days");
130 Assert
.AreEqual (2, ts
.Hours
, "Hours");
131 Assert
.AreEqual (28, ts
.Minutes
, "Minutes");
132 Assert
.AreEqual (16, ts
.Seconds
, "Seconds");
133 Assert
.AreEqual (0, ts
.Milliseconds
, "Milliseconds");
134 Assert
.AreEqual (21474808960000000, ts
.Ticks
, "Ticks");
138 public void MinHours ()
140 TimeSpan ts
= new TimeSpan (0, -256204778, 0, 0, 0);
141 Assert
.AreEqual (-10675199, ts
.Days
, "Days");
142 Assert
.AreEqual (-2, ts
.Hours
, "Hours");
143 Assert
.AreEqual (0, ts
.Minutes
, "Minutes");
144 Assert
.AreEqual (0, ts
.Seconds
, "Seconds");
145 Assert
.AreEqual (0, ts
.Milliseconds
, "Milliseconds");
146 Assert
.AreEqual (-9223372008000000000, ts
.Ticks
, "Ticks");
150 [ExpectedException (typeof (ArgumentOutOfRangeException
))]
151 public void MinHours_BreakPoint ()
153 TimeSpan ts
= new TimeSpan (0, -2146887124, 0, 0, 0);
154 Assert
.AreEqual (-24855, ts
.Days
, "Days");
155 Assert
.AreEqual (-2, ts
.Hours
, "Hours");
156 Assert
.AreEqual (-28, ts
.Minutes
, "Minutes");
157 Assert
.AreEqual (-16, ts
.Seconds
, "Seconds");
158 Assert
.AreEqual (0, ts
.Milliseconds
, "Milliseconds");
159 Assert
.AreEqual (-21474808960000000, ts
.Ticks
, "Ticks");
163 public void MaxMinutes ()
166 ts
= new TimeSpan (0, 0, 256204778, 0, 0);
167 Assert
.AreEqual (177919, ts
.Days
, "Max-Days");
168 Assert
.AreEqual (23, ts
.Hours
, "Max-Hours");
169 Assert
.AreEqual (38, ts
.Minutes
, "Max-Minutes");
170 Assert
.AreEqual (0, ts
.Seconds
, "Max-Seconds");
171 Assert
.AreEqual (0, ts
.Milliseconds
, "Max-Milliseconds");
172 Assert
.AreEqual (153722866800000000, ts
.Ticks
, "Max-Ticks");
176 [ExpectedException (typeof (ArgumentOutOfRangeException
))]
177 public void MaxMinutes_BreakPoint ()
179 TimeSpan ts
= new TimeSpan (0, Int32
.MaxValue
- 35791394, 0, 0, 0);
180 Assert
.AreEqual (0, ts
.Days
, "Days");
181 Assert
.AreEqual (0, ts
.Hours
, "Hours");
182 Assert
.AreEqual (-52, ts
.Minutes
, "Minutes");
183 Assert
.AreEqual (0, ts
.Seconds
, "Seconds");
184 Assert
.AreEqual (0, ts
.Milliseconds
, "Milliseconds");
185 Assert
.AreEqual (-31200000000, ts
.Ticks
, "Ticks");
189 public void MinMinutes ()
192 ts
= new TimeSpan (0, 0, Int32
.MinValue
, 0, 0);
193 Assert
.AreEqual (-1491308, ts
.Days
, "Days");
194 Assert
.AreEqual (-2, ts
.Hours
, "Hours");
195 Assert
.AreEqual (-8, ts
.Minutes
, "Minutes");
196 Assert
.AreEqual (0, ts
.Seconds
, "Seconds");
197 Assert
.AreEqual (0, ts
.Milliseconds
, "Milliseconds");
198 Assert
.AreEqual (-1288490188800000000, ts
.Ticks
, "Ticks");
202 public void MinMinutes_BreakPoint ()
204 TimeSpan ts
= new TimeSpan (0, 0, -2111692253, 0, 0);
205 Assert
.AreEqual (-1466452, ts
.Days
, "Days");
206 Assert
.AreEqual (-22, ts
.Hours
, "Hours");
207 Assert
.AreEqual (-53, ts
.Minutes
, "Minutes");
208 Assert
.AreEqual (-0, ts
.Seconds
, "Seconds");
209 Assert
.AreEqual (0, ts
.Milliseconds
, "Milliseconds");
210 Assert
.AreEqual (-1267015351800000000, ts
.Ticks
, "Ticks");
214 public void MaxSeconds ()
216 TimeSpan ts
= new TimeSpan (0, 0, 0, Int32
.MaxValue
, 0);
217 Assert
.AreEqual (24855, ts
.Days
, "Days");
218 Assert
.AreEqual (3, ts
.Hours
, "Hours");
219 Assert
.AreEqual (14, ts
.Minutes
, "Minutes");
220 Assert
.AreEqual (7, ts
.Seconds
, "Seconds");
221 Assert
.AreEqual (0, ts
.Milliseconds
, "Milliseconds");
222 Assert
.AreEqual (21474836470000000, ts
.Ticks
, "Ticks");
226 public void MinSeconds ()
228 TimeSpan ts
= new TimeSpan (0, 0, 0, Int32
.MinValue
, 0);
229 Assert
.AreEqual (-24855, ts
.Days
, "Days");
230 Assert
.AreEqual (-3, ts
.Hours
, "Hours");
231 Assert
.AreEqual (-14, ts
.Minutes
, "Minutes");
232 Assert
.AreEqual (-8, ts
.Seconds
, "Seconds");
233 Assert
.AreEqual (0, ts
.Milliseconds
, "Milliseconds");
234 Assert
.AreEqual (-21474836480000000, ts
.Ticks
, "Ticks");
238 public void MaxMilliseconds ()
240 TimeSpan ts
= new TimeSpan (0, 0, 0, 0, Int32
.MaxValue
);
241 Assert
.AreEqual (24, ts
.Days
, "Days");
242 Assert
.AreEqual (20, ts
.Hours
, "Hours");
243 Assert
.AreEqual (31, ts
.Minutes
, "Minutes");
244 Assert
.AreEqual (23, ts
.Seconds
, "Seconds");
245 Assert
.AreEqual (647, ts
.Milliseconds
, "Milliseconds");
246 Assert
.AreEqual (21474836470000, ts
.Ticks
, "Ticks");
250 public void MinMilliseconds ()
252 TimeSpan ts
= new TimeSpan (0, 0, 0, 0, Int32
.MinValue
);
253 Assert
.AreEqual (-24, ts
.Days
, "Days");
254 Assert
.AreEqual (-20, ts
.Hours
, "Hours");
255 Assert
.AreEqual (-31, ts
.Minutes
, "Minutes");
256 Assert
.AreEqual (-23, ts
.Seconds
, "Seconds");
257 Assert
.AreEqual (-648, ts
.Milliseconds
, "Milliseconds");
258 Assert
.AreEqual (-21474836480000, ts
.Ticks
, "Ticks");
262 public void NegativeTimeSpan ()
264 TimeSpan ts
= new TimeSpan (-23, -59, -59);
265 Assert
.AreEqual (0, ts
.Days
, "Days");
266 Assert
.AreEqual (-23, ts
.Hours
, "Hours");
267 Assert
.AreEqual (-59, ts
.Minutes
, "Minutes");
268 Assert
.AreEqual (-59, ts
.Seconds
, "Seconds");
269 Assert
.AreEqual (0, ts
.Milliseconds
, "Milliseconds");
270 Assert
.AreEqual (-863990000000, ts
.Ticks
, "Ticks");
274 public void TestProperties ()
276 TimeSpan t1
= new TimeSpan (1,2,3,4,5);
279 Assert
.AreEqual (1, t1
.Days
, "A1");
280 Assert
.AreEqual (2, t1
.Hours
, "A2");
281 Assert
.AreEqual (3, t1
.Minutes
, "A3");
282 Assert
.AreEqual (4, t1
.Seconds
, "A4");
283 Assert
.AreEqual (5, t1
.Milliseconds
, "A5");
284 Assert
.AreEqual (-1, t2
.Days
, "A6");
285 Assert
.AreEqual (-2, t2
.Hours
, "A7");
286 Assert
.AreEqual (-3, t2
.Minutes
, "A8");
287 Assert
.AreEqual (-4, t2
.Seconds
, "A9");
288 Assert
.AreEqual (-5, t2
.Milliseconds
, "A10");
292 public void TestAdd ()
294 TimeSpan t1
= new TimeSpan (2,3,4,5,6);
295 TimeSpan t2
= new TimeSpan (1,2,3,4,5);
296 TimeSpan t3
= t1
+ t2
;
297 TimeSpan t4
= t1
.Add (t2
);
301 Assert
.AreEqual (3, t3
.Days
, "A1");
302 Assert
.AreEqual (5, t3
.Hours
, "A2");
303 Assert
.AreEqual (7, t3
.Minutes
, "A3");
304 Assert
.AreEqual (9, t3
.Seconds
, "A4");
305 Assert
.AreEqual (11, t3
.Milliseconds
, "A5");
306 Assert
.AreEqual ("3.05:07:09.0110000", t4
.ToString (), "A6");
309 t5
= TimeSpan
.MaxValue
+ new TimeSpan (1);
312 catch (OverflowException
)
316 Assert
.IsTrue (exception
, "A7");
320 public void TestCompare ()
322 TimeSpan t1
= new TimeSpan (-1);
323 TimeSpan t2
= new TimeSpan (1);
327 Assert
.AreEqual (-1, TimeSpan
.Compare (t1
, t2
), "A1");
328 Assert
.AreEqual (1, TimeSpan
.Compare (t2
, t1
), "A2");
329 Assert
.AreEqual (0, TimeSpan
.Compare (t2
, t2
), "A3");
330 Assert
.AreEqual (-1, TimeSpan
.Compare (TimeSpan
.MinValue
, TimeSpan
.MaxValue
), "A4");
331 Assert
.AreEqual (-1, t1
.CompareTo (t2
), "A5");
332 Assert
.AreEqual (1, t2
.CompareTo (t1
), "A6");
333 Assert
.AreEqual (0, t2
.CompareTo (t2
), "A7");
334 Assert
.AreEqual (-1, TimeSpan
.Compare (TimeSpan
.MinValue
, TimeSpan
.MaxValue
), "A8");
336 Assert
.AreEqual (1, TimeSpan
.Zero
.CompareTo (null), "A9");
340 res
= TimeSpan
.Zero
.CompareTo("");
343 catch (ArgumentException
)
347 Assert
.IsTrue (exception
, "A10");
349 Assert
.AreEqual (false, t1
== t2
, "A11");
350 Assert
.AreEqual (false, t1
> t2
, "A12");
351 Assert
.AreEqual (false, t1
>= t2
, "A13");
352 Assert
.AreEqual (true, t1
!= t2
, "A14");
353 Assert
.AreEqual (true, t1
< t2
, "A15");
354 Assert
.AreEqual (true, t1
<= t2
, "A16");
358 [ExpectedException (typeof (OverflowException
))]
359 public void NoNegateMinValue() {
360 TimeSpan t1
= TimeSpan
.MinValue
.Negate ();
364 public void TestNegateAndDuration ()
369 Assert
.AreEqual ("-00:00:00.0012345", new TimeSpan (12345).Negate ().ToString (), "A1");
370 Assert
.AreEqual ("00:00:00.0012345", new TimeSpan (-12345).Duration ().ToString (), "A2");
374 t1
= TimeSpan
.MinValue
.Duration ();
377 catch (OverflowException
) {
380 Assert
.IsTrue (exception
, "A4");
382 Assert
.AreEqual ("-00:00:00.0000077", (-(new TimeSpan (77))).ToString (), "A5");
383 Assert
.AreEqual ("00:00:00.0000077", (+(new TimeSpan(77))).ToString(), "A6");
387 public void TestEquals ()
389 TimeSpan t1
= new TimeSpan (1);
390 TimeSpan t2
= new TimeSpan (2);
391 string s
= "justastring";
393 Assert
.AreEqual (true, t1
.Equals (t1
), "A1");
394 Assert
.AreEqual (false, t1
.Equals (t2
), "A2");
395 Assert
.AreEqual (false, t1
.Equals (s
), "A3");
396 Assert
.AreEqual (false, t1
.Equals (null), "A4");
397 Assert
.AreEqual (true, TimeSpan
.Equals (t1
, t1
), "A5");
398 Assert
.AreEqual (false, TimeSpan
.Equals (t1
, t2
), "A6");
399 Assert
.AreEqual (false, TimeSpan
.Equals (t1
, null), "A7");
400 Assert
.AreEqual (false, TimeSpan
.Equals (t1
, s
), "A8");
401 Assert
.AreEqual (false, TimeSpan
.Equals (s
, t2
), "A9");
402 Assert
.AreEqual (true, TimeSpan
.Equals (null, null), "A10");
406 public void TestFromXXXX ()
408 Assert
.AreEqual ("12.08:16:48", TimeSpan
.FromDays (12.345).ToString (), "A1");
409 Assert
.AreEqual ("12:20:42", TimeSpan
.FromHours (12.345).ToString (), "A2");
410 Assert
.AreEqual ("00:12:20.7000000", TimeSpan
.FromMinutes (12.345).ToString (), "A3");
411 Assert
.AreEqual ("00:00:12.3450000", TimeSpan
.FromSeconds (12.345).ToString (), "A4");
412 Assert
.AreEqual ("00:00:00.0120000", TimeSpan
.FromMilliseconds (12.345).ToString (), "A5");
413 Assert
.AreEqual ("00:00:00.0012345", TimeSpan
.FromTicks (12345).ToString (), "A6");
414 Assert
.AreEqual ("-00:00:00.0010000", TimeSpan
.FromMilliseconds (-0.5).ToString (), "A7");
415 Assert
.AreEqual ("00:00:00.0010000", TimeSpan
.FromMilliseconds (0.5).ToString (), "A8");
416 Assert
.AreEqual ("-00:00:00.0030000", TimeSpan
.FromMilliseconds (-2.5).ToString (), "A9");
417 Assert
.AreEqual ("00:00:00.0030000", TimeSpan
.FromMilliseconds (2.5).ToString (), "A10");
418 Assert
.AreEqual ("00:00:00.0010000", TimeSpan
.FromSeconds (0.0005).ToString (), "A11");
422 [ExpectedException (typeof (OverflowException
))]
423 public void FromDays_MinValue ()
425 TimeSpan
.FromDays (Double
.MinValue
);
429 [ExpectedException (typeof (OverflowException
))]
430 public void FromDays_MaxValue ()
432 TimeSpan
.FromDays (Double
.MaxValue
);
436 [ExpectedException (typeof (ArgumentException
))]
437 public void FromDays_NaN ()
439 TimeSpan
.FromDays (Double
.NaN
);
443 [ExpectedException (typeof (OverflowException
))]
444 public void FromDays_PositiveInfinity ()
446 // LAMESPEC: Document to return TimeSpan.MaxValue
447 Assert
.AreEqual (TimeSpan
.MaxValue
, TimeSpan
.FromDays (Double
.PositiveInfinity
));
451 [ExpectedException (typeof (OverflowException
))]
452 public void FromDays_NegativeInfinity ()
454 // LAMESPEC: Document to return TimeSpan.MinValue
455 Assert
.AreEqual (TimeSpan
.MinValue
, TimeSpan
.FromDays (Double
.NegativeInfinity
));
459 [ExpectedException (typeof (OverflowException
))]
460 public void FromHours_MinValue ()
462 TimeSpan
.FromHours (Double
.MinValue
);
466 [ExpectedException (typeof (OverflowException
))]
467 public void FromHours_MaxValue ()
469 TimeSpan
.FromHours (Double
.MaxValue
);
473 [ExpectedException (typeof (ArgumentException
))]
474 public void FromHours_NaN ()
476 TimeSpan
.FromHours (Double
.NaN
);
480 [ExpectedException (typeof (OverflowException
))]
481 public void FromHours_PositiveInfinity ()
483 // LAMESPEC: Document to return TimeSpan.MaxValue
484 Assert
.AreEqual (TimeSpan
.MaxValue
, TimeSpan
.FromHours (Double
.PositiveInfinity
));
488 [ExpectedException (typeof (OverflowException
))]
489 public void FromHours_NegativeInfinity ()
491 // LAMESPEC: Document to return TimeSpan.MinValue
492 Assert
.AreEqual (TimeSpan
.MinValue
, TimeSpan
.FromHours (Double
.NegativeInfinity
));
496 [ExpectedException (typeof (OverflowException
))]
497 public void FromMilliseconds_MinValue ()
499 TimeSpan
.FromMilliseconds (Double
.MinValue
);
503 [ExpectedException (typeof (OverflowException
))]
504 public void FromMilliseconds_MaxValue ()
506 TimeSpan
.FromMilliseconds (Double
.MaxValue
);
510 [ExpectedException (typeof (ArgumentException
))]
511 public void FromMilliseconds_NaN ()
513 TimeSpan
.FromMilliseconds (Double
.NaN
);
517 [ExpectedException (typeof (OverflowException
))]
518 public void FromMilliseconds_PositiveInfinity ()
520 // LAMESPEC: Document to return TimeSpan.MaxValue
521 Assert
.AreEqual (TimeSpan
.MaxValue
, TimeSpan
.FromMilliseconds (Double
.PositiveInfinity
));
525 [ExpectedException (typeof (OverflowException
))]
526 public void FromMilliseconds_NegativeInfinity ()
528 // LAMESPEC: Document to return TimeSpan.MinValue
529 Assert
.AreEqual (TimeSpan
.MinValue
, TimeSpan
.FromMilliseconds (Double
.NegativeInfinity
));
533 [ExpectedException (typeof (OverflowException
))]
534 public void FromMinutes_MinValue ()
536 TimeSpan
.FromMinutes (Double
.MinValue
);
540 [ExpectedException (typeof (OverflowException
))]
541 public void FromMinutes_MaxValue ()
543 TimeSpan
.FromMinutes (Double
.MaxValue
);
547 [ExpectedException (typeof (ArgumentException
))]
548 public void FromMinutes_NaN ()
550 TimeSpan
.FromMinutes (Double
.NaN
);
554 [ExpectedException (typeof (OverflowException
))]
555 public void FromMinutes_PositiveInfinity ()
557 // LAMESPEC: Document to return TimeSpan.MaxValue
558 Assert
.AreEqual (TimeSpan
.MaxValue
, TimeSpan
.FromMinutes (Double
.PositiveInfinity
));
562 [ExpectedException (typeof (OverflowException
))]
563 public void FromMinutes_NegativeInfinity ()
565 // LAMESPEC: Document to return TimeSpan.MinValue
566 Assert
.AreEqual (TimeSpan
.MinValue
, TimeSpan
.FromMinutes (Double
.NegativeInfinity
));
570 [ExpectedException (typeof (OverflowException
))]
571 public void FromSeconds_MinValue ()
573 TimeSpan
.FromSeconds (Double
.MinValue
);
577 [ExpectedException (typeof (OverflowException
))]
578 public void FromSeconds_MaxValue ()
580 TimeSpan
.FromSeconds (Double
.MaxValue
);
584 [ExpectedException (typeof (ArgumentException
))]
585 public void FromSeconds_NaN ()
587 TimeSpan
.FromSeconds (Double
.NaN
);
591 [ExpectedException (typeof (OverflowException
))]
592 public void FromSeconds_PositiveInfinity ()
594 // LAMESPEC: Document to return TimeSpan.MaxValue
595 Assert
.AreEqual (TimeSpan
.MaxValue
, TimeSpan
.FromSeconds (Double
.PositiveInfinity
));
599 [ExpectedException (typeof (OverflowException
))]
600 public void FromSeconds_NegativeInfinity ()
602 // LAMESPEC: Document to return TimeSpan.MinValue
603 Assert
.AreEqual (TimeSpan
.MinValue
, TimeSpan
.FromSeconds (Double
.NegativeInfinity
));
607 public void TestGetHashCode ()
609 Assert
.AreEqual (77, new TimeSpan (77).GetHashCode (), "A1");
612 private void ParseHelper (string s
, bool expectFormat
, bool expectOverflow
, string expect
)
614 bool formatException
= false;
615 bool overflowException
= false;
616 string result
= "junk ";
619 result
= TimeSpan
.Parse (s
).ToString ();
621 catch (OverflowException
) {
622 overflowException
= true;
624 catch (FormatException
) {
625 formatException
= true;
627 Assert
.AreEqual (expectFormat
, formatException
, "A1 [" + s
+ "]");
628 Assert
.AreEqual (expectOverflow
, overflowException
, "A2 " + s
+ "]");
630 if (!expectOverflow
&& !expectFormat
) {
631 Assert
.AreEqual (expect
, result
, "A3 [" + s
+ "]");
636 public void TestParse ()
638 ParseHelper (" 13:45:15 ",false, false, "13:45:15");
639 ParseHelper (" -1:2:3 ", false, false, "-01:02:03");
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
;
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");
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
682 public void Parse_Days_WithoutColon ()
684 TimeSpan ts
= TimeSpan
.Parse ("1");
685 Assert
.AreEqual (1, ts
.Days
, "Days");
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
);
698 Assert
.AreEqual ("1.01:01:01.0010000", t3
.ToString (), "A1");
699 Assert
.AreEqual ("1.01:01:01.0010000", t4
.ToString (), "A2");
701 t5
= TimeSpan
.MinValue
- new TimeSpan (1);
704 catch (OverflowException
) {
707 Assert
.IsTrue (exception
, "A3");
711 public void TestToString ()
713 TimeSpan t1
= new TimeSpan (1,2,3,4,5);
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");
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");
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
736 TimeSpan
.Parse ("0.99.99.0");
738 } catch (FormatException
) {
741 TimeSpan
.Parse ("0.999999999999.99.0");
743 } catch (OverflowException
) {
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");
755 [ExpectedException (typeof (OverflowException
))]
756 public void Parse_OverMaxValue()
758 TimeSpan
.Parse ("10675199.02:48:05.4775808");
762 [ExpectedException (typeof (OverflowException
))]
763 public void Parse_UnderMinValue()
765 TimeSpan
.Parse ("-10675199.02:48:05.4775809");
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
789 public void TryParse ()
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);
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");
829 Thread
.CurrentThread
.CurrentCulture
= prev_culture
;
835 public void TryParseErrors ()
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");
845 public void TryParseOverloads ()
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");
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
);
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
);
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
);
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");
962 public void ParseExactCustomFormats ()
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
);
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
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");
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");
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
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
;
1077 result
= TimeSpan
.ParseExact (input
, formats
, formatProvider
, timeSpanStyles
);
1078 } catch (OverflowException
) {
1079 overflow_exc
= true;
1080 } catch (FormatException
) {
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.
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
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
);
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
)
1167 success
= TimeSpan
.TryParseExact (input
, formats
, formatProvider
, styles
, out result
);
1168 Assert
.AreEqual (!error
, success
);
1170 Assert
.AreEqual (expected
, result
.ToString ());
1174 public void ParseExactExceptions ()
1177 TimeSpan
.ParseExact (null, "g", null);
1178 Assert
.Fail ("#A1");
1179 } catch (ArgumentNullException
) {
1183 TimeSpan
.ParseExact ("10:12", (string)null, null);
1184 Assert
.Fail ("#A2");
1185 } catch (ArgumentNullException
) {
1189 TimeSpan
.ParseExact ("10:12", (string [])null, null);
1190 Assert
.Fail ("#A3");
1191 } catch (ArgumentNullException
) {
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");
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");
1282 public void ToStringOverloadsErrors ()
1284 TimeSpan ts
= new TimeSpan (10, 10, 10);
1288 result
= ts
.ToString ("non-valid");
1290 } catch (FormatException
) {
1294 result
= ts
.ToString ("C");
1296 } catch (FormatException
) {
1303 } catch (FormatException
) {
1308 ts
.ToString ("d"); // Missing % for single char
1310 } catch (FormatException
)
1316 ts
.ToString ("ddddddddd");
1318 } catch (FormatException
)
1324 ts
.ToString ("hhh");
1326 } catch (FormatException
)
1332 ts
.ToString ("ffffffff");
1334 } catch (FormatException
)