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)
10 //
11 
12 using NUnit.Framework;
13 using System;
14 using System.Globalization;
15 using System.Threading;
16 
17 namespace MonoTests.System
18 {
19 
20 [TestFixture]
21 public class TimeSpanTest {
22 
Debug(TimeSpan ts)23 	private void Debug (TimeSpan ts)
24 	{
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);
31 	}
32 
33 	[Test]
TestCtors()34 	public void TestCtors ()
35 	{
36 		TimeSpan t1 = new TimeSpan (1234567890);
37 
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");
49     }
50 
51 	[Test]
52 	[ExpectedException (typeof (ArgumentOutOfRangeException))]
DaysOverflow()53 	public void DaysOverflow ()
54 	{
55 		int days = (int) (Int64.MaxValue / TimeSpan.TicksPerDay) + 1;
56 		TimeSpan ts = new TimeSpan (days, 0, 0, 0, 0);
57 	}
58 
59 	[Test]
60 	[ExpectedException (typeof (ArgumentOutOfRangeException))]
TemporaryOverflow()61 	public void TemporaryOverflow ()
62 	{
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");
73 	}
74 
75 	[Test]
76 	[ExpectedException (typeof (ArgumentOutOfRangeException))]
NoOverflowInHoursMinsSecondsMS()77 	public void NoOverflowInHoursMinsSecondsMS ()
78 	{
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");
86 	}
87 
88 	[Test]
89 	[ExpectedException (typeof (ArgumentOutOfRangeException))]
MaxDays()90 	public void MaxDays ()
91 	{
92 		new TimeSpan (Int32.MaxValue, 0, 0, 0, 0);
93 	}
94 
95 	[Test]
96 	[ExpectedException (typeof (ArgumentOutOfRangeException))]
MinDays()97 	public void MinDays ()
98 	{
99 		new TimeSpan (Int32.MinValue, 0, 0, 0, 0);
100 	}
101 
102 	[Test]
103 	[ExpectedException (typeof (ArgumentOutOfRangeException))]
MaxHours()104 	public void MaxHours ()
105 	{
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");
114 
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");
122 	}
123 
124 	[Test]
125 	[ExpectedException (typeof (ArgumentOutOfRangeException))]
MaxHours_BreakPoint()126 	public void MaxHours_BreakPoint ()
127 	{
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");
135 	}
136 
137 	[Test]
MinHours()138 	public void MinHours ()
139 	{
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");
147 	}
148 
149 	[Test]
150 	[ExpectedException (typeof (ArgumentOutOfRangeException))]
MinHours_BreakPoint()151 	public void MinHours_BreakPoint ()
152 	{
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");
160 	}
161 
162 	[Test]
MaxMinutes()163 	public void MaxMinutes ()
164 	{
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");
173 	}
174 
175 	[Test]
176 	[ExpectedException (typeof (ArgumentOutOfRangeException))]
MaxMinutes_BreakPoint()177 	public void MaxMinutes_BreakPoint ()
178 	{
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");
186 	}
187 
188 	[Test]
MinMinutes()189 	public void MinMinutes ()
190 	{
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");
199 	}
200 
201 	[Test]
MinMinutes_BreakPoint()202 	public void MinMinutes_BreakPoint ()
203 	{
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");
211 	}
212 
213 	[Test]
MaxSeconds()214 	public void MaxSeconds ()
215 	{
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");
223 	}
224 
225 	[Test]
MinSeconds()226 	public void MinSeconds ()
227 	{
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");
235 	}
236 
237 	[Test]
MaxMilliseconds()238 	public void MaxMilliseconds ()
239 	{
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");
247 	}
248 
249 	[Test]
MinMilliseconds()250 	public void MinMilliseconds ()
251 	{
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");
259 	}
260 
261 	[Test]
NegativeTimeSpan()262 	public void NegativeTimeSpan ()
263 	{
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");
271 	}
272 
273 	[Test]
TestProperties()274 	public void TestProperties ()
275 	{
276 		TimeSpan t1 = new TimeSpan (1,2,3,4,5);
277 		TimeSpan t2 = -t1;
278 
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");
289 	}
290 
291 	[Test]
TestAdd()292 	public void TestAdd ()
293 	{
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;
300 
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");
307 		try
308 		{
309 			t5 = TimeSpan.MaxValue + new TimeSpan (1);
310 			exception = false;
311 		}
312 		catch (OverflowException)
313 		{
314 			exception = true;
315 		}
316 		Assert.IsTrue (exception, "A7");
317 	}
318 
319 	[Test]
TestCompare()320 	public void TestCompare ()
321 	{
322 		TimeSpan t1 = new TimeSpan (-1);
323 		TimeSpan t2 = new TimeSpan (1);
324 		int res;
325 		bool exception;
326 
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");
335 
336 		Assert.AreEqual (1, TimeSpan.Zero.CompareTo (null), "A9");
337 
338 		try
339 		{
340 			res = TimeSpan.Zero.CompareTo("");
341 			exception = false;
342 		}
343 		catch (ArgumentException)
344 		{
345 			exception = true;
346 		}
347 		Assert.IsTrue (exception, "A10");
348 
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");
355 	}
356 
357 	[Test]
358 	[ExpectedException (typeof (OverflowException))]
NoNegateMinValue()359 	public void NoNegateMinValue() {
360 		TimeSpan t1 = TimeSpan.MinValue.Negate ();
361 	}
362 
363 	[Test]
TestNegateAndDuration()364 	public void TestNegateAndDuration ()
365 	{
366 		TimeSpan t1;
367 		bool exception;
368 
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");
371 
372 		try
373 		{
374 			t1 = TimeSpan.MinValue.Duration ();
375 			exception = false;
376 		}
377 		catch (OverflowException) {
378 			exception = true;
379 		}
380 		Assert.IsTrue (exception, "A4");
381 
382 		Assert.AreEqual ("-00:00:00.0000077", (-(new TimeSpan (77))).ToString (), "A5");
383 		Assert.AreEqual ("00:00:00.0000077", (+(new TimeSpan(77))).ToString(), "A6");
384 	}
385 
386 	[Test]
TestEquals()387 	public void TestEquals ()
388 	{
389 		TimeSpan t1 = new TimeSpan (1);
390 		TimeSpan t2 = new TimeSpan (2);
391 		string s = "justastring";
392 
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");
403 	}
404 
405 	[Test]
TestFromXXXX()406 	public void TestFromXXXX ()
407 	{
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");
419 	}
420 
421 	[Test]
422 	[ExpectedException (typeof (OverflowException))]
FromDays_MinValue()423 	public void FromDays_MinValue ()
424 	{
425 		TimeSpan.FromDays (Double.MinValue);
426 	}
427 
428 	[Test]
429 	[ExpectedException (typeof (OverflowException))]
FromDays_MaxValue()430 	public void FromDays_MaxValue ()
431 	{
432 		TimeSpan.FromDays (Double.MaxValue);
433 	}
434 
435 	[Test]
436 	[ExpectedException (typeof (ArgumentException))]
FromDays_NaN()437 	public void FromDays_NaN ()
438 	{
439 		TimeSpan.FromDays (Double.NaN);
440 	}
441 
442 	[Test]
443 	[ExpectedException (typeof (OverflowException))]
FromDays_PositiveInfinity()444 	public void FromDays_PositiveInfinity ()
445 	{
446 		// LAMESPEC: Document to return TimeSpan.MaxValue
447 		Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.FromDays (Double.PositiveInfinity));
448 	}
449 
450 	[Test]
451 	[ExpectedException (typeof (OverflowException))]
FromDays_NegativeInfinity()452 	public void FromDays_NegativeInfinity ()
453 	{
454 		// LAMESPEC: Document to return TimeSpan.MinValue
455 		Assert.AreEqual (TimeSpan.MinValue, TimeSpan.FromDays (Double.NegativeInfinity));
456 	}
457 
458 	[Test]
459 	[ExpectedException (typeof (OverflowException))]
FromHours_MinValue()460 	public void FromHours_MinValue ()
461 	{
462 		TimeSpan.FromHours (Double.MinValue);
463 	}
464 
465 	[Test]
466 	[ExpectedException (typeof (OverflowException))]
FromHours_MaxValue()467 	public void FromHours_MaxValue ()
468 	{
469 		TimeSpan.FromHours (Double.MaxValue);
470 	}
471 
472 	[Test]
473 	[ExpectedException (typeof (ArgumentException))]
FromHours_NaN()474 	public void FromHours_NaN ()
475 	{
476 		TimeSpan.FromHours (Double.NaN);
477 	}
478 
479 	[Test]
480 	[ExpectedException (typeof (OverflowException))]
FromHours_PositiveInfinity()481 	public void FromHours_PositiveInfinity ()
482 	{
483 		// LAMESPEC: Document to return TimeSpan.MaxValue
484 		Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.FromHours (Double.PositiveInfinity));
485 	}
486 
487 	[Test]
488 	[ExpectedException (typeof (OverflowException))]
FromHours_NegativeInfinity()489 	public void FromHours_NegativeInfinity ()
490 	{
491 		// LAMESPEC: Document to return TimeSpan.MinValue
492 		Assert.AreEqual (TimeSpan.MinValue, TimeSpan.FromHours (Double.NegativeInfinity));
493 	}
494 
495 	[Test]
496 	[ExpectedException (typeof (OverflowException))]
FromMilliseconds_MinValue()497 	public void FromMilliseconds_MinValue ()
498 	{
499 		TimeSpan.FromMilliseconds (Double.MinValue);
500 	}
501 
502 	[Test]
503 	[ExpectedException (typeof (OverflowException))]
FromMilliseconds_MaxValue()504 	public void FromMilliseconds_MaxValue ()
505 	{
506 		TimeSpan.FromMilliseconds (Double.MaxValue);
507 	}
508 
509 	[Test]
510 	[ExpectedException (typeof (ArgumentException))]
FromMilliseconds_NaN()511 	public void FromMilliseconds_NaN ()
512 	{
513 		TimeSpan.FromMilliseconds (Double.NaN);
514 	}
515 
516 	[Test]
517 	[ExpectedException (typeof (OverflowException))]
FromMilliseconds_PositiveInfinity()518 	public void FromMilliseconds_PositiveInfinity ()
519 	{
520 		// LAMESPEC: Document to return TimeSpan.MaxValue
521 		Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.FromMilliseconds (Double.PositiveInfinity));
522 	}
523 
524 	[Test]
525 	[ExpectedException (typeof (OverflowException))]
FromMilliseconds_NegativeInfinity()526 	public void FromMilliseconds_NegativeInfinity ()
527 	{
528 		// LAMESPEC: Document to return TimeSpan.MinValue
529 		Assert.AreEqual (TimeSpan.MinValue, TimeSpan.FromMilliseconds (Double.NegativeInfinity));
530 	}
531 
532 	[Test]
533 	[ExpectedException (typeof (OverflowException))]
FromMinutes_MinValue()534 	public void FromMinutes_MinValue ()
535 	{
536 		TimeSpan.FromMinutes (Double.MinValue);
537 	}
538 
539 	[Test]
540 	[ExpectedException (typeof (OverflowException))]
FromMinutes_MaxValue()541 	public void FromMinutes_MaxValue ()
542 	{
543 		TimeSpan.FromMinutes (Double.MaxValue);
544 	}
545 
546 	[Test]
547 	[ExpectedException (typeof (ArgumentException))]
FromMinutes_NaN()548 	public void FromMinutes_NaN ()
549 	{
550 		TimeSpan.FromMinutes (Double.NaN);
551 	}
552 
553 	[Test]
554 	[ExpectedException (typeof (OverflowException))]
FromMinutes_PositiveInfinity()555 	public void FromMinutes_PositiveInfinity ()
556 	{
557 		// LAMESPEC: Document to return TimeSpan.MaxValue
558 		Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.FromMinutes (Double.PositiveInfinity));
559 	}
560 
561 	[Test]
562 	[ExpectedException (typeof (OverflowException))]
FromMinutes_NegativeInfinity()563 	public void FromMinutes_NegativeInfinity ()
564 	{
565 		// LAMESPEC: Document to return TimeSpan.MinValue
566 		Assert.AreEqual (TimeSpan.MinValue, TimeSpan.FromMinutes (Double.NegativeInfinity));
567 	}
568 
569 	[Test]
570 	[ExpectedException (typeof (OverflowException))]
FromSeconds_MinValue()571 	public void FromSeconds_MinValue ()
572 	{
573 		TimeSpan.FromSeconds (Double.MinValue);
574 	}
575 
576 	[Test]
577 	[ExpectedException (typeof (OverflowException))]
FromSeconds_MaxValue()578 	public void FromSeconds_MaxValue ()
579 	{
580 		TimeSpan.FromSeconds (Double.MaxValue);
581 	}
582 
583 	[Test]
584 	[ExpectedException (typeof (ArgumentException))]
FromSeconds_NaN()585 	public void FromSeconds_NaN ()
586 	{
587 		TimeSpan.FromSeconds (Double.NaN);
588 	}
589 
590 	[Test]
591 	[ExpectedException (typeof (OverflowException))]
FromSeconds_PositiveInfinity()592 	public void FromSeconds_PositiveInfinity ()
593 	{
594 		// LAMESPEC: Document to return TimeSpan.MaxValue
595 		Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.FromSeconds (Double.PositiveInfinity));
596 	}
597 
598 	[Test]
599 	[ExpectedException (typeof (OverflowException))]
FromSeconds_NegativeInfinity()600 	public void FromSeconds_NegativeInfinity ()
601 	{
602 		// LAMESPEC: Document to return TimeSpan.MinValue
603 		Assert.AreEqual (TimeSpan.MinValue, TimeSpan.FromSeconds (Double.NegativeInfinity));
604 	}
605 
606 	[Test]
TestGetHashCode()607 	public void TestGetHashCode ()
608 	{
609 		Assert.AreEqual (77, new TimeSpan (77).GetHashCode (), "A1");
610 	}
611 
ParseHelper(string s, bool expectFormat, bool expectOverflow, string expect)612 	private void ParseHelper (string s, bool expectFormat, bool expectOverflow, string expect)
613 	{
614 		bool formatException = false;
615 		bool overflowException = false;
616 		string result = "junk ";
617 
618 		try {
619 			result =  TimeSpan.Parse (s).ToString ();
620 		}
621 		catch (OverflowException) {
622 			overflowException = true;
623 		}
624 		catch (FormatException) {
625 			formatException = true;
626 		}
627 		Assert.AreEqual (expectFormat, formatException, "A1 [" + s + "]");
628 		Assert.AreEqual (expectOverflow, overflowException, "A2 " + s + "]");
629 
630 		if (!expectOverflow && !expectFormat) {
631 			Assert.AreEqual (expect, result, "A3 [" + s + "]");
632 		}
633 	}
634 
635 	[Test]
TestParse()636 	public void TestParse ()
637 	{
638 		ParseHelper (" 13:45:15 ",false, false, "13:45:15");
639 		ParseHelper (" -1:2:3 ", false, false, "-01:02:03");
640 
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");
645 
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");
649 
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");
653 
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");
656 
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
659 
660 		// Force the use of french culture -which is using a non common NumberDecimalSeparator-
661 		// as current culture, to show that the Parse method is *actually* being culture sensitive
662 		// *and* also keeping the compatibility with '.'
663 		CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
664 		CultureInfo prev_culture = CultureInfo.CurrentCulture;
665 		try {
666 			Thread.CurrentThread.CurrentCulture = french_culture;
667 			ParseHelper ("10:10:10,006", false, false, "10:10:10.0060000");
668 			ParseHelper ("10:10:10.006", false, false, "10:10:10.0060000");
669 		} finally {
670 			// restore culture
671 			Thread.CurrentThread.CurrentCulture = prev_culture;
672 		}
673 
674 		ParseHelper ("00:00:00", false, false, "00:00:00");
675 		ParseHelper ("00:10:00", false, false, "00:10:00");
676 	}
677 
678 	// LAMESPEC: timespan in documentation is wrong - hh:mm:ss isn't mandatory
679 	[Test]
Parse_Days_WithoutColon()680 	public void Parse_Days_WithoutColon ()
681 	{
682 		TimeSpan ts = TimeSpan.Parse ("1");
683 		Assert.AreEqual (1, ts.Days, "Days");
684 	}
685 
686 	[Test]
TestSubstract()687 	public void TestSubstract ()
688 	{
689 		TimeSpan t1 = new TimeSpan (2,3,4,5,6);
690 		TimeSpan t2 = new TimeSpan (1,2,3,4,5);
691 		TimeSpan t3 = t1 - t2;
692 		TimeSpan t4 = t1.Subtract (t2);
693 		TimeSpan t5;
694 		bool exception;
695 
696 		Assert.AreEqual ("1.01:01:01.0010000", t3.ToString (), "A1");
697 		Assert.AreEqual ("1.01:01:01.0010000", t4.ToString (), "A2");
698 		try {
699 			t5 = TimeSpan.MinValue - new TimeSpan (1);
700 			exception = false;
701 		}
702 		catch (OverflowException) {
703 			exception = true;
704 		}
705 		Assert.IsTrue (exception, "A3");
706 	}
707 
708 	[Test]
TestToString()709 	public void TestToString ()
710 	{
711 		TimeSpan t1 = new TimeSpan (1,2,3,4,5);
712 		TimeSpan t2 = -t1;
713 
714 		Assert.AreEqual ("1.02:03:04.0050000", t1.ToString (), "A1");
715 		Assert.AreEqual ("-1.02:03:04.0050000", t2.ToString (), "A2");
716 		Assert.AreEqual ("10675199.02:48:05.4775807", TimeSpan.MaxValue.ToString (), "A3");
717 		Assert.AreEqual ("-10675199.02:48:05.4775808", TimeSpan.MinValue.ToString (), "A4");
718 	}
719 
720 	[Test]
ToString_Constants()721 	public void ToString_Constants ()
722 	{
723 		Assert.AreEqual ("00:00:00", TimeSpan.Zero.ToString (), "Zero");
724 		Assert.AreEqual ("10675199.02:48:05.4775807", TimeSpan.MaxValue.ToString (), "MaxValue");
725 		Assert.AreEqual ("-10675199.02:48:05.4775808", TimeSpan.MinValue.ToString (), "MinValue");
726 	}
727 
728 	[Test]
Parse_InvalidValuesAndFormat_ExceptionOrder()729 	public void Parse_InvalidValuesAndFormat_ExceptionOrder ()
730 	{
731 		// hours should be between 0 and 23 but format is also invalid (too many dots)
732 		// In 2.0 overflow as precedence over format, but not in 4.0
733 		try {
734 			TimeSpan.Parse ("0.99.99.0");
735 			Assert.Fail ("#A1");
736 		} catch (FormatException) {
737 		}
738 		try {
739 			TimeSpan.Parse ("0.999999999999.99.0");
740 			Assert.Fail ("#A2");
741 		} catch (OverflowException) {
742 		}
743 	}
744 
745 	[Test]
Parse_MinMaxValues()746 	public void Parse_MinMaxValues ()
747 	{
748 		Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.Parse ("10675199.02:48:05.4775807"), "MaxValue");
749 		Assert.AreEqual (TimeSpan.MinValue, TimeSpan.Parse ("-10675199.02:48:05.4775808"), "MinValue");
750 	}
751 
752 	[Test]
753 	[ExpectedException (typeof (OverflowException))]
Parse_OverMaxValue()754 	public void Parse_OverMaxValue()
755 	{
756 		TimeSpan.Parse ("10675199.02:48:05.4775808");
757 	}
758 
759 	[Test]
760 	[ExpectedException (typeof (OverflowException))]
Parse_UnderMinValue()761 	public void Parse_UnderMinValue()
762 	{
763 		TimeSpan.Parse ("-10675199.02:48:05.4775809");
764 	}
765 
766 	[Test]
ParseMissingSeconds()767 	public void ParseMissingSeconds ()
768 	{
769 		// as seen in ML for http://resources.esri.com/arcgisserver/apis/silverlight/
770 		TimeSpan ts = TimeSpan.Parse ("0:0:.75");
771 
772 		Assert.AreEqual (0, ts.Days, "Days");
773 		Assert.AreEqual (0, ts.Hours, "Hours");
774 		Assert.AreEqual (750, ts.Milliseconds, "Milliseconds");
775 		Assert.AreEqual (0, ts.Minutes, "Minutes");
776 		Assert.AreEqual (0, ts.Seconds, "Seconds");
777 		Assert.AreEqual (7500000, ts.Ticks, "Ticks");
778 		Assert.AreEqual (0.0000086805555555555555, ts.TotalDays, 0.00000000000000001, "TotalDays");
779 		Assert.AreEqual (0.00020833333333333332, ts.TotalHours, 0.00000000000000001, "TotalHours");
780 		Assert.AreEqual (750.0, ts.TotalMilliseconds, "TotalMilliseconds");
781 		Assert.AreEqual (0.0125, ts.TotalMinutes, "TotalMinutes");
782 		Assert.AreEqual (0.75, ts.TotalSeconds, "TotalSeconds");
783 	}
784 
785 	// 'Ported' the Parse test to use TryParse
786 	[Test]
TryParse()787 	public void TryParse ()
788 	{
789 		TimeSpan result;
790 
791 		Assert.AreEqual (true, TimeSpan.TryParse (" 13:45:15 ", out result), "#A1");
792 		Assert.AreEqual ("13:45:15", result.ToString (), "#A2");
793 
794 		Assert.AreEqual (true, TimeSpan.TryParse (" -1:2:3 ", out result), "#B1");
795 		Assert.AreEqual ("-01:02:03", result.ToString (), "#B2");
796 
797 		Assert.AreEqual (false, TimeSpan.TryParse ("aaa", out result), "#C2");
798 
799 		Assert.AreEqual (true, TimeSpan.TryParse ("-21.23:59:59.9999999", out result), "#D1");
800 		Assert.AreEqual ("-21.23:59:59.9999999", result.ToString (), "#D2");
801 
802 		Assert.AreEqual (false, TimeSpan.TryParse ("100000000000000.1:1:1", out result), "#E1");
803 		Assert.AreEqual (false, TimeSpan.TryParse ("24:60:60", out result), "#E2");
804 
805 		Assert.AreEqual (true, TimeSpan.TryParse ("0001:0002:0003.12     ", out result), "#F1");
806 
807 		Assert.AreEqual (false, TimeSpan.TryParse (" 1:2:3:12345678 ", out result), "#G1");
808 
809 		// Min and Max values
810 		Assert.AreEqual (true, TimeSpan.TryParse ("10675199.02:48:05.4775807", out result), "MaxValue#1");
811 		Assert.AreEqual (TimeSpan.MaxValue, result, "MaxValue#2");
812 		Assert.AreEqual (true, TimeSpan.TryParse ("-10675199.02:48:05.4775808", out result), "MinValue#1");
813 		Assert.AreEqual (TimeSpan.MinValue, result, "MinValue#2");
814 
815 		// Force the use of french culture -which is using a non common NumberDecimalSeparator-
816 		// as current culture, to show that the Parse method is *actually* being culture sensitive
817 		CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
818 		CultureInfo prev_culture = CultureInfo.CurrentCulture;
819 		result = new TimeSpan (0, 10, 10, 10, 6);
820 		try {
821 			Thread.CurrentThread.CurrentCulture = french_culture;
822 			Assert.AreEqual (true, TimeSpan.TryParse ("10:10:10,006", out result), "#CultureSensitive1");
823 			Assert.AreEqual ("10:10:10.0060000", result.ToString (), "#CultureSensitive2");
824 		} finally {
825 			// restore culture
826 			Thread.CurrentThread.CurrentCulture = prev_culture;
827 		}
828 	}
829 
830 	[Test]
TryParseErrors()831 	public void TryParseErrors ()
832 	{
833 		TimeSpan result;
834 
835 		Assert.AreEqual (false, TimeSpan.TryParse ("0.99.99.0", out result), "Format#1");
836 		Assert.AreEqual (false, TimeSpan.TryParse ("10675199.02:48:05.4775808", out result), "OverMaxValue");
837 		Assert.AreEqual (false, TimeSpan.TryParse ("-10675199.02:48:05.4775809", out result), "UnderMinValue");
838 	}
839 
840 	[Test]
TryParseOverloads()841 	public void TryParseOverloads ()
842 	{
843 		TimeSpan result;
844 
845 		// We use fr-FR culture since its NumericDecimalSeparator is not the same used by
846 		// most cultures - including the invariant one.
847 		CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
848 		Assert.AreEqual (true, TimeSpan.TryParse ("11:50:50,006", french_culture, out result), "#A1");
849 
850 		// LAMESPEC - msdn states that an instance of DateTimeFormatInfo is retrieved to
851 		// obtain culture sensitive information, but at least in the betas that's false
852 		DateTimeFormatInfo format_info = new DateTimeFormatInfo ();
853 		format_info.TimeSeparator = ";";
854 		Assert.AreEqual (false, TimeSpan.TryParse ("11;50;50", format_info, out result), "#B1");
855 		Assert.AreEqual (true, TimeSpan.TryParse ("11:50:50", format_info, out result), "#B2");
856 	}
857 
858 	[Test]
ParseExact()859 	public void ParseExact ()
860 	{
861 		CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
862 		CultureInfo us_culture = CultureInfo.GetCultureInfo ("en-US");
863 
864 		// At this point we are only missing the style bites and then we are
865 		// pretty much done with the standard formats.
866 
867 		//
868 		// 'g' format - this is the short and culture sensitive format
869 		//
870 		string [] g_format = new string [] { "g" };
871 		ParseExactHelper ("12", g_format, false, false, "12.00:00:00");
872 		ParseExactHelper ("11:12", g_format, false, false, "11:12:00");
873 		ParseExactHelper ("-11:12", g_format, false, false, "-11:12:00");
874 		ParseExactHelper ("25:13", g_format, true, false, "dontcare");
875 		ParseExactHelper ("11:66", g_format, true, false, "dontcare"); // I'd have expected OverflowExc here
876 		ParseExactHelper ("11:12:13", g_format, false, false, "11:12:13");
877 		ParseExactHelper ("-11:12:13", g_format, false, false, "-11:12:13");
878 		ParseExactHelper ("10.11:12:13", g_format, true, false, "dontcare"); // this should work as well
879 		ParseExactHelper ("10.11:12:13", g_format, true, false, "dontcare", us_culture);
880 		ParseExactHelper ("10.11:12:13", g_format, true, false, "dontcare", CultureInfo.InvariantCulture);
881 		ParseExactHelper ("10:11:12:66", g_format, true, false, "dontcare");
882 		ParseExactHelper ("10:11:12:13", g_format, false, false, "10.11:12:13");
883 		ParseExactHelper ("11:12:13.6", g_format, false, false, "11:12:13.6000000", CultureInfo.InvariantCulture);
884 		ParseExactHelper ("11:12:13,6", g_format, false, false, "11:12:13.6000000", french_culture);
885 		ParseExactHelper ("10:11:12:13.6", g_format, false, false, "10.11:12:13.6000000", us_culture);
886 		ParseExactHelper (" 10:11:12:13.6 ", g_format, false, false, "10.11:12:13.6000000", us_culture);
887 		ParseExactHelper ("10:11", g_format, false, false, "10:11:00", null, TimeSpanStyles.None);
888 		ParseExactHelper ("10:11", g_format, false, false, "10:11:00", null, TimeSpanStyles.AssumeNegative); // no effect
889 
890 		//
891 		// G format
892 		//
893 		string [] G_format = new string [] { "G" };
894 		ParseExactHelper ("9:10:12", G_format, true, false, "dontcare");
895 		ParseExactHelper ("9:10:12.6", G_format, true, false, "dontcare");
896 		ParseExactHelper ("3.9:10:12", G_format, true, false, "dontcare");
897 		ParseExactHelper ("3.9:10:12.153", G_format, true, false, "dontcare"); // this should be valid...
898 		ParseExactHelper ("3:9:10:12.153", G_format, false, false, "3.09:10:12.1530000", us_culture);
899 		ParseExactHelper ("0:9:10:12.153", G_format, false, false, "09:10:12.1530000", us_culture);
900 		ParseExactHelper ("03:09:10:12.153", G_format, false, false, "3.09:10:12.1530000", us_culture);
901 		ParseExactHelper ("003:009:0010:0012.00153", G_format, false, false, "3.09:10:12.0015300", us_culture);
902 		ParseExactHelper ("3:9:10:66.153", G_format, true, false, "dontcare"); // seconds out of range
903 		ParseExactHelper ("3:9:10:12.153", G_format, true, false, "dontcare", french_culture); // fr-FR uses ',' as decimal separator
904 		ParseExactHelper ("3:9:10:12,153", G_format, false, false, "3.09:10:12.1530000", french_culture);
905 		ParseExactHelper ("  3:9:10:12.153  ", G_format, false, false, "3.09:10:12.1530000", us_culture);
906 		ParseExactHelper ("3:9:10:13.153", G_format, false, false, "3.09:10:13.1530000", us_culture, TimeSpanStyles.AssumeNegative);
907 
908 		// c format
909 		string [] c_format = new string [] { "c" };
910 		ParseExactHelper ("12", c_format, false, false, "12.00:00:00");
911 		ParseExactHelper ("12:11", c_format, false, false, "12:11:00");
912 		ParseExactHelper ("12:66", c_format, true, false, "dontcare");
913 		ParseExactHelper ("10.11:12", c_format, false, false, "10.11:12:00");
914 		ParseExactHelper ("10.11:12:13", c_format, false, false, "10.11:12:13");
915 		ParseExactHelper ("10:11:12:13", c_format, true, false, "dontcare"); // this is normally accepted in the Parse method
916 		ParseExactHelper ("10.11:12:13.6", c_format, false, false, "10.11:12:13.6000000");
917 		ParseExactHelper ("10:11:12,6", c_format, true, false, "dontcare");
918 		ParseExactHelper ("10:11:12,6", c_format, true, false, "dontcare", french_culture);
919 		ParseExactHelper ("  10:11:12.6  ", c_format, false, false, "10:11:12.6000000");
920 		ParseExactHelper ("10:12", c_format, false, false, "10:12:00", null, TimeSpanStyles.AssumeNegative);
921 		ParseExactHelper ("10:123456789999", c_format, true, false, "dontcare");
922 
923 		ParseExactHelper ("10:12", new string [0], true, false, "dontcare");
924 		ParseExactHelper ("10:12", new string [] { String.Empty }, true, false, "dontcare");
925 		ParseExactHelper ("10:12", new string [] { null }, true, false, "dontcare");
926 	}
927 
928 	[Test]
ParseExactMultipleFormats()929 	public void ParseExactMultipleFormats ()
930 	{
931 		ParseExactHelper ("10:12", new string [] { "G", "g" }, false, false, "10:12:00");
932 		ParseExactHelper ("10:12", new string [] { "g", "G" }, false, false, "10:12:00");
933 		ParseExactHelper ("7.8:9:10", new string [] { "G", "g" }, true, false, "dontcare");
934 		ParseExactHelper ("7.8:9:10", new string [] { "G", "g", "c" }, false, false, "7.08:09:10");
935 		ParseExactHelper ("7:8:9:10", new string [] { "c", "g" }, false, false, "7.08:09:10");
936 		ParseExactHelper ("7:8:9:10", new string [] { "c", "G" }, true, false, "dontcare");
937 		ParseExactHelper ("7.123456789:1", new string [] { "c", "G", "g" }, true, false, "dontcare");
938 		ParseExactHelper ("7.123456789:1", new string [] { "G", "g", "c" }, true, false, "dontcare");
939 		ParseExactHelper ("1234567890123456", new string [] { "c", "g" }, true, false, "dontcare"); // I'd expect an OverflowException
940 		ParseExactHelper ("10:12", new string [] { null, "c", "g" }, true, false, "10:12:00");
941 		ParseExactHelper ("10:12", new string [] { String.Empty, "c", "g" }, true, false, "10:12:00");
942 	}
943 
944 	[Test]
ParseExactCustomFormats()945 	public void ParseExactCustomFormats ()
946 	{
947 		// Days
948 		ParseExactHelper ("33", new string [] { "%d" }, false, false, "33.00:00:00");
949 		ParseExactHelper ("00", new string [] { "%d" }, false, false, "00:00:00");
950 		ParseExactHelper ("33", new string [] { "%dd" }, false, false, "33.00:00:00");
951 		ParseExactHelper ("3333", new string [] { "%d" }, false, false, "3333.00:00:00");
952 		ParseExactHelper ("3333", new string [] { "%ddd" }, true, false, "3333.00:00:00"); // 'dd' mismatch the digit count
953 		ParseExactHelper ("3333", new string [] { "%dddd" }, false, false, "3333.00:00:00");
954 		ParseExactHelper ("00033", new string [] { "%ddddd" }, false, false, "33.00:00:00");
955 		ParseExactHelper ("00033", new string [] { "%d" }, false, false, "33.00:00:00");
956 		ParseExactHelper ("00000003", new string [] { "%dddddddd" }, false, false, "3.00:00:00"); // up to 8 'd'
957 		ParseExactHelper ("000000003", new string [] { "%ddddddddd" }, true, false, "dontcare");
958 		ParseExactHelper ("33", new string [] { "d" }, true, false, "33.00:00:00"); // This is sort of weird.
959 		ParseExactHelper ("33", new string [] { "dd" }, false, false, "33.00:00:00");
960 		ParseExactHelper ("-33", new string [] { "%d" }, true, false, "dontcare");
961 		ParseExactHelper ("33", new string [] { "%d" }, false, false, "-33.00:00:00", null, TimeSpanStyles.AssumeNegative);
962 
963 		// Hours
964 		ParseExactHelper ("12", new string [] { "%h" }, false, false, "12:00:00");
965 		ParseExactHelper ("00", new string [] { "%h" }, false, false, "00:00:00");
966 		ParseExactHelper ("012", new string [] { "%h" }, true, false, "dontcare"); // more than 2 digits
967 		ParseExactHelper ("00012", new string [] { "%hhhhh" }, true, false, "dontcare");
968 		ParseExactHelper ("15", new string [] { "%h" }, false, false, "15:00:00");
969 		ParseExactHelper ("24", new string [] { "%h" }, true, false, "dontcare");
970 		ParseExactHelper ("15", new string [] { "%hh" }, false, false, "15:00:00");
971 		ParseExactHelper ("1", new string [] { "%hh" }, true, false, "dontcare"); // 'hh' but a single digit
972 		ParseExactHelper ("01", new string [] { "%hh" }, false, false, "01:00:00");
973 		ParseExactHelper ("015", new string [] { "%hhh" }, true, false, "dontcare"); // Too many 'h'
974 		ParseExactHelper ("12", new string [] { "h" }, true, false, "dontcare");
975 		ParseExactHelper ("12", new string [] { "hh" }, false, false, "12:00:00");
976 		ParseExactHelper ("-15", new string [] {"%h"}, true, false, "dontcare"); // Explicit - not accepted
977 		ParseExactHelper ("15", new string [] { "%h" }, false, false, "-15:00:00", null, TimeSpanStyles.AssumeNegative);
978 		ParseExactHelper ("15", new string [] { "%H" }, true, false, "dontcare"); // Uppercase is not accepted
979 
980 		// Minutes
981 		ParseExactHelper ("12", new string [] { "%m" }, false, false, "00:12:00");
982 		ParseExactHelper ("00", new string [] { "%m" }, false, false, "00:00:00");
983 		ParseExactHelper ("60", new string [] { "%m" }, true, false, "dontcare");
984 		ParseExactHelper ("12", new string [] { "%mm" }, false, false, "00:12:00");
985 		ParseExactHelper ("1", new string [] { "%mm" }, true, false, "dontcare");
986 		ParseExactHelper ("12", new string [] { "%mmm" }, true, false, "dontcare");
987 		ParseExactHelper ("12", new string [] { "m" }, true, false, "dontcare");
988 		ParseExactHelper ("12", new string [] { "mm" }, false, false, "00:12:00");
989 		ParseExactHelper ("-12", new string [] { "%m" }, true, false, "dontcare");
990 		ParseExactHelper ("12", new string [] { "%m" }, false, false, "-00:12:00", null, TimeSpanStyles.AssumeNegative);
991 		ParseExactHelper ("12", new string [] { "%M" }, true, false, "dontcare");
992 
993 		// Seconds
994 		ParseExactHelper ("12", new string [] { "%s" }, false, false, "00:00:12");
995 		ParseExactHelper ("00", new string [] { "%s" }, false, false, "00:00:00");
996 		ParseExactHelper ("000", new string [] { "%s" }, true, false, "dontcare");
997 		ParseExactHelper ("12", new string [] { "%ss" }, false, false, "00:00:12");
998 		ParseExactHelper ("12", new string [] { "%sss" }, true, false, "dontcare");
999 		ParseExactHelper ("60", new string [] { "%s" }, true, false, "dontcare");
1000 		ParseExactHelper ("-12", new string [] { "%s" }, true, false, "dontcare");
1001 		ParseExactHelper ("12", new string [] { "%s" }, false, false, "-00:00:12", null, TimeSpanStyles.AssumeNegative);
1002 
1003 		// Fractions of seconds - f
1004 		ParseExactHelper ("3", new string [] { "%f" }, false, false, "00:00:00.3000000");
1005 		ParseExactHelper ("0", new string [] { "%f" }, false, false, "00:00:00");
1006 		ParseExactHelper ("03", new string [] { "%f" }, true, false, "dontcare"); // This would work for other elements
1007 		ParseExactHelper ("10", new string [] { "%f" }, true, false, "dontcare"); // Only a digit is accepted with '%f'
1008 		ParseExactHelper ("3", new string [] { "%ff" }, true, false, "dontcare");
1009 		ParseExactHelper ("12", new string [] { "%ff" }, false, false, "00:00:00.1200000");
1010 		ParseExactHelper ("123", new string [] { "%ff" }, true, false, "dontcare");
1011 		ParseExactHelper ("123", new string [] { "%fff" }, false, false, "00:00:00.1230000");
1012 		ParseExactHelper ("1234", new string [] { "%ffff" }, false, false, "00:00:00.1234000");
1013 		ParseExactHelper ("1234567", new string [] { "%fffffff" }, false, false, "00:00:00.1234567");
1014 		ParseExactHelper ("1234567", new string [] { "%FfFFFFF" }, true, false, "dontcare"); // Mixed f and M
1015 		ParseExactHelper ("12345678", new string [] { "%ffffffff" }, true, false, "dontcare");
1016 		ParseExactHelper ("0000000", new string [] { "%fffffff" }, false, false, "00:00:00");
1017 
1018 		// Fractions of second - F
1019 		ParseExactHelper ("3", new string [] { "%F" }, false, false, "00:00:00.3000000");
1020 		ParseExactHelper ("333", new string [] { "%FFFFF" }, false, false, "00:00:00.3330000");
1021 		ParseExactHelper ("1234567", new string [] { "%FFFFFFF" }, false, false, "00:00:00.1234567");
1022 
1023 		// Multiple symbols
1024 		ParseExactHelper ("9:10", new string [] { @"h\:m" }, false, false, "09:10:00");
1025 		ParseExactHelper ("9;10", new string [] { @"h\;m" }, false, false, "09:10:00");
1026 		ParseExactHelper ("10:9", new string [] { @"m\:h" }, false, false, "09:10:00");
1027 		ParseExactHelper ("10:9", new string [] { @"%m\:%h" }, false, false, "09:10:00");
1028 		ParseExactHelper ("9 10", new string [] { @"h\ m" }, false, false, "09:10:00");
1029 		ParseExactHelper ("9   10", new string [] { @"h\ \ \ m" }, false, false, "09:10:00");
1030 		ParseExactHelper (" 9:10 ", new string [] { @"h\:m" }, true, false, "dontcare");
1031 		ParseExactHelper ("9:10:11", new string [] { @"h\:m\:s" }, false, false, "09:10:11");
1032 		ParseExactHelper ("9:10:11:6", new string [] { @"h\:m\:s\:f" }, false, false, "09:10:11.6000000");
1033 		ParseExactHelper ("9:10:11:666", new string [] { @"h\:m\:s\:f" }, true, false, "dontcare"); // fff with 1 digit
1034 		ParseExactHelper ("9:10:11:", new string [] { @"h\:m\:s\:F" }, false, false, "09:10:11"); // optional frac of seconds
1035 		ParseExactHelper ("9:10:11:", new string [] { @"h\:m\:s\:FF" }, false, false, "09:10:11");
1036 		ParseExactHelper ("9:10:11::", new string [] { @"h\:m\:s\:F\:" }, false, false, "09:10:11");
1037 		ParseExactHelper ("8:9:10:11:6666666", new string [] { @"d\:h\:m\:s\:fffffff" }, false, false, "8.09:10:11.6666666");
1038 		ParseExactHelper ("8:9:10:11:6666666", new string [] { @"d\:h\:m\:s\:fffffff" }, false, false, "-8.09:10:11.6666666",
1039 				null, TimeSpanStyles.AssumeNegative);
1040 		ParseExactHelper ("9:10", new string [] { @"h\:h" }, true, false, "dontcare"); // Repeated element
1041 
1042 		// Misc
1043 		ParseExactHelper (" 0 ", new string [] { "%d" }, true, false, "dontcare");
1044 		ParseExactHelper (" 0 ", new string [] { " %d " }, true, false, "dontcare");
1045 		ParseExactHelper ("0", new string [] { " %d " }, true, false, "dontcare");
1046 		ParseExactHelper ("::", new string [] { @"\:\:" }, false, false, "00:00:00"); // funny
1047 		ParseExactHelper ("::", new string [] { @"\:\:" }, false, false, "00:00:00", null, TimeSpanStyles.AssumeNegative);
1048 		ParseExactHelper (" 0", new string [] { @"\ d" }, false, false, "00:00:00");
1049 		ParseExactHelper ("Interval = 12:13:14", new string [] { @"'Interval = 'h\:m\:s" }, false, false, "12:13:14");
1050 	}
1051 
ParseExactHelper(string input, string [] formats, bool format_error, bool overflow_error, string expected, IFormatProvider formatProvider = null, TimeSpanStyles timeSpanStyles = TimeSpanStyles.None)1052 	void ParseExactHelper (string input, string [] formats, bool format_error, bool overflow_error, string expected,
1053         IFormatProvider formatProvider = null, TimeSpanStyles timeSpanStyles = TimeSpanStyles.None)
1054 	{
1055 		bool overflow_exc = false;
1056 		bool format_exc = false;
1057 		TimeSpan result = TimeSpan.Zero;
1058 
1059 		try {
1060 			result = TimeSpan.ParseExact (input, formats, formatProvider, timeSpanStyles);
1061 		} catch (OverflowException) {
1062 			overflow_exc = true;
1063 		} catch (FormatException) {
1064 			format_exc = true;
1065 		}
1066 
1067 		Assert.AreEqual (format_error, format_exc, "A1");
1068 		Assert.AreEqual (overflow_error, overflow_exc, "A2");
1069 		if (!overflow_exc && !format_exc)
1070 			Assert.AreEqual (expected, result.ToString ());
1071 	}
1072 
1073 	// 'Ported' the ParseExact test to use TryParseExact instead.
1074 	[Test]
TryParseExact()1075 	public void TryParseExact ()
1076 	{
1077 		CultureInfo french_culture = CultureInfo.GetCultureInfo ("fr-FR");
1078 		CultureInfo us_culture = CultureInfo.GetCultureInfo ("en-US");
1079 
1080 		//
1081 		// 'g' format - this is the short and culture sensitive format
1082 		//
1083 		string [] g_format = new string [] { "g" };
1084 		TryParseExactHelper ("12", g_format, false, "12.00:00:00");
1085 		TryParseExactHelper ("11:12", g_format, false, "11:12:00");
1086 		TryParseExactHelper ("-11:12", g_format, false, "-11:12:00");
1087 		TryParseExactHelper ("25:13", g_format, true, "dontcare");
1088 		TryParseExactHelper ("11:66", g_format, true, "dontcare"); // I'd have expected OverflowExc here
1089 		TryParseExactHelper ("11:12:13", g_format, false, "11:12:13");
1090 		TryParseExactHelper ("-11:12:13", g_format, false, "-11:12:13");
1091 		TryParseExactHelper ("10.11:12:13", g_format, true, "dontcare"); // this should work as well
1092 		TryParseExactHelper ("10.11:12:13", g_format, true, "dontcare", us_culture);
1093 		TryParseExactHelper ("10.11:12:13", g_format, true, "dontcare", CultureInfo.InvariantCulture);
1094 		TryParseExactHelper ("10:11:12:66", g_format, true, "dontcare");
1095 		TryParseExactHelper ("10:11:12:13", g_format, false, "10.11:12:13");
1096 		TryParseExactHelper ("11:12:13.6", g_format, false, "11:12:13.6000000", CultureInfo.InvariantCulture);
1097 		TryParseExactHelper ("11:12:13,6", g_format, false, "11:12:13.6000000", french_culture);
1098 		TryParseExactHelper ("10:11:12:13.6", g_format, false, "10.11:12:13.6000000", us_culture);
1099 		TryParseExactHelper (" 10:11:12:13.6 ", g_format, false, "10.11:12:13.6000000", us_culture);
1100 		TryParseExactHelper ("10:11", g_format, false, "10:11:00", null, TimeSpanStyles.None);
1101 		TryParseExactHelper ("10:11", g_format, false, "10:11:00", null, TimeSpanStyles.AssumeNegative); // no effect
1102 
1103 		//
1104 		// G format
1105 		//
1106 		string [] G_format = new string [] { "G" };
1107 		TryParseExactHelper ("9:10:12", G_format, true, "dontcare");
1108 		TryParseExactHelper ("9:10:12.6", G_format, true, "dontcare");
1109 		TryParseExactHelper ("3.9:10:12", G_format, true, "dontcare");
1110 		TryParseExactHelper ("3.9:10:12.153", G_format, true, "dontcare"); // this should be valid...
1111 		TryParseExactHelper ("3:9:10:12.153", G_format, false, "3.09:10:12.1530000", us_culture);
1112 		TryParseExactHelper ("0:9:10:12.153", G_format, false, "09:10:12.1530000", us_culture);
1113 		TryParseExactHelper ("03:09:10:12.153", G_format, false, "3.09:10:12.1530000", us_culture);
1114 		TryParseExactHelper ("003:009:0010:0012.00153", G_format, false, "3.09:10:12.0015300", us_culture);
1115 		TryParseExactHelper ("3:9:10:66.153", G_format, true, "dontcare"); // seconds out of range
1116 		TryParseExactHelper ("3:9:10:12.153", G_format, true, "dontcare", french_culture); // fr-FR uses ',' as decimal separator
1117 		TryParseExactHelper ("3:9:10:12,153", G_format, false, "3.09:10:12.1530000", french_culture);
1118 		TryParseExactHelper ("  3:9:10:12.153  ", G_format, false, "3.09:10:12.1530000", us_culture);
1119 		TryParseExactHelper ("3:9:10:13.153", G_format, false, "3.09:10:13.1530000", us_culture, TimeSpanStyles.AssumeNegative);
1120 
1121 		// c format
1122 		string [] c_format = new string [] { "c" };
1123 		TryParseExactHelper ("12", c_format, false, "12.00:00:00");
1124 		TryParseExactHelper ("12:11", c_format, false, "12:11:00");
1125 		TryParseExactHelper ("12:66", c_format, true, "dontcare");
1126 		TryParseExactHelper ("10.11:12", c_format, false, "10.11:12:00");
1127 		TryParseExactHelper ("10.11:12:13", c_format, false, "10.11:12:13");
1128 		TryParseExactHelper ("10:11:12:13", c_format, true, "dontcare"); // this is normally accepted in the Parse method
1129 		TryParseExactHelper ("10.11:12:13.6", c_format, false, "10.11:12:13.6000000");
1130 		TryParseExactHelper ("10:11:12,6", c_format, true, "dontcare");
1131 		TryParseExactHelper ("10:11:12,6", c_format, true, "dontcare", french_culture);
1132 		TryParseExactHelper ("  10:11:12.6  ", c_format, false, "10:11:12.6000000");
1133 		TryParseExactHelper ("10:12", c_format, false, "10:12:00", null, TimeSpanStyles.AssumeNegative);
1134 		TryParseExactHelper ("10:123456789999", c_format, true, "dontcare");
1135 
1136 		TryParseExactHelper ("10:12", new string [0], true, "dontcare");
1137 		TryParseExactHelper ("10:12", new string [] { String.Empty }, true, "dontcare");
1138 		TryParseExactHelper ("10:12", new string [] { null }, true, "dontcare");
1139 
1140 		TryParseExactHelper (null, new string [] { null }, true, "dontcare");
1141 	}
1142 
TryParseExactHelper(string input, string [] formats, bool error, string expected, IFormatProvider formatProvider = null, TimeSpanStyles styles = TimeSpanStyles.None)1143 	void TryParseExactHelper (string input, string [] formats, bool error, string expected, IFormatProvider formatProvider = null,
1144 			TimeSpanStyles styles = TimeSpanStyles.None)
1145 	{
1146 		TimeSpan result;
1147 		bool success;
1148 
1149 		success = TimeSpan.TryParseExact (input, formats, formatProvider, styles, out result);
1150 		Assert.AreEqual (!error, success);
1151 		if (!error)
1152 			Assert.AreEqual (expected, result.ToString ());
1153 	}
1154 
1155 	[Test]
ParseExactExceptions()1156 	public void ParseExactExceptions ()
1157 	{
1158 		try {
1159 			TimeSpan.ParseExact (null, "g", null);
1160 			Assert.Fail ("#A1");
1161 		} catch (ArgumentNullException) {
1162 		}
1163 
1164 		try {
1165 			TimeSpan.ParseExact ("10:12", (string)null, null);
1166 			Assert.Fail ("#A2");
1167 		} catch (ArgumentNullException) {
1168 		}
1169 
1170 		try {
1171 			TimeSpan.ParseExact ("10:12", (string [])null, null);
1172 			Assert.Fail ("#A3");
1173 		} catch (ArgumentNullException) {
1174 		}
1175 	}
1176 
1177 	[Test]
ToStringOverloads()1178 	public void ToStringOverloads ()
1179 	{
1180 		TimeSpan ts = new TimeSpan (1, 2, 3, 4, 6);
1181 
1182 		// Simple version - culture invariant
1183 		Assert.AreEqual ("1.02:03:04.0060000", ts.ToString (), "#A1");
1184 		Assert.AreEqual ("1.02:03:04.0060000", ts.ToString ("c"), "#A2");
1185 		Assert.AreEqual ("1.02:03:04.0060000", ts.ToString (null), "#A3");
1186 		Assert.AreEqual ("1.02:03:04.0060000", ts.ToString (String.Empty), "#A4");
1187 
1188 		//
1189 		// IFormatProvider ones - use a culture changing numeric format.
1190 		// Also, we use fr-FR as culture, since it uses some elements different to invariant culture
1191 		//
1192 		CultureInfo culture = CultureInfo.GetCultureInfo ("fr-FR");
1193 
1194 		Assert.AreEqual ("1:2:03:04,006", ts.ToString ("g", culture), "#B1");
1195 		Assert.AreEqual ("1:02:03:04,0060000", ts.ToString ("G", culture), "#B2");
1196 		Assert.AreEqual ("1.02:03:04.0060000", ts.ToString ("c", culture), "#B3"); // 'c' format ignores CultureInfo
1197 		Assert.AreEqual ("1.02:03:04.0060000", ts.ToString ("t", culture), "#B4"); // 't' and 'T' are the same as 'c'
1198 		Assert.AreEqual("1.02:03:04.0060000", ts.ToString("T", culture), "#B5");
1199 
1200 		ts = new TimeSpan (4, 5, 6);
1201 		Assert.AreEqual ("4:05:06", ts.ToString ("g", culture), "#C1");
1202 		Assert.AreEqual ("0:04:05:06,0000000", ts.ToString ("G", culture), "#C2");
1203 	}
1204 
1205 	[Test]
ToStringCustomFormats()1206 	public void ToStringCustomFormats ()
1207 	{
1208 		TimeSpan ts = new TimeSpan (1, 3, 5, 7);
1209 
1210 		Assert.AreEqual ("1", ts.ToString ("%d"), "#A0");
1211 		Assert.AreEqual ("3", ts.ToString ("%h"), "#A1");
1212 		Assert.AreEqual ("5", ts.ToString ("%m"), "#A2");
1213 		Assert.AreEqual ("7", ts.ToString ("%s"), "#A3");
1214 		Assert.AreEqual ("0", ts.ToString ("%f"), "#A4");
1215 		Assert.AreEqual (String.Empty, ts.ToString ("%F"), "#A5"); // Nothing to display
1216 
1217 		Assert.AreEqual ("01", ts.ToString ("dd"), "#B0");
1218 		Assert.AreEqual ("00000001", ts.ToString ("dddddddd"), "#B1");
1219 		Assert.AreEqual ("03", ts.ToString ("hh"), "#B2");
1220 		Assert.AreEqual ("05", ts.ToString ("mm"), "#B3");
1221 		Assert.AreEqual ("07", ts.ToString ("ss"), "#B4");
1222 		Assert.AreEqual ("00", ts.ToString ("ff"), "#B5");
1223 		Assert.AreEqual ("0000000", ts.ToString ("fffffff"), "#B6");
1224 		Assert.AreEqual (String.Empty, ts.ToString ("FF"), "#B7");
1225 
1226 		Assert.AreEqual ("01;03;05", ts.ToString (@"dd\;hh\;mm"), "#C0");
1227 		Assert.AreEqual ("05 07", ts.ToString (@"mm\ ss"), "#C1");
1228 		Assert.AreEqual ("05 07 ", ts.ToString (@"mm\ ss\ FF"), "#C2");
1229 		Assert.AreEqual ("Result = 3 hours with 5 minutes and 7 seconds",
1230 				ts.ToString (@"'Result = 'h' hours with 'm' minutes and 's' seconds'"), "#C3");
1231 		Assert.AreEqual ("  ", ts.ToString (@"\ \ "), "#C4");
1232 
1233 		ts = new TimeSpan (1, 3, 5, 7, 153);
1234 		Assert.AreEqual ("1", ts.ToString ("%F"), "#D0");
1235 		Assert.AreEqual ("15", ts.ToString ("FF"), "#D1"); // Don't use %, as the parser gets confused here
1236 		Assert.AreEqual ("153", ts.ToString ("FFFFFFF"), "#D2");
1237 
1238 		// Negative values are shown without sign
1239 		ts = new TimeSpan (-1, -3, -5);
1240 		Assert.AreEqual ("1", ts.ToString ("%h"), "#E0");
1241 		Assert.AreEqual ("3", ts.ToString ("%m"), "#E1");
1242 		Assert.AreEqual ("5", ts.ToString ("%s"), "#E2");
1243 
1244 		ts = new TimeSpan (123456789);
1245 		Assert.AreEqual ("12.3", ts.ToString ("s\\.f"), "#F0");
1246 		Assert.AreEqual ("12.3", ts.ToString ("s\\.F"), "#F1");
1247 		Assert.AreEqual ("12.3456789", ts.ToString ("s\\.fffffff"), "#F2");
1248 		Assert.AreEqual ("12.345678", ts.ToString ("s\\.ffffff"), "#F3");
1249 
1250 		ts = new TimeSpan (1234);
1251 		Assert.AreEqual ("0.000123", ts.ToString ("s\\.ffffff"), "#G0");
1252 		Assert.AreEqual ("0.0001", ts.ToString ("s\\.ffff"), "#G1");
1253 		Assert.AreEqual ("0.", ts.ToString ("s\\.F"), "#G2");
1254 		Assert.AreEqual ("0.", ts.ToString ("s\\.FFF"), "#G3");
1255 
1256 		ts = TimeSpan.FromSeconds (0.05);
1257 		Assert.AreEqual (".0", ts.ToString ("\\.f"), "#H0");
1258 		Assert.AreEqual (".", ts.ToString ("\\.F"), "#H1");
1259 	}
1260 
1261 	[Test]
ToStringOverloadsErrors()1262 	public void ToStringOverloadsErrors ()
1263 	{
1264 		TimeSpan ts = new TimeSpan (10, 10, 10);
1265 		string result;
1266 
1267 		try {
1268 			result = ts.ToString ("non-valid");
1269 			Assert.Fail ("#1");
1270 		} catch (FormatException) {
1271 		}
1272 
1273 		try {
1274 			result = ts.ToString ("C");
1275 			Assert.Fail ("#2");
1276 		} catch (FormatException) {
1277 		}
1278 
1279 		try
1280 		{
1281 			ts.ToString ("m");
1282 			Assert.Fail ("#3");
1283 		} catch (FormatException) {
1284 		}
1285 
1286 		try
1287 		{
1288 			ts.ToString ("d"); // Missing % for single char
1289 			Assert.Fail ("#4");
1290 		} catch (FormatException)
1291 		{
1292 		}
1293 
1294 		try
1295 		{
1296 			ts.ToString ("ddddddddd");
1297 			Assert.Fail ("#5");
1298 		} catch (FormatException)
1299 		{
1300 		}
1301 
1302 		try
1303 		{
1304 			ts.ToString ("hhh");
1305 			Assert.Fail ("#5");
1306 		} catch (FormatException)
1307 		{
1308 		}
1309 
1310 		try
1311 		{
1312 			ts.ToString ("ffffffff");
1313 			Assert.Fail ("6");
1314 		} catch (FormatException)
1315 		{
1316 		}
1317 	}
1318 }
1319 
1320 }
1321