2010-03-12 Jb Evain <jbevain@novell.com>
[mono.git] / mcs / class / corlib / Test / System / TimeSpanTest.cs
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
16 namespace MonoTests.System
17 {
18
19 [TestFixture]
20 public class TimeSpanTest {
21
22         private void Debug (TimeSpan ts) 
23         {
24                 Console.Out.WriteLine ("Days {0}", ts.Days);
25                 Console.Out.WriteLine ("Hours {0}", ts.Hours);
26                 Console.Out.WriteLine ("Minutes {0}", ts.Minutes);
27                 Console.Out.WriteLine ("Seconds {0}", ts.Seconds);
28                 Console.Out.WriteLine ("Milliseconds {0}", ts.Milliseconds);
29                 Console.Out.WriteLine ("Ticks {0}", ts.Ticks);
30         }
31
32         public void TestCtors ()
33         {
34                 TimeSpan t1 = new TimeSpan (1234567890);
35
36                 Assert.AreEqual ("00:02:03.4567890", t1.ToString (), "A1");
37                 t1 = new TimeSpan (1,2,3);
38                 Assert.AreEqual ("01:02:03", t1.ToString (), "A2");
39                 t1 = new TimeSpan (1,2,3,4);
40                 Assert.AreEqual ("1.02:03:04", t1.ToString (), "A3");
41                 t1 = new TimeSpan (1,2,3,4,5);
42                 Assert.AreEqual ("1.02:03:04.0050000", t1.ToString (), "A4");
43                 t1 = new TimeSpan (-1,2,-3,4,-5);
44                 Assert.AreEqual ("-22:02:56.0050000", t1.ToString (), "A5");
45                 t1 = new TimeSpan (0,25,0,0,0);
46                 Assert.AreEqual ("1.01:00:00", t1.ToString (), "A6");
47         }
48
49         [Test]
50         [ExpectedException (typeof (ArgumentOutOfRangeException))]
51         public void DaysOverflow () 
52         {
53                 int days = (int) (Int64.MaxValue / TimeSpan.TicksPerDay) + 1;
54                 TimeSpan ts = new TimeSpan (days, 0, 0, 0, 0);
55         }
56
57         [Test]
58 #if NET_2_0
59         [ExpectedException (typeof (ArgumentOutOfRangeException))]
60         [Category ("NotWorking")]
61 #endif
62         public void TemporaryOverflow () 
63         {
64                 // calculating part of this results in overflow (days)
65                 // but the negative hours, minutes, seconds & ms correct this
66                 int days = (int) (Int64.MaxValue / TimeSpan.TicksPerDay) + 1;
67                 TimeSpan ts = new TimeSpan (days, Int32.MinValue, Int32.MinValue, Int32.MinValue, Int32.MinValue);
68                 Assert.AreEqual (10650320, ts.Days, "Days");
69                 Assert.AreEqual (0, ts.Hours, "Hours");
70                 Assert.AreEqual (14, ts.Minutes, "Minutes");
71                 Assert.AreEqual (28, ts.Seconds, "Seconds");
72                 Assert.AreEqual (352, ts.Milliseconds, "Milliseconds");
73                 Assert.AreEqual (9201876488683520000, ts.Ticks, "Ticks");
74         }
75
76         [Test]
77 #if NET_2_0
78         [ExpectedException (typeof (ArgumentOutOfRangeException))]
79         [Category ("NotWorking")]
80 #endif
81         public void NoOverflowInHoursMinsSecondsMS () 
82         {
83                 TimeSpan ts = new TimeSpan (0, Int32.MaxValue, Int32.MaxValue, Int32.MaxValue, Int32.MaxValue);
84                 Assert.AreEqual (24879, ts.Days, "Days");
85                 Assert.AreEqual (22, ts.Hours, "Hours");
86                 Assert.AreEqual (44, ts.Minutes, "Minutes");
87                 Assert.AreEqual (30, ts.Seconds, "Seconds");
88                 Assert.AreEqual (647, ts.Milliseconds, "Milliseconds");
89                 Assert.AreEqual (21496274706470000, ts.Ticks, "Ticks");
90         }
91
92         [Test]
93         [ExpectedException (typeof (ArgumentOutOfRangeException))]
94         public void MaxDays () 
95         {
96                 new TimeSpan (Int32.MaxValue, 0, 0, 0, 0);
97         }
98
99         [Test]
100         [ExpectedException (typeof (ArgumentOutOfRangeException))]
101         public void MinDays () 
102         {
103                 new TimeSpan (Int32.MinValue, 0, 0, 0, 0);
104         }
105
106         [Test]
107         [Ignore ("too long")]
108         public void MaxHours_TooLong () 
109         {
110                 // LAMESPEC: the highest hours are "special"
111                 for (int i=0; i < 596523; i++) {
112                         TimeSpan ts = new TimeSpan (0, Int32.MaxValue - i, 0, 0, 0);
113                         int h = i + 1;
114                         string prefix = i.ToString () + '-';
115                         Assert.AreEqual (-(h / 24), ts.Days, prefix + "Days");
116                         Assert.AreEqual (-(h % 24), ts.Hours, prefix + "Hours");
117                         Assert.AreEqual (0, ts.Minutes, prefix + "Minutes");
118                         Assert.AreEqual (0, ts.Seconds, prefix + "Seconds");
119                         Assert.AreEqual (0, ts.Milliseconds, prefix + "Milliseconds");
120                         Assert.AreEqual (-36000000000 * h, ts.Ticks, prefix + "Ticks");
121                 }
122         }
123
124         [Test]
125 #if NET_2_0
126         [ExpectedException (typeof (ArgumentOutOfRangeException))]
127         [Category ("NotWorking")]
128 #endif
129         public void MaxHours () 
130         {
131                 // LAMESPEC: the highest hours are "special"
132                 TimeSpan ts = new TimeSpan (0, Int32.MaxValue, 0, 0, 0);
133                 Assert.AreEqual (0, ts.Days, "Max-Days");
134                 Assert.AreEqual (-1, ts.Hours, "Max-Hours");
135                 Assert.AreEqual (0, ts.Minutes, "Max-Minutes");
136                 Assert.AreEqual (0, ts.Seconds, "Max-Seconds");
137                 Assert.AreEqual (0, ts.Milliseconds, "Max-Milliseconds");
138                 Assert.AreEqual (-36000000000, ts.Ticks, "Max-Ticks");
139
140                 ts = new TimeSpan (0, Int32.MaxValue - 596522, 0, 0, 0);
141                 Assert.AreEqual (-24855, ts.Days, "Days");
142                 Assert.AreEqual (-3, 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 (-21474828000000000, ts.Ticks, "Ticks");
147         }
148
149         [Test]
150 #if NET_2_0
151         [ExpectedException (typeof (ArgumentOutOfRangeException))]
152         [Category ("NotWorking")]
153 #endif
154         public void MaxHours_BreakPoint () 
155         {
156                 TimeSpan ts = new TimeSpan (0, Int32.MaxValue - 596523, 0, 0, 0);
157                 Assert.AreEqual (24855, ts.Days, "Days");
158                 Assert.AreEqual (2, ts.Hours, "Hours");
159                 Assert.AreEqual (28, ts.Minutes, "Minutes");
160                 Assert.AreEqual (16, ts.Seconds, "Seconds");
161                 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
162                 Assert.AreEqual (21474808960000000, ts.Ticks, "Ticks");
163         }
164
165         [Test]
166         [Ignore ("too long")]
167         public void MinHours_TooLong () 
168         {
169                 // LAMESPEC: the lowest hours are "special"
170                 for (int i=Int32.MinValue; i < -2146887124; i++) {
171                         TimeSpan ts = new TimeSpan (0, i, 0, 0, 0);
172                         int h = i + Int32.MaxValue + 1;
173                         string prefix = i.ToString () + '-';
174                         Assert.AreEqual ((h / 24), ts.Days, prefix + "Days");
175                         Assert.AreEqual ((h % 24), ts.Hours, prefix + "Hours");
176                         Assert.AreEqual (0, ts.Minutes, prefix + "Minutes");
177                         Assert.AreEqual (0, ts.Seconds, prefix + "Seconds");
178                         Assert.AreEqual (0, ts.Milliseconds, prefix + "Milliseconds");
179                         Assert.AreEqual (36000000000 * h, ts.Ticks, prefix + "Ticks");
180                 }
181         }
182
183         [Test]
184 #if NET_2_0
185         [Category ("NotWorking")]
186 #endif
187         public void MinHours () 
188         {
189 #if NET_2_0
190                 TimeSpan ts = new TimeSpan (0, -256204778, 0, 0, 0);
191                 Assert.AreEqual (-10675199, ts.Days, "Days");
192                 Assert.AreEqual (-2, ts.Hours, "Hours");
193                 Assert.AreEqual (0, ts.Minutes, "Minutes");
194                 Assert.AreEqual (0, ts.Seconds, "Seconds");
195                 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
196                 Assert.AreEqual (-9223372008000000000, ts.Ticks, "Ticks");
197 #else
198                 // LAMESPEC: the lowest hours are "special"
199                 TimeSpan ts = new TimeSpan (0, Int32.MinValue, 0, 0, 0);
200                 Assert.AreEqual (0, ts.Days, "Min-Days");
201                 Assert.AreEqual (0, ts.Hours, "Min-Hours");
202                 Assert.AreEqual (0, ts.Minutes, "Min-Minutes");
203                 Assert.AreEqual (0, ts.Seconds, "Min-Seconds");
204                 Assert.AreEqual (0, ts.Milliseconds, "Min-Milliseconds");
205                 Assert.AreEqual (0, ts.Ticks, "Min-Ticks");
206
207                 ts = new TimeSpan (0, -2146887125, 0, 0, 0);
208                 Assert.AreEqual (24855, ts.Days, "Days");
209                 Assert.AreEqual (3, ts.Hours, "Hours");
210                 Assert.AreEqual (0, ts.Minutes, "Minutes");
211                 Assert.AreEqual (0, ts.Seconds, "Seconds");
212                 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
213                 Assert.AreEqual (21474828000000000, ts.Ticks, "Ticks");
214 #endif
215         }
216
217         [Test]
218 #if NET_2_0
219         [ExpectedException (typeof (ArgumentOutOfRangeException))]
220         [Category ("NotWorking")]
221 #endif
222         public void MinHours_BreakPoint () 
223         {
224                 TimeSpan ts = new TimeSpan (0, -2146887124, 0, 0, 0);
225                 Assert.AreEqual (-24855, ts.Days, "Days");
226                 Assert.AreEqual (-2, ts.Hours, "Hours");
227                 Assert.AreEqual (-28, ts.Minutes, "Minutes");
228                 Assert.AreEqual (-16, ts.Seconds, "Seconds");
229                 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
230                 Assert.AreEqual (-21474808960000000, ts.Ticks, "Ticks");
231         }
232
233         [Test]
234         [Ignore ("too long")]
235         public void MaxMinutes_TooLong () 
236         {
237                 // LAMESPEC: the highest minutes are "special"
238                 for (int i=0; i < 35791394; i++) {
239                         TimeSpan ts = new TimeSpan (0, 0, Int32.MaxValue - i, 0, 0);
240                         long h = -(i + 1);
241                         string prefix = i.ToString () + '-';
242                         Assert.AreEqual ((h / 1440), ts.Days, prefix + "Days");
243                         Assert.AreEqual (((h / 60) % 24), ts.Hours, prefix + "Hours");
244                         Assert.AreEqual ((h % 60), ts.Minutes, prefix + "Minutes");
245                         Assert.AreEqual (0, ts.Seconds, prefix + "Seconds");
246                         Assert.AreEqual (0, ts.Milliseconds, prefix + "Milliseconds");
247                         Assert.AreEqual ((600000000L * h), ts.Ticks, prefix + "Ticks");
248                 }
249         }
250
251         [Test]
252 #if NET_2_0
253         [Category ("NotWorking")]
254 #endif
255         public void MaxMinutes () 
256         {
257                 TimeSpan ts;
258 #if NET_2_0
259                 ts = new TimeSpan (0, 0, 256204778, 0, 0);
260                 Assert.AreEqual (177919, ts.Days, "Max-Days");
261                 Assert.AreEqual (23, ts.Hours, "Max-Hours");
262                 Assert.AreEqual (38, ts.Minutes, "Max-Minutes");
263                 Assert.AreEqual (0, ts.Seconds, "Max-Seconds");
264                 Assert.AreEqual (0, ts.Milliseconds, "Max-Milliseconds");
265                 Assert.AreEqual (153722866800000000, ts.Ticks, "Max-Ticks");
266 #else
267                 // LAMESPEC: the highest minutes are "special"
268                 ts = new TimeSpan (0, 0, Int32.MaxValue, 0, 0);
269                 Assert.AreEqual (0, ts.Days, "Max-Days");
270                 Assert.AreEqual (0, ts.Hours, "Max-Hours");
271                 Assert.AreEqual (-1, ts.Minutes, "Max-Minutes");
272                 Assert.AreEqual (0, ts.Seconds, "Max-Seconds");
273                 Assert.AreEqual (0, ts.Milliseconds, "Max-Milliseconds");
274                 Assert.AreEqual (-600000000, ts.Ticks, "Max-Ticks");
275
276                 ts = new TimeSpan (0, 0, Int32.MaxValue - 35791393, 0, 0);
277                 Assert.AreEqual (-24855, ts.Days, "Days");
278                 Assert.AreEqual (-3, ts.Hours, "Hours");
279                 Assert.AreEqual (-14, ts.Minutes, "Minutes");
280                 Assert.AreEqual (0, ts.Seconds, "Seconds");
281                 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
282                 Assert.AreEqual (-21474836400000000, ts.Ticks, "Ticks");
283 #endif
284         }
285
286         [Test]
287 #if NET_2_0
288         [ExpectedException (typeof (ArgumentOutOfRangeException))]
289         [Category ("NotWorking")]
290 #endif
291         public void MaxMinutes_BreakPoint () 
292         {
293                 TimeSpan ts = new TimeSpan (0, Int32.MaxValue - 35791394, 0, 0, 0);
294                 Assert.AreEqual (0, ts.Days, "Days");
295                 Assert.AreEqual (0, ts.Hours, "Hours");
296                 Assert.AreEqual (-52, ts.Minutes, "Minutes");
297                 Assert.AreEqual (0, ts.Seconds, "Seconds");
298                 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
299                 Assert.AreEqual (-31200000000, ts.Ticks, "Ticks");
300         }
301
302         [Test]
303         [Ignore ("too long")]
304         public void MinMinutes_TooLong () 
305         {
306                 // LAMESPEC: the highest minutes are "special"
307                 for (int i=Int32.MinValue; i < -2111692253; i++) {
308                         TimeSpan ts = new TimeSpan (0, 0, i, 0, 0);
309                         long h = i + Int32.MaxValue + 1;
310                         string prefix = i.ToString () + '-';
311                         Assert.AreEqual ((h / 1440), ts.Days, prefix + "Days");
312                         Assert.AreEqual (((h / 60) % 24), ts.Hours, prefix + "Hours");
313                         Assert.AreEqual ((h % 60), ts.Minutes, prefix + "Minutes");
314                         Assert.AreEqual (0, ts.Seconds, prefix + "Seconds");
315                         Assert.AreEqual (0, ts.Milliseconds, prefix + "Milliseconds");
316                         Assert.AreEqual ((600000000L * h), ts.Ticks, prefix + "Ticks");
317                 }
318         }
319
320         [Test]
321 #if NET_2_0
322         [Category ("NotWorking")]
323 #endif
324         public void MinMinutes () 
325         {
326                 TimeSpan ts;
327 #if NET_2_0
328                 ts = new TimeSpan (0, 0, Int32.MinValue, 0, 0);
329                 Assert.AreEqual (-1491308, ts.Days, "Days");
330                 Assert.AreEqual (-2, ts.Hours, "Hours");
331                 Assert.AreEqual (-8, ts.Minutes, "Minutes");
332                 Assert.AreEqual (0, ts.Seconds, "Seconds");
333                 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
334                 Assert.AreEqual (-1288490188800000000, ts.Ticks, "Ticks");
335 #else
336                 // LAMESPEC: the highest minutes are "special"
337                 ts = new TimeSpan (0, 0, Int32.MinValue, 0, 0);
338                 Assert.AreEqual (0, ts.Days, "Min-Days");
339                 Assert.AreEqual (0, ts.Hours, "Min-Hours");
340                 Assert.AreEqual (0, ts.Minutes, "Min-Minutes");
341                 Assert.AreEqual (0, ts.Seconds, "Min-Seconds");
342                 Assert.AreEqual (0, ts.Milliseconds, "Min-Milliseconds");
343                 Assert.AreEqual (0, ts.Ticks, "Min-Ticks");
344
345                 ts = new TimeSpan (0, 0, -2111692254, 0, 0);
346                 Assert.AreEqual (24855, ts.Days, "Days");
347                 Assert.AreEqual (3, ts.Hours, "Hours");
348                 Assert.AreEqual (14, ts.Minutes, "Minutes");
349                 Assert.AreEqual (0, ts.Seconds, "Seconds");
350                 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
351                 Assert.AreEqual (21474836400000000, ts.Ticks, "Ticks");
352 #endif
353         }
354
355         [Test]
356 #if NET_2_0
357         [Category ("NotWorking")]
358 #endif
359         public void MinMinutes_BreakPoint () 
360         {
361 #if NET_2_0
362                 TimeSpan ts = new TimeSpan (0, 0, -2111692253, 0, 0);
363                 Assert.AreEqual (-1466452, ts.Days, "Days");
364                 Assert.AreEqual (-22, ts.Hours, "Hours");
365                 Assert.AreEqual (-53, ts.Minutes, "Minutes");
366                 Assert.AreEqual (-0, ts.Seconds, "Seconds");
367                 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
368                 Assert.AreEqual (-1267015351800000000, ts.Ticks, "Ticks");
369 #else
370                 TimeSpan ts = new TimeSpan (0, 0, -2111692253, 0, 0);
371                 Assert.AreEqual (-24855, ts.Days, "Days");
372                 Assert.AreEqual (-3, ts.Hours, "Hours");
373                 Assert.AreEqual (-13, ts.Minutes, "Minutes");
374                 Assert.AreEqual (-16, ts.Seconds, "Seconds");
375                 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
376                 Assert.AreEqual (-21474835960000000, ts.Ticks, "Ticks");
377 #endif
378         }
379
380         [Test]
381         public void MaxSeconds () 
382         {
383                 TimeSpan ts = new TimeSpan (0, 0, 0, Int32.MaxValue, 0);
384                 Assert.AreEqual (24855, ts.Days, "Days");
385                 Assert.AreEqual (3, ts.Hours, "Hours");
386                 Assert.AreEqual (14, ts.Minutes, "Minutes");
387                 Assert.AreEqual (7, ts.Seconds, "Seconds");
388                 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
389                 Assert.AreEqual (21474836470000000, ts.Ticks, "Ticks");
390         }
391
392         [Test]
393         public void MinSeconds () 
394         {
395                 TimeSpan ts = new TimeSpan (0, 0, 0, Int32.MinValue, 0);
396                 Assert.AreEqual (-24855, ts.Days, "Days");
397                 Assert.AreEqual (-3, ts.Hours, "Hours");
398                 Assert.AreEqual (-14, ts.Minutes, "Minutes");
399                 Assert.AreEqual (-8, ts.Seconds, "Seconds");
400                 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
401                 Assert.AreEqual (-21474836480000000, ts.Ticks, "Ticks");
402         }
403
404         [Test]
405         public void MaxMilliseconds () 
406         {
407                 TimeSpan ts = new TimeSpan (0, 0, 0, 0, Int32.MaxValue);
408                 Assert.AreEqual (24, ts.Days, "Days");
409                 Assert.AreEqual (20, ts.Hours, "Hours");
410                 Assert.AreEqual (31, ts.Minutes, "Minutes");
411                 Assert.AreEqual (23, ts.Seconds, "Seconds");
412                 Assert.AreEqual (647, ts.Milliseconds, "Milliseconds");
413                 Assert.AreEqual (21474836470000, ts.Ticks, "Ticks");
414         }
415
416         [Test]
417         public void MinMilliseconds () 
418         {
419                 TimeSpan ts = new TimeSpan (0, 0, 0, 0, Int32.MinValue);
420                 Assert.AreEqual (-24, ts.Days, "Days");
421                 Assert.AreEqual (-20, ts.Hours, "Hours");
422                 Assert.AreEqual (-31, ts.Minutes, "Minutes");
423                 Assert.AreEqual (-23, ts.Seconds, "Seconds");
424                 Assert.AreEqual (-648, ts.Milliseconds, "Milliseconds");
425                 Assert.AreEqual (-21474836480000, ts.Ticks, "Ticks");
426         }
427
428         [Test]
429         public void NegativeTimeSpan () 
430         {
431                 TimeSpan ts = new TimeSpan (-23, -59, -59);
432                 Assert.AreEqual (0, ts.Days, "Days");
433                 Assert.AreEqual (-23, ts.Hours, "Hours");
434                 Assert.AreEqual (-59, ts.Minutes, "Minutes");
435                 Assert.AreEqual (-59, ts.Seconds, "Seconds");
436                 Assert.AreEqual (0, ts.Milliseconds, "Milliseconds");
437                 Assert.AreEqual (-863990000000, ts.Ticks, "Ticks");
438         }
439
440         public void TestProperties ()
441         {
442                 TimeSpan t1 = new TimeSpan (1,2,3,4,5);
443                 TimeSpan t2 = -t1;
444
445                 Assert.AreEqual (1, t1.Days, "A1");
446                 Assert.AreEqual (2, t1.Hours, "A2");
447                 Assert.AreEqual (3, t1.Minutes, "A3");
448                 Assert.AreEqual (4, t1.Seconds, "A4");
449                 Assert.AreEqual (5, t1.Milliseconds, "A5");
450                 Assert.AreEqual (-1, t2.Days, "A6");
451                 Assert.AreEqual (-2, t2.Hours, "A7");
452                 Assert.AreEqual (-3, t2.Minutes, "A8");
453                 Assert.AreEqual (-4, t2.Seconds, "A9");
454                 Assert.AreEqual (-5, t2.Milliseconds, "A10");
455         }
456
457         public void TestAdd ()
458         {
459                 TimeSpan t1 = new TimeSpan (2,3,4,5,6);
460                 TimeSpan t2 = new TimeSpan (1,2,3,4,5);
461                 TimeSpan t3 = t1 + t2;
462                 TimeSpan t4 = t1.Add (t2);
463                 TimeSpan t5;
464                 bool exception;
465
466                 Assert.AreEqual (3, t3.Days, "A1");
467                 Assert.AreEqual (5, t3.Hours, "A2");
468                 Assert.AreEqual (7, t3.Minutes, "A3");
469                 Assert.AreEqual (9, t3.Seconds, "A4");
470                 Assert.AreEqual (11, t3.Milliseconds, "A5");
471                 Assert.AreEqual ("3.05:07:09.0110000", t4.ToString (), "A6");
472                 try
473                 {
474                         t5 = TimeSpan.MaxValue + new TimeSpan (1);                      
475                         exception = false;
476                 }
477                 catch (OverflowException)
478                 {
479                         exception = true;
480                 }
481                 Assert.IsTrue (exception, "A7");
482         }
483
484         public void TestCompare ()
485         {
486                 TimeSpan t1 = new TimeSpan (-1);
487                 TimeSpan t2 = new TimeSpan (1);
488                 int res;
489                 bool exception;
490
491                 Assert.AreEqual (-1, TimeSpan.Compare (t1, t2), "A1");
492                 Assert.AreEqual (1, TimeSpan.Compare (t2, t1), "A2");
493                 Assert.AreEqual (0, TimeSpan.Compare (t2, t2), "A3");
494                 Assert.AreEqual (-1, TimeSpan.Compare (TimeSpan.MinValue, TimeSpan.MaxValue), "A4");
495                 Assert.AreEqual (-1, t1.CompareTo (t2), "A5");
496                 Assert.AreEqual (1, t2.CompareTo (t1), "A6");
497                 Assert.AreEqual (0, t2.CompareTo (t2), "A7");
498                 Assert.AreEqual (-1, TimeSpan.Compare (TimeSpan.MinValue, TimeSpan.MaxValue), "A8");
499
500                 Assert.AreEqual (1, TimeSpan.Zero.CompareTo (null), "A9");
501                 
502                 try
503                 {
504                         res = TimeSpan.Zero.CompareTo("");
505                         exception = false;      
506                 }
507                 catch (ArgumentException)
508                 {
509                         exception = true;
510                 }
511                 Assert.IsTrue (exception, "A10");
512
513                 Assert.AreEqual (false, t1 == t2, "A11");
514                 Assert.AreEqual (false, t1 > t2, "A12");
515                 Assert.AreEqual (false, t1 >= t2, "A13");
516                 Assert.AreEqual (true, t1 != t2, "A14");
517                 Assert.AreEqual (true, t1 < t2, "A15");
518                 Assert.AreEqual (true, t1 <= t2, "A16");
519         }
520
521         [Test]
522         [ExpectedException (typeof (OverflowException))]
523         public void NoNegateMinValue() {
524                 TimeSpan t1 = TimeSpan.MinValue.Negate ();
525         }
526
527         public void TestNegateAndDuration ()
528         {
529                 TimeSpan t1;
530                 bool exception;
531
532                 Assert.AreEqual ("-00:00:00.0012345", new TimeSpan (12345).Negate ().ToString (), "A1");
533                 Assert.AreEqual ("00:00:00.0012345", new TimeSpan (-12345).Duration ().ToString (), "A2");
534                         
535                 try
536                 {
537                         t1 = TimeSpan.MinValue.Duration ();
538                         exception = false;
539                 }
540                 catch (OverflowException) {
541                         exception = true;
542                 }
543                 Assert.IsTrue (exception, "A4");
544
545                 Assert.AreEqual ("-00:00:00.0000077", (-(new TimeSpan (77))).ToString (), "A5");
546                 Assert.AreEqual ("00:00:00.0000077", (+(new TimeSpan(77))).ToString(), "A6");
547         }
548
549         public void TestEquals ()
550         {
551                 TimeSpan t1 = new TimeSpan (1);
552                 TimeSpan t2 = new TimeSpan (2);
553                 string s = "justastring";
554
555                 Assert.AreEqual (true, t1.Equals (t1), "A1");
556                 Assert.AreEqual (false, t1.Equals (t2), "A2");
557                 Assert.AreEqual (false, t1.Equals (s), "A3");
558                 Assert.AreEqual (false, t1.Equals (null), "A4");
559                 Assert.AreEqual (true, TimeSpan.Equals (t1, t1), "A5");
560                 Assert.AreEqual (false, TimeSpan.Equals (t1, t2), "A6");
561                 Assert.AreEqual (false, TimeSpan.Equals (t1, null), "A7");
562                 Assert.AreEqual (false, TimeSpan.Equals (t1, s), "A8");
563                 Assert.AreEqual (false, TimeSpan.Equals (s, t2), "A9");
564                 Assert.AreEqual (true, TimeSpan.Equals (null, null), "A10");
565         }
566
567         public void TestFromXXXX ()
568         {
569                 Assert.AreEqual ("12.08:16:48", TimeSpan.FromDays (12.345).ToString (), "A1");
570                 Assert.AreEqual ("12:20:42", TimeSpan.FromHours (12.345).ToString (), "A2");
571                 Assert.AreEqual ("00:12:20.7000000", TimeSpan.FromMinutes (12.345).ToString (), "A3");
572                 Assert.AreEqual ("00:00:12.3450000", TimeSpan.FromSeconds (12.345).ToString (), "A4");
573                 Assert.AreEqual ("00:00:00.0120000", TimeSpan.FromMilliseconds (12.345).ToString (), "A5");
574                 Assert.AreEqual ("00:00:00.0012345", TimeSpan.FromTicks (12345).ToString (), "A6");
575         }
576
577         [Test]
578         [ExpectedException (typeof (OverflowException))]
579         public void FromDays_MinValue ()
580         {
581                 TimeSpan.FromDays (Double.MinValue);
582         }
583
584         [Test]
585         [ExpectedException (typeof (OverflowException))]
586         public void FromDays_MaxValue ()
587         {
588                 TimeSpan.FromDays (Double.MaxValue);
589         }
590
591         [Test]
592         [ExpectedException (typeof (ArgumentException))]
593         public void FromDays_NaN ()
594         {
595                 TimeSpan.FromDays (Double.NaN);
596         }
597
598         [Test]
599         [ExpectedException (typeof (OverflowException))]
600         public void FromDays_PositiveInfinity ()
601         {
602                 // LAMESPEC: Document to return TimeSpan.MaxValue
603                 Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.FromDays (Double.PositiveInfinity));
604         }
605
606         [Test]
607         [ExpectedException (typeof (OverflowException))]
608         public void FromDays_NegativeInfinity ()
609         {
610                 // LAMESPEC: Document to return TimeSpan.MinValue
611                 Assert.AreEqual (TimeSpan.MinValue, TimeSpan.FromDays (Double.NegativeInfinity));
612         }
613
614         [Test]
615         [ExpectedException (typeof (OverflowException))]
616         public void FromHours_MinValue ()
617         {
618                 TimeSpan.FromHours (Double.MinValue);
619         }
620
621         [Test]
622         [ExpectedException (typeof (OverflowException))]
623         public void FromHours_MaxValue ()
624         {
625                 TimeSpan.FromHours (Double.MaxValue);
626         }
627
628         [Test]
629         [ExpectedException (typeof (ArgumentException))]
630         public void FromHours_NaN ()
631         {
632                 TimeSpan.FromHours (Double.NaN);
633         }
634
635         [Test]
636         [ExpectedException (typeof (OverflowException))]
637         public void FromHours_PositiveInfinity ()
638         {
639                 // LAMESPEC: Document to return TimeSpan.MaxValue
640                 Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.FromHours (Double.PositiveInfinity));
641         }
642
643         [Test]
644         [ExpectedException (typeof (OverflowException))]
645         public void FromHours_NegativeInfinity ()
646         {
647                 // LAMESPEC: Document to return TimeSpan.MinValue
648                 Assert.AreEqual (TimeSpan.MinValue, TimeSpan.FromHours (Double.NegativeInfinity));
649         }
650
651         [Test]
652         [ExpectedException (typeof (OverflowException))]
653         public void FromMilliseconds_MinValue ()
654         {
655                 TimeSpan.FromMilliseconds (Double.MinValue);
656         }
657
658         [Test]
659         [ExpectedException (typeof (OverflowException))]
660         public void FromMilliseconds_MaxValue ()
661         {
662                 TimeSpan.FromMilliseconds (Double.MaxValue);
663         }
664
665         [Test]
666         [ExpectedException (typeof (ArgumentException))]
667         public void FromMilliseconds_NaN ()
668         {
669                 TimeSpan.FromMilliseconds (Double.NaN);
670         }
671
672         [Test]
673         [ExpectedException (typeof (OverflowException))]
674         public void FromMilliseconds_PositiveInfinity ()
675         {
676                 // LAMESPEC: Document to return TimeSpan.MaxValue
677                 Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.FromMilliseconds (Double.PositiveInfinity));
678         }
679
680         [Test]
681         [ExpectedException (typeof (OverflowException))]
682         public void FromMilliseconds_NegativeInfinity ()
683         {
684                 // LAMESPEC: Document to return TimeSpan.MinValue
685                 Assert.AreEqual (TimeSpan.MinValue, TimeSpan.FromMilliseconds (Double.NegativeInfinity));
686         }
687
688         [Test]
689         [ExpectedException (typeof (OverflowException))]
690         public void FromMinutes_MinValue ()
691         {
692                 TimeSpan.FromMinutes (Double.MinValue);
693         }
694
695         [Test]
696         [ExpectedException (typeof (OverflowException))]
697         public void FromMinutes_MaxValue ()
698         {
699                 TimeSpan.FromMinutes (Double.MaxValue);
700         }
701
702         [Test]
703         [ExpectedException (typeof (ArgumentException))]
704         public void FromMinutes_NaN ()
705         {
706                 TimeSpan.FromMinutes (Double.NaN);
707         }
708
709         [Test]
710         [ExpectedException (typeof (OverflowException))]
711         public void FromMinutes_PositiveInfinity ()
712         {
713                 // LAMESPEC: Document to return TimeSpan.MaxValue
714                 Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.FromMinutes (Double.PositiveInfinity));
715         }
716
717         [Test]
718         [ExpectedException (typeof (OverflowException))]
719         public void FromMinutes_NegativeInfinity ()
720         {
721                 // LAMESPEC: Document to return TimeSpan.MinValue
722                 Assert.AreEqual (TimeSpan.MinValue, TimeSpan.FromMinutes (Double.NegativeInfinity));
723         }
724
725         [Test]
726         [ExpectedException (typeof (OverflowException))]
727         public void FromSeconds_MinValue ()
728         {
729                 TimeSpan.FromSeconds (Double.MinValue);
730         }
731
732         [Test]
733         [ExpectedException (typeof (OverflowException))]
734         public void FromSeconds_MaxValue ()
735         {
736                 TimeSpan.FromSeconds (Double.MaxValue);
737         }
738
739         [Test]
740         [ExpectedException (typeof (ArgumentException))]
741         public void FromSeconds_NaN ()
742         {
743                 TimeSpan.FromSeconds (Double.NaN);
744         }
745
746         [Test]
747         [ExpectedException (typeof (OverflowException))]
748         public void FromSeconds_PositiveInfinity ()
749         {
750                 // LAMESPEC: Document to return TimeSpan.MaxValue
751                 Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.FromSeconds (Double.PositiveInfinity));
752         }
753
754         [Test]
755         [ExpectedException (typeof (OverflowException))]
756         public void FromSeconds_NegativeInfinity ()
757         {
758                 // LAMESPEC: Document to return TimeSpan.MinValue
759                 Assert.AreEqual (TimeSpan.MinValue, TimeSpan.FromSeconds (Double.NegativeInfinity));
760         }
761
762         public void TestGetHashCode ()
763         {
764                 Assert.AreEqual (77, new TimeSpan (77).GetHashCode (), "A1");
765         }
766
767         private void ParseHelper (string s, bool expectFormat, bool expectOverflow, string expect)
768         {
769                 bool formatException = false;
770                 bool overflowException = false;
771                 string result = "junk ";
772
773                 try {
774                         result =  TimeSpan.Parse (s).ToString ();
775                 }
776                 catch (OverflowException) {
777                         overflowException = true;
778                 }
779                 catch (FormatException) {
780                         formatException = true;
781                 }
782                 Assert.AreEqual (expectFormat, formatException, "A1");
783                 Assert.AreEqual (expectOverflow, overflowException, "A2");
784
785                 if (!expectOverflow && !expectFormat) {
786                         Assert.AreEqual (expect, result, "A3");
787                 }
788         }
789
790         public void TestParse ()
791         {
792                 ParseHelper (" 13:45:15 ",false, false, "13:45:15");
793                 ParseHelper (" -1:2:3 ", false, false, "-01:02:03");
794
795                 ParseHelper (" 25:0:0 ",false, true, "dontcare");
796                 ParseHelper ("aaa", true, false, "dontcare");
797
798                 ParseHelper ("-21.23:59:59.9999999", false, false, "-21.23:59:59.9999999");
799
800                 ParseHelper ("100000000000000.1:1:1", false, true, "dontcare");
801                 ParseHelper ("24:60:60", false, true, "dontcare");
802                 ParseHelper ("0001:0002:0003.12     ", false, false, "01:02:03.1200000");
803
804                 ParseHelper (" 1:2:3:12345678 ", true, false, "dontcare"); 
805         }
806
807         // LAMESPEC: timespan in documentation is wrong - hh:mm:ss isn't mandatory
808         [Test]
809         public void Parse_Days_WithoutColon () 
810         {
811                 TimeSpan ts = TimeSpan.Parse ("1");
812                 Assert.AreEqual (1, ts.Days, "Days");
813         }
814
815         public void TestSubstract ()
816         {
817                 TimeSpan t1 = new TimeSpan (2,3,4,5,6);
818                 TimeSpan t2 = new TimeSpan (1,2,3,4,5);
819                 TimeSpan t3 = t1 - t2;
820                 TimeSpan t4 = t1.Subtract (t2);
821                 TimeSpan t5;
822                 bool exception;
823
824                 Assert.AreEqual ("1.01:01:01.0010000", t3.ToString (), "A1");
825                 Assert.AreEqual ("1.01:01:01.0010000", t4.ToString (), "A2");
826                 try {
827                         t5 = TimeSpan.MinValue - new TimeSpan (1);
828                         exception = false;
829                 }
830                 catch (OverflowException) {
831                         exception = true;
832                 }
833                 Assert.IsTrue (exception, "A3");
834         }
835
836         public void TestToString () 
837         {
838                 TimeSpan t1 = new TimeSpan (1,2,3,4,5);
839                 TimeSpan t2 = -t1;
840                 
841                 Assert.AreEqual ("1.02:03:04.0050000", t1.ToString (), "A1");
842                 Assert.AreEqual ("-1.02:03:04.0050000", t2.ToString (), "A2");
843                 Assert.AreEqual ("10675199.02:48:05.4775807", TimeSpan.MaxValue.ToString (), "A3");
844                 Assert.AreEqual ("-10675199.02:48:05.4775808", TimeSpan.MinValue.ToString (), "A4");
845         }
846
847         [Test]
848         public void ToString_Constants () 
849         {
850                 Assert.AreEqual ("00:00:00", TimeSpan.Zero.ToString (), "Zero");
851                 Assert.AreEqual ("10675199.02:48:05.4775807", TimeSpan.MaxValue.ToString (), "MaxValue");
852                 Assert.AreEqual ("-10675199.02:48:05.4775808", TimeSpan.MinValue.ToString (), "MinValue");
853         }
854
855         [Test]
856         [ExpectedException (typeof (OverflowException))]
857         public void Parse_InvalidValuesAndFormat_ExceptionOrder () 
858         {
859                 // hours should be between 0 and 23 but format is also invalid (too many dots)
860                 TimeSpan.Parse ("0.99.99.0");
861         }
862
863         [Test]
864         public void Parse_MinMaxValues () 
865         {
866                 Assert.AreEqual (TimeSpan.MaxValue, TimeSpan.Parse ("10675199.02:48:05.4775807"), "MaxValue");
867                 Assert.AreEqual (TimeSpan.MinValue, TimeSpan.Parse ("-10675199.02:48:05.4775808"), "MinValue");
868         }
869
870         [Test]
871         [ExpectedException (typeof (OverflowException))]
872         public void Parse_OverMaxValue() 
873         {
874                 TimeSpan.Parse ("10675199.02:48:05.4775808");
875         }
876
877         [Test]
878         [ExpectedException (typeof (OverflowException))]
879         public void Parse_UnderMinValue() 
880         {
881                 TimeSpan.Parse ("-10675199.02:48:05.4775809");
882         }
883
884         [Test]
885         public void ParseMissingSeconds ()
886         {
887                 // as seen in ML for http://resources.esri.com/arcgisserver/apis/silverlight/
888                 TimeSpan ts = TimeSpan.Parse ("0:0:.75");
889
890                 Assert.AreEqual (0, ts.Days, "Days");
891                 Assert.AreEqual (0, ts.Hours, "Hours");
892                 Assert.AreEqual (750, ts.Milliseconds, "Milliseconds");
893                 Assert.AreEqual (0, ts.Minutes, "Minutes");
894                 Assert.AreEqual (0, ts.Seconds, "Seconds");
895                 Assert.AreEqual (7500000, ts.Ticks, "Ticks");
896                 Assert.AreEqual (0.0000086805555555555555, ts.TotalDays, 0.00000000000000001, "TotalDays");
897                 Assert.AreEqual (0.00020833333333333332, ts.TotalHours, 0.00000000000000001, "TotalHours");
898                 Assert.AreEqual (750.0, ts.TotalMilliseconds, "TotalMilliseconds");
899                 Assert.AreEqual (0.0125, ts.TotalMinutes, "TotalMinutes");
900                 Assert.AreEqual (0.75, ts.TotalSeconds, "TotalSeconds");
901         }
902
903         // 'Ported' the Parse test to use TryParse
904         [Test]
905         public void TryParse ()
906         {
907                 TimeSpan result;
908
909                 Assert.AreEqual (true, TimeSpan.TryParse (" 13:45:15 ", out result), "#A1");
910                 Assert.AreEqual ("13:45:15", result.ToString (), "#A2");
911
912                 Assert.AreEqual (true, TimeSpan.TryParse (" -1:2:3 ", out result), "#B1");
913                 Assert.AreEqual ("-01:02:03", result.ToString (), "#B2");
914
915                 Assert.AreEqual (false, TimeSpan.TryParse (" 25:0:0 ", out result), "#C1");
916                 Assert.AreEqual (false, TimeSpan.TryParse ("aaa", out result), "#C2");
917
918                 Assert.AreEqual (true, TimeSpan.TryParse ("-21.23:59:59.9999999", out result), "#D1");
919                 Assert.AreEqual ("-21.23:59:59.9999999", result.ToString (), "#D2");
920
921                 Assert.AreEqual (false, TimeSpan.TryParse ("100000000000000.1:1:1", out result), "#E1");
922                 Assert.AreEqual (false, TimeSpan.TryParse ("24:60:60", out result), "#E2");
923
924                 ParseHelper ("0001:0002:0003.12     ", false, false, "01:02:03.1200000");
925                 Assert.AreEqual (true, TimeSpan.TryParse ("0001:0002:0003.12     ", out result), "#F1");
926                 Assert.AreEqual ("01:02:03.1200000", result.ToString (), "#F2");
927
928                 Assert.AreEqual (false, TimeSpan.TryParse (" 1:2:3:12345678 ", out result), "#G1");
929
930                 // Min and Max values
931                 Assert.AreEqual (true, TimeSpan.TryParse ("10675199.02:48:05.4775807", out result), "MaxValue#1");
932                 Assert.AreEqual (TimeSpan.MaxValue, result, "MaxValue#2");
933                 Assert.AreEqual (true, TimeSpan.TryParse ("-10675199.02:48:05.4775808", out result), "MinValue#1");
934                 Assert.AreEqual (TimeSpan.MinValue, result, "MinValue#2");
935         }
936
937         [Test]
938         public void TryParseErrors ()
939         {
940                 TimeSpan result;
941
942                 Assert.AreEqual (false, TimeSpan.TryParse ("0.99.99.0", out result), "Format#1");
943                 Assert.AreEqual (false, TimeSpan.TryParse ("10675199.02:48:05.4775808", out result), "OverMaxValue");
944                 Assert.AreEqual (false, TimeSpan.TryParse ("-10675199.02:48:05.4775809", out result), "UnderMinValue");
945         }
946
947 #if NET_4_0
948         [Test]
949         public void ToStringOverloads ()
950         {
951                 TimeSpan ts = new TimeSpan (1, 2, 3, 4, 6);
952
953                 // Simple version - culture invariant
954                 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString (), "#A1");
955                 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString ("c"), "#A2");
956                 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString (null), "#A3");
957                 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString (String.Empty), "#A4");
958
959                 //
960                 // IFormatProvider ones - use a culture changing numeric format.
961                 // Also, we use fr-FR as culture, since it uses some elements different to invariant culture
962                 //
963                 CultureInfo culture = CultureInfo.GetCultureInfo ("fr-FR");
964
965                 Assert.AreEqual ("1:2:03:04,006", ts.ToString ("g", culture), "#B1");
966                 Assert.AreEqual ("1:02:03:04,0060000", ts.ToString ("G", culture), "#B2");
967                 Assert.AreEqual ("1.02:03:04.0060000", ts.ToString ("c", culture), "#B3"); // 'c' format ignores CultureInfo
968
969                 ts = new TimeSpan (4, 5, 6);
970                 Assert.AreEqual ("4:05:06", ts.ToString ("g", culture), "#C1");
971                 Assert.AreEqual ("0:04:05:06,0000000", ts.ToString ("G", culture), "#C2");
972         }
973
974         [Test]
975         public void ToStringOverloadsErrors ()
976         {
977                 TimeSpan ts = new TimeSpan (10, 10, 10);
978                 string result;
979
980                 try {
981                         result = ts.ToString ("non-valid");
982                         Assert.Fail ("#1");
983                 } catch (FormatException) {
984                 }
985
986                 try {
987                         result = ts.ToString ("C");
988                         Assert.Fail ("#2");
989                 } catch (FormatException) {
990                 }
991
992                 // This is suppoused to work, but the docs are wrong.
993                 try {
994                         result = ts.ToString ("t");
995                         Assert.Fail ("#3");
996                 } catch (FormatException) {
997                 }
998         }
999 #endif
1000 }
1001
1002 }