9dc808768423a72ce7f7c385eb127f12f8a214a4
[mono.git] / mcs / class / corlib / Test / System / DateTimeTest.cs
1 //
2 // DateTimeTest.cs - NUnit Test Cases for the System.DateTime struct
3 //
4 // author:
5 //   Martin Baulig (martin@gnome.org)
6 //
7 //   (C) 2002 Free Software Foundation
8 // Copyright (C) 2004 Novell (http://www.novell.com)
9 //
10
11 using System;
12 using System.IO;
13 using System.Threading;
14 using System.Globalization;
15 using System.Collections.Generic;
16 using System.Globalization;
17 using System.Runtime.CompilerServices;
18 using System.Runtime.InteropServices;
19 using System.Text;
20 using System.Runtime.Serialization;
21
22 using NUnit.Framework;
23
24 namespace MonoTests.System
25 {
26         [TestFixture]
27         public class DateTimeTest
28         {
29                 [Flags]
30                 internal enum Resolution : ushort
31                 {
32                         Year = 64,
33                         Month = 96,
34                         Day = 112,
35                         Hour = 120,
36                         Minute = 124,
37                         Second = 126,
38                         Millisecond = 127,
39                         _Month = 32,
40                         _Day = 16,
41                         _Hour = 8,
42                         _Minute = 4,
43                         _Second = 2,
44                         _Millisecond = 1
45                 }
46
47                 internal void DTAssertEquals (DateTime actual, DateTime expected, Resolution resolution)
48                 {
49                         DTAssertEquals (actual, expected, resolution, "");
50                 }
51
52                 internal void DTAssertEquals (DateTime expected, DateTime actual, Resolution resolution, string message)
53                 {
54                         if ((resolution & Resolution.Year) != 0)
55                                 Assert.AreEqual (expected.Year, actual.Year, message);
56                         if ((resolution & Resolution._Month) != 0)
57                                 Assert.AreEqual (expected.Month, actual.Month, message);
58                         if ((resolution & Resolution._Day) != 0)
59                                 Assert.AreEqual (expected.Day, actual.Day, message);
60                         if ((resolution & Resolution._Hour) != 0)
61                                 Assert.AreEqual (expected.Hour, actual.Hour, message);
62                         if ((resolution & Resolution._Minute) != 0)
63                                 Assert.AreEqual (expected.Minute, actual.Minute, message);
64                         if ((resolution & Resolution._Second) != 0)
65                                 Assert.AreEqual (expected.Second, actual.Second, message);
66                         if ((resolution & Resolution._Millisecond) != 0)
67                                 Assert.AreEqual (expected.Millisecond, actual.Millisecond, message);
68                 }
69
70                 private CultureInfo oldcult;
71         
72                 long[] myTicks = {
73                         631501920000000000L,    // 25 Feb 2002 - 00:00:00
74                         631502475130080000L,    // 25 Feb 2002 - 15:25:13,8
75                         631502115130080000L,    // 25 Feb 2002 - 05:25:13,8
76                         631502115000000000L,    // 25 Feb 2002 - 05:25:00
77                         631502115130000000L,    // 25 Feb 2002 - 05:25:13
78                         631502079130000000L,    // 25 Feb 2002 - 04:25:13
79                         629197085770000000L,    // 06 Nov 1994 - 08:49:37 
80                         631796544000000000L,    // 01 Feb 2003 - 00:00:00
81                 };
82
83                 [SetUp]
84                 public void SetUp() 
85                 {
86                         // the current culture determines the result of formatting
87                         oldcult = Thread.CurrentThread.CurrentCulture;
88                         Thread.CurrentThread.CurrentCulture = new CultureInfo ("");
89                 }
90         
91                 [TearDown]
92                 public void TearDown ()
93                 {
94                         Thread.CurrentThread.CurrentCulture = oldcult;
95                 }
96
97                 [Test]
98                 public void TestCtors ()
99                 {
100                         DateTime t1 = new DateTime (2002,2,25);
101                         Assert.AreEqual (myTicks [0], t1.Ticks, "A01");
102                         DateTime t2 = new DateTime (2002,2,25,15,25,13,8);
103                         Assert.AreEqual (myTicks [1], t2.Ticks, "A02");
104                         Assert.AreEqual (myTicks [0], t2.Date.Ticks, "A03");
105                         Assert.AreEqual (2002, t2.Year, "A04");
106                         Assert.AreEqual (2, t2.Month, "A05");
107                         Assert.AreEqual (25, t2.Day, "A06");
108                         Assert.AreEqual (15, t2.Hour, "A07");
109                         Assert.AreEqual (25, t2.Minute, "A08");
110                         Assert.AreEqual (13, t2.Second, "A09");
111                         Assert.AreEqual (8, t2.Millisecond, "A10");
112                         DateTime t3 = new DateTime (2002,2,25,5,25,13,8);
113                         Assert.AreEqual (myTicks [2], t3.Ticks, "A11");
114                 }
115
116                 [Test]
117                 public void Constructor_Max ()
118                 {
119                         Assert.AreEqual (3155378975999990000, new DateTime (9999, 12, 31, 23, 59, 59, 999).Ticks, "Max");
120                 }
121
122                 [Test]
123                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
124                 public void Constructor_Milliseconds_Negative () 
125                 {
126                         new DateTime (9999, 12, 31, 23, 59, 59, -1);
127                 }
128
129                 [Test]
130                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
131                 public void Constructor_Milliseconds_1000 () 
132                 {
133                         new DateTime (9999, 12, 31, 23, 59, 59, 1000);
134                 }
135                 
136                 [Test]
137                 public void Fields ()
138                 {
139                         Assert.AreEqual (3155378975999999999L, DateTime.MaxValue.Ticks, "#1");
140                         Assert.AreEqual (0, DateTime.MinValue.Ticks, "#2");
141                 }
142                 
143                 [Test]
144                 public void Add ()
145                 {
146                         DateTime t1 = new DateTime (myTicks [1]);
147                         TimeSpan span = new TimeSpan (3, 54, 1);
148                         DateTime t2 = t1.Add (span);
149
150                         Assert.AreEqual (25, t2.Day, "#1");
151                         Assert.AreEqual (19, t2.Hour, "#2");
152                         Assert.AreEqual (19, t2.Minute, "#3");
153                         Assert.AreEqual (14, t2.Second, "#4");
154
155                         Assert.AreEqual (25, t1.Day, "#5");
156                         Assert.AreEqual (15, t1.Hour, "#6");
157                         Assert.AreEqual (25, t1.Minute, "#7");
158                         Assert.AreEqual (13, t1.Second, "#8");
159                 }
160                 
161                 [Test]
162                 [ExpectedException(typeof (ArgumentOutOfRangeException))]
163                 public void AddOutOfRangeException1 ()
164                 {
165                         DateTime t1 = new DateTime (myTicks [1]);
166                         t1.Add (TimeSpan.MaxValue);
167                 }
168
169                 [Test]
170                 [ExpectedException(typeof (ArgumentOutOfRangeException))]
171                 public void AddOutOfRangeException2 ()
172                 {
173                         DateTime t1 = new DateTime (myTicks [1]);
174                         t1.Add (TimeSpan.MinValue);
175                 }
176         
177                 [Test]
178                 public void AddDays ()
179                 {
180                         DateTime t1 = new DateTime (myTicks [1]);
181                         t1 = t1.AddDays (3);
182                         Assert.AreEqual (28, t1.Day, "#A1");
183                         Assert.AreEqual (15, t1.Hour, "#A2");
184                         Assert.AreEqual (25, t1.Minute, "#A3");
185                         Assert.AreEqual (13, t1.Second, "#A4");
186                         
187                         t1 = t1.AddDays (1.9);
188                         Assert.AreEqual (2, t1.Day, "#B1");
189                         Assert.AreEqual (13, t1.Hour, "#B2");
190                         Assert.AreEqual (1, t1.Minute, "#B3");
191                         Assert.AreEqual (13, t1.Second, "#B4");
192
193                         t1 = t1.AddDays (0.2);
194                         Assert.AreEqual (2, t1.Day, "#C1");
195                         Assert.AreEqual (17, t1.Hour, "#C2");
196                         Assert.AreEqual (49, t1.Minute, "#C3");
197                         Assert.AreEqual (13, t1.Second, "#C4");
198                 }
199                 
200                 [Test]
201                 [ExpectedException(typeof (ArgumentOutOfRangeException))]
202                 public void AddDaysOutOfRangeException1 ()
203                 {
204                         DateTime t1 = new DateTime (myTicks [1]);
205                         t1.AddDays (10000000);
206                 }
207
208                 [Test]
209                 [ExpectedException(typeof (ArgumentOutOfRangeException))]
210                 public void AddDaysOutOfRangeException2 ()
211                 {
212                         DateTime t1 = new DateTime (myTicks [1]);
213                         t1.AddDays (-10000000);
214                 }
215
216                 [Test]
217                 public void AddHours ()
218                 {
219                         DateTime t1 = new DateTime (myTicks [1]);
220                         t1 = t1.AddHours (10);
221                         Assert.AreEqual (26, t1.Day, "#A1");
222                         Assert.AreEqual (1, t1.Hour, "#A2");
223                         Assert.AreEqual (25, t1.Minute, "#A3");
224                         Assert.AreEqual (13, t1.Second, "#A4");
225                         
226                         t1 = t1.AddHours (-3.7);
227                         Assert.AreEqual (25, t1.Day, "#B1");
228                         Assert.AreEqual (21, t1.Hour, "#B2");
229                         Assert.AreEqual (43, t1.Minute, "#B3");
230                         Assert.AreEqual (13, t1.Second, "#B4");
231
232                         t1 = t1.AddHours (3.732);
233                         Assert.AreEqual (26, t1.Day, "#C1");
234                         Assert.AreEqual (1, t1.Hour, "#C2");
235                         Assert.AreEqual (27, t1.Minute, "#C3");
236                         Assert.AreEqual (8, t1.Second, "#C4");
237                 }
238                 
239                 [Test]
240                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
241                 public void AddHoursOutOfRangeException1 ()
242                 {
243                         DateTime t1 = new DateTime (myTicks [1]);
244                         t1.AddHours (9E100);
245                 }
246
247                 [Test]
248                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
249                 public void AddHoursOutOfRangeException2 ()
250                 {
251                         DateTime t1 = new DateTime (myTicks [1]);
252                         t1.AddHours (-9E100);
253                 }
254
255                 [Test]
256                 public void AddMilliseconds ()
257                 {
258                         DateTime t1 = new DateTime (myTicks [1]);
259                         t1 = t1.AddMilliseconds (1E10);
260                         Assert.AreEqual (21, t1.Day, "#A1");
261                         Assert.AreEqual (9, t1.Hour, "#A2");
262                         Assert.AreEqual (11, t1.Minute, "#A3");
263                         Assert.AreEqual (53, t1.Second, "#A4");
264                         
265                         t1 = t1.AddMilliseconds (-19E10);
266                         Assert.AreEqual (13, t1.Day, "#B1");
267                         Assert.AreEqual (7, t1.Hour, "#B2");
268                         Assert.AreEqual (25, t1.Minute, "#B3");
269                         Assert.AreEqual (13, t1.Second, "#B4");
270
271                         t1 = t1.AddMilliseconds (15.623);
272                         Assert.AreEqual (13, t1.Day, "#C1");
273                         Assert.AreEqual (7, t1.Hour, "#C2");
274                         Assert.AreEqual (25, t1.Minute, "#C3");
275                         Assert.AreEqual (13, t1.Second, "#C4");
276                 }
277
278                 [Test]
279                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
280                 public void AddMillisecondsOutOfRangeException1 ()
281                 {
282                         DateTime t1 = new DateTime (myTicks [1]);
283                         t1.AddMilliseconds (9E100);
284                 }
285
286                 [Test]
287                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
288                 public void AddMillisecondsOutOfRangeException2 ()
289                 {
290                         DateTime t1 = new DateTime (myTicks [1]);
291                         t1.AddMilliseconds (-9E100);
292                 }
293
294                 [Test]
295                 public void TestToString ()
296                 {
297                         DateTime t1 = new DateTime (myTicks[2]);
298                         DateTime t2 = new DateTime (myTicks[1]);
299                         DateTime t3 = new DateTime (999, 1, 2, 3, 4, 5);
300                         // Standard patterns
301                         Assert.AreEqual ("02/25/2002", t1.ToString ("d"), "#A1");
302                         Assert.AreEqual ("Monday, 25 February 2002", t1.ToString ("D"), "#A2");
303                         Assert.AreEqual ("Monday, 25 February 2002 05:25", t1.ToString ("f"), "#A3");
304                         Assert.AreEqual ("Monday, 25 February 2002 05:25:13", t1.ToString ("F"), "#A4");
305                         Assert.AreEqual ("02/25/2002 05:25", t1.ToString ("g"), "#A5");
306                         Assert.AreEqual ("02/25/2002 05:25:13", t1.ToString ("G"), "#A6");
307                         Assert.AreEqual ("February 25", t1.ToString ("m"), "#A7");
308                         Assert.AreEqual ("February 25", t1.ToString ("M"), "#A8");
309                         Assert.AreEqual ("Mon, 25 Feb 2002 05:25:13 GMT", t1.ToString ("r"), "#A9");
310                         Assert.AreEqual ("Mon, 25 Feb 2002 05:25:13 GMT", t1.ToString ("R"), "#A10");
311                         Assert.AreEqual ("2002-02-25T05:25:13", t1.ToString ("s"), "#A11");
312                         Assert.AreEqual ("05:25", t1.ToString ("t"), "#A12");
313                         Assert.AreEqual ("05:25:13", t1.ToString ("T"), "#A13");
314                         Assert.AreEqual ("2002-02-25 05:25:13Z", t1.ToString ("u"), "#A14");
315                         // FIXME: this test is timezone dependent
316                         // Assert.AreEqual ("Sunday, 24 February 2002 11:25:13", t1.ToString ("U"), "#A15");
317                         Assert.AreEqual ("2002 February", t1.ToString ("y"), "#A16");
318                         Assert.AreEqual ("2002 February", t1.ToString ("Y"), "#A17");
319                         Assert.AreEqual ("02/25/2002 05:25:13", t1.ToString (""), "#A18");
320
321                         // Custom patterns
322                         Assert.AreEqual ("25", t1.ToString ("%d"), "#B1");
323                         Assert.AreEqual ("25", t1.ToString ("dd"), "#B2");
324                         Assert.AreEqual ("Mon", t1.ToString ("ddd"), "#B3");
325                         Assert.AreEqual ("Monday", t1.ToString ("dddd"), "#B4");
326                         Assert.AreEqual ("2", t1.ToString ("%M"), "#B5");
327                         Assert.AreEqual ("02", t1.ToString ("MM"), "#B6");
328                         Assert.AreEqual ("Feb", t1.ToString ("MMM"), "#B7");
329                         Assert.AreEqual ("February", t1.ToString ("MMMM"), "#B8");
330                         Assert.AreEqual ("2", t1.ToString ("%y"), "#B9");
331                         Assert.AreEqual ("02", t1.ToString ("yy"), "#B10");
332                         Assert.AreEqual ("2002", t1.ToString ("yyyy"), "#B11");
333                         Assert.AreEqual ("5", t1.ToString ("%h"), "#B12");
334                         Assert.AreEqual ("05", t1.ToString ("hh"), "#B13");
335                         Assert.AreEqual ("3", t2.ToString ("%h"), "#B14");
336                         Assert.AreEqual ("03", t2.ToString ("hh"), "#B15");
337                         Assert.AreEqual ("15", t2.ToString ("%H"), "#B16");
338                         Assert.AreEqual ("15", t2.ToString ("HH"), "#B17");
339                         Assert.AreEqual ("25", t2.ToString ("%m"), "#B18");
340                         Assert.AreEqual ("25", t2.ToString ("mm"), "#B19");
341                         Assert.AreEqual ("13", t2.ToString ("%s"), "#B20");
342                         Assert.AreEqual ("13", t2.ToString ("ss"), "#B21");
343                         Assert.AreEqual ("A", t1.ToString ("%t"), "#B22");
344                         Assert.AreEqual ("P", t2.ToString ("%t"), "#B23");
345                         Assert.AreEqual ("AM", t1.ToString ("tt"), "#B24");
346                         Assert.AreEqual ("PM", t2.ToString ("tt"), "#B25");
347                         long offset = TimeZone.CurrentTimeZone.GetUtcOffset(t1).Ticks / 36000000000;
348                         // Must specify '+0' for GMT
349                         Assert.AreEqual (offset.ToString ("+#;-#;+0"), t1.ToString ("%z"), "#B26");
350                         Assert.AreEqual (offset.ToString ("+00;-00;+00"), t1.ToString ("zz"), "#B28");
351                         // This does not work in, eg banglore, because their timezone has an offset of
352                         // +05:30
353                         //Assert.AreEqual (offset.ToString("+00;-00;00") + ":00", t1.ToString ("zzz"), "#B28");
354                         Assert.AreEqual (" : ", t1.ToString (" : "), "#B29");
355                         Assert.AreEqual (" / ", t1.ToString (" / "), "#B30");
356                         Assert.AreEqual (" yyy ", t1.ToString (" 'yyy' "), "#B31");
357                         Assert.AreEqual (" d", t1.ToString (" \\d"), "#B32");
358                         Assert.AreEqual ("2002", t1.ToString ("yyy"), "#B33");
359                         Assert.AreEqual ("0002002", t1.ToString ("yyyyyyy"), "#B34");
360                         Assert.AreEqual ("999", t3.ToString ("yyy"), "#B33");
361                         Assert.AreEqual ("0999", t3.ToString ("yyyy"), "#B33");
362                 }
363
364                 [Test]
365                 public void TestToStringGenitive ()
366                 {
367                         DateTime dt = new DateTime (2010, 1, 2, 3, 4, 5);
368                         var dtf = new CultureInfo ("cs-cz").DateTimeFormat;
369
370                         Assert.AreEqual ("2 ledna", dt.ToString ("d MMMM", dtf), "#A1");
371                         Assert.AreEqual ("2. ledna", dt.ToString ("d. MMMM", dtf), "#A2");
372                         Assert.AreEqual ("leden", dt.ToString ("MMMM", dtf), "#A4");
373                         Assert.AreEqual ("leden", dt.ToString ("MMMMMMM", dtf), "#A5");
374                 }
375
376                 [Test]
377                 public void ParseExact_Format_Empty ()
378                 {
379                         try {
380                                 DateTime.ParseExact ("2002-02-25 04:25:13Z", string.Empty, null);
381                                 Assert.Fail ("#A1");
382                         } catch (FormatException ex) {
383                                 // Format specifier was invalid
384                                 Assert.AreEqual (typeof (FormatException), ex.GetType (), "#B2");
385                                 Assert.IsNull (ex.InnerException, "#B3");
386                                 Assert.IsNotNull (ex.Message, "#B4");
387                         }
388
389                         try {
390                                 DateTime.ParseExact ("2002-02-25 04:25:13Z", string.Empty, null,
391                                         DateTimeStyles.None);
392                                 Assert.Fail ("#B1");
393                         } catch (FormatException ex) {
394                                 // Format specifier was invalid
395                                 Assert.AreEqual (typeof (FormatException), ex.GetType (), "#B2");
396                                 Assert.IsNull (ex.InnerException, "#B3");
397                                 Assert.IsNotNull (ex.Message, "#B4");
398                         }
399                 }
400
401                 [Test]
402                 public void ParseExact_Format_Null ()
403                 {
404                         try {
405                                 DateTime.ParseExact ("2002-02-25 04:25:13Z", (string) null, null);
406                                 Assert.Fail ("#A1");
407                         } catch (ArgumentNullException ex) {
408                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
409                                 Assert.IsNull (ex.InnerException, "#A3");
410                                 Assert.IsNotNull (ex.Message, "#A4");
411                                 Assert.IsNotNull (ex.ParamName, "#A5");
412                                 Assert.AreEqual ("format", ex.ParamName, "#A6");
413                         }
414
415                         try {
416                                 DateTime.ParseExact ("2002-02-25 04:25:13Z", (string) null, null,
417                                         DateTimeStyles.None);
418                                 Assert.Fail ("#B1");
419                         } catch (ArgumentNullException ex) {
420                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
421                                 Assert.IsNull (ex.InnerException, "#B3");
422                                 Assert.IsNotNull (ex.Message, "#B4");
423                                 Assert.IsNotNull (ex.ParamName, "#B5");
424                                 Assert.AreEqual ("format", ex.ParamName, "#B6");
425                         }
426                 }
427
428                 [Test]
429                 public void ParseExact_Formats_Empty ()
430                 {
431                         try {
432                                 DateTime.ParseExact ("2002-02-25 04:25:13Z", new string [0],
433                                         null, DateTimeStyles.None);
434                                 Assert.Fail ("#A1");
435                         } catch (FormatException ex) {
436                                 // Format specifier was invalid
437                                 Assert.AreEqual (typeof (FormatException), ex.GetType (), "#A2");
438                                 Assert.IsNull (ex.InnerException, "#A3");
439                                 Assert.IsNotNull (ex.Message, "#A4");
440                         }
441
442                         string [] formats = new string [] { "G", string.Empty, "d" };
443                         try {
444                                 DateTime.ParseExact ("2002-02-25 04:25:13Z", formats, null,
445                                         DateTimeStyles.None);
446                                 Assert.Fail ("#B1");
447                         } catch (FormatException ex) {
448                                 // Format specifier was invalid
449                                 Assert.AreEqual (typeof (FormatException), ex.GetType (), "#B2");
450                                 Assert.IsNull (ex.InnerException, "#B3");
451                                 Assert.IsNotNull (ex.Message, "#B4");
452                         }
453                 }
454
455                 [Test]
456                 public void ParseExact_Formats_Null ()
457                 {
458                         try {
459                                 DateTime.ParseExact ("2002-02-25 04:25:13Z", (string []) null,
460                                         null, DateTimeStyles.None);
461                                 Assert.Fail ("#A1");
462                         } catch (ArgumentNullException ex) {
463                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
464                                 Assert.IsNull (ex.InnerException, "#A3");
465                                 Assert.IsNotNull (ex.Message, "#A4");
466                                 Assert.IsNotNull (ex.ParamName, "#A5");
467                                 Assert.AreEqual ("formats", ex.ParamName, "#A6");
468                         }
469
470                         string [] formats = new string [] { "G", null, "d" };
471                         try {
472                                 DateTime.ParseExact ("2002-02-25 04:25:13Z", formats, null,
473                                         DateTimeStyles.None);
474                                 Assert.Fail ("#B1");
475                         } catch (FormatException ex) {
476                                 // Format specifier was invalid
477                                 Assert.AreEqual (typeof (FormatException), ex.GetType (), "#B2");
478                                 Assert.IsNull (ex.InnerException, "#B3");
479                                 Assert.IsNotNull (ex.Message, "#B4");
480                         }
481                 }
482
483                 [Test]
484                 public void ParseExact_String_Empty ()
485                 {
486                         try {
487                                 DateTime.ParseExact (string.Empty, "G", null);
488                                 Assert.Fail ("#A1");
489                         } catch (FormatException ex) {
490                                 // Format specifier was invalid
491                                 Assert.AreEqual (typeof (FormatException), ex.GetType (), "#A2");
492                                 Assert.IsNull (ex.InnerException, "#A3");
493                                 Assert.IsNotNull (ex.Message, "#A4");
494                         }
495
496                         try {
497                                 DateTime.ParseExact (string.Empty, "G", null, DateTimeStyles.None);
498                                 Assert.Fail ("#B1");
499                         } catch (FormatException ex) {
500                                 // Format specifier was invalid
501                                 Assert.AreEqual (typeof (FormatException), ex.GetType (), "#B2");
502                                 Assert.IsNull (ex.InnerException, "#B3");
503                                 Assert.IsNotNull (ex.Message, "#B4");
504                         }
505
506                         try {
507                                 DateTime.ParseExact (string.Empty, new string [] { "G" }, null,
508                                         DateTimeStyles.None);
509                                 Assert.Fail ("#C1");
510                         } catch (FormatException ex) {
511                                 // Format specifier was invalid
512                                 Assert.AreEqual (typeof (FormatException), ex.GetType (), "#C2");
513                                 Assert.IsNull (ex.InnerException, "#C3");
514                                 Assert.IsNotNull (ex.Message, "#C4");
515                         }
516                 }
517
518                 [Test]
519                 public void ParseExact_String_Null ()
520                 {
521                         try {
522                                 DateTime.ParseExact ((string) null, "G", null);
523                                 Assert.Fail ("#A1");
524                         } catch (ArgumentNullException ex) {
525                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
526                                 Assert.IsNull (ex.InnerException, "#A3");
527                                 Assert.IsNotNull (ex.Message, "#A4");
528                                 Assert.IsNotNull (ex.ParamName, "#A5");
529                                 Assert.AreEqual ("s", ex.ParamName, "#A6");
530                         }
531
532                         try {
533                                 DateTime.ParseExact ((string) null, "G", null, DateTimeStyles.None);
534                                 Assert.Fail ("#B1");
535                         } catch (ArgumentNullException ex) {
536                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
537                                 Assert.IsNull (ex.InnerException, "#B3");
538                                 Assert.IsNotNull (ex.Message, "#B4");
539                                 Assert.IsNotNull (ex.ParamName, "#B5");
540                                 Assert.AreEqual ("s", ex.ParamName, "#B6");
541                         }
542
543                         try {
544                                 DateTime.ParseExact ((string) null, new string [] { "G" }, null,
545                                         DateTimeStyles.None);
546                                 Assert.Fail ("#C1");
547                         } catch (ArgumentNullException ex) {
548                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#C2");
549                                 Assert.IsNull (ex.InnerException, "#C3");
550                                 Assert.IsNotNull (ex.Message, "#C4");
551                                 Assert.IsNotNull (ex.ParamName, "#C5");
552                                 Assert.AreEqual ("s", ex.ParamName, "#C6");
553                         }
554                 }
555
556                 [Test]
557                 public void TestParseExact3 ()
558                 {
559                         DateTime t1 = DateTime.ParseExact ("2002-02-25 04:25:13Z", "u", null);
560                         Assert.AreEqual (2002, t1.Year, "#1");
561                         Assert.AreEqual (02, t1.Month, "#2");
562                         Assert.AreEqual (25, t1.Day, "#3");
563                         Assert.AreEqual (04, t1.Hour, "#4");
564                         Assert.AreEqual (25, t1.Minute, "#5");
565                         Assert.AreEqual (13, t1.Second, "#6");
566                 }
567
568                 [Test]
569                 public void TestParseExact4 ()
570                 {
571                         // Checks 24hours format used together with the AM/PM designator
572                         string s = "6/28/2004 13:00:00 AM";
573                         string f = "M/d/yyyy HH':'mm':'ss tt";
574                         try {
575                                 DateTime.ParseExact (s, f, CultureInfo.InvariantCulture);
576                                 Assert.Fail ("#1");
577                         } catch (FormatException) {
578                         }
579
580                         s = "6/28/2004 04:00:00 AM";
581                         DateTime.ParseExact (s, f, CultureInfo.InvariantCulture);
582
583                         s = "6/28/2004 06:00:00 PM";
584                         try {
585                                 DateTime.ParseExact (s, f, CultureInfo.InvariantCulture);
586                                 Assert.Fail ("#2");
587                         } catch (FormatException) {
588                         }
589
590                         s = "6/28/2004 17:00:00 PM";
591                         DateTime.ParseExact (s, f, CultureInfo.InvariantCulture);
592                 }
593                 
594                 [Test]
595                 public void TestParseExact4_2 ()
596                 {
597                         // bug #63137
598                         DateTime.ParseExact ("Wed, 12 May 2004 20:51:09 +0200",
599                                 @"ddd, d MMM yyyy H:m:s zzz",
600                                 CultureInfo.CreateSpecificCulture("en-us"),
601                                 DateTimeStyles.AllowInnerWhite);
602                 }
603
604                 [Test]
605                 public void TestParseExact5 ()
606                 {
607                         DateTime dt = DateTime.ParseExact ("Wed, 12 May 2004 20:51:09 -02:30",
608                                                         @"ddd, d MMM yyyy H:m:s zzz",
609                                                         CultureInfo.CreateSpecificCulture("en-us"),
610                                                         DateTimeStyles.AllowInnerWhite);
611                         dt = dt.ToUniversalTime ();
612                         Assert.AreEqual (23, dt.Hour, "Hour");
613                         Assert.AreEqual (21, dt.Minute, "Minute");
614                 }
615
616                 [Test]
617                 public void TestParseExactMiliseconds ()
618                 {
619                         string s = "1984-09-17T09:00:00.6Z";
620                         DateTime dt = DateTime.ParseExact (s, "yyyy-MM-dd'T'HH:mm:ss.FFF'Z'", CultureInfo.InvariantCulture);
621                         Assert.AreEqual (new DateTime (1984, 9, 17, 9, 0, 0, 600), dt, "#1");
622
623                         s = "1984-09-17T09:00:00Z";
624                         dt = DateTime.ParseExact (s, "yyyy-MM-dd'T'HH:mm:ss.FFF'Z'", CultureInfo.InvariantCulture);
625                         Assert.AreEqual (new DateTime (1984, 9, 17, 9, 0, 0, 0), dt, "#2");
626
627                         s = "1984-09-17T09:00:00Z";
628                         dt = DateTime.ParseExact (s, "yyyy-MM-dd'T'HH:mm:ssFFF'Z'", CultureInfo.InvariantCulture);
629                         Assert.AreEqual (new DateTime (1984, 9, 17, 9, 0, 0, 0), dt, "#3");
630                 }
631
632                 [Test]
633                 public void TestParseExact ()
634                 {
635                         // Standard patterns
636                         DateTime t1 = DateTime.ParseExact ("02/25/2002", "d", null);
637                         Assert.AreEqual (myTicks [0], t1.Ticks, "#A1");
638                         t1 = DateTime.ParseExact ("Monday, 25 February 2002", "D", null);
639                         Assert.AreEqual (myTicks [0], t1.Ticks, "#A2");
640                         t1 = DateTime.ParseExact ("Monday, 25 February 2002 05:25", "f", null);
641                         Assert.AreEqual (myTicks [3], t1.Ticks, "#A3");
642                         t1 = DateTime.ParseExact ("Monday, 25 February 2002 05:25:13", "F", null);
643                         Assert.AreEqual (myTicks [4], t1.Ticks, "#A4");
644                         t1 = DateTime.ParseExact ("02/25/2002 05:25", "g", null);
645                         Assert.AreEqual (myTicks [3], t1.Ticks, "#A5");
646                         t1 = DateTime.ParseExact ("02/25/2002 05:25:13", "G", null);
647                         Assert.AreEqual (myTicks [4], t1.Ticks, "#A6");
648                         t1 = DateTime.ParseExact ("Monday, 25 February 2002 04:25:13", "U", null);
649                         t1 = TimeZone.CurrentTimeZone.ToUniversalTime(t1);
650                         Assert.AreEqual (2002, t1.Year, "#A7");
651                         Assert.AreEqual (02, t1.Month, "#A8");
652                         Assert.AreEqual (25, t1.Day, "#A9");
653                         Assert.AreEqual (04, t1.Hour, "#A10");
654                         Assert.AreEqual (25, t1.Minute, "#A11");
655                         Assert.AreEqual (13, t1.Second, "#A12");
656                         t1 = DateTime.ParseExact ("Monday, 25 February 2002 04:25:13", "U", null);
657                         Assert.AreEqual ("Monday, 25 February 2002 04:25:13", t1.ToString ("U"), "#A13");
658
659                         DateTime t2 = new DateTime (DateTime.Today.Year, 2, 25);
660                         t1 = DateTime.ParseExact ("February 25", "m", null);
661                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#B1");
662
663                         t2 = new DateTime (DateTime.Today.Year, 2, 25);
664                         t1 = DateTime.ParseExact ("February 25", "M", null);
665                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#B2");
666
667                         t1 = DateTime.ParseExact ("Mon, 25 Feb 2002 04:25:13 GMT", "r", null);
668                         Assert.AreEqual (2002, t1.Year, "#C1");
669                         Assert.AreEqual (02, t1.Month, "#C2");
670                         Assert.AreEqual (25, t1.Day, "#C3");
671                         Assert.AreEqual (04, t1.Hour, "#C4");
672                         Assert.AreEqual (25, t1.Minute, "#C5");
673                         Assert.AreEqual (13, t1.Second, "#C6");
674
675                         t1 = DateTime.ParseExact ("Mon, 25 Feb 2002 04:25:13 GMT", "R", null);
676                         Assert.AreEqual (2002, t1.Year, "#D1");
677                         Assert.AreEqual (02, t1.Month, "#D2");
678                         Assert.AreEqual (25, t1.Day, "#D3");
679                         Assert.AreEqual (04, t1.Hour, "#D4");
680                         Assert.AreEqual (25, t1.Minute, "#D5");
681                         Assert.AreEqual (13, t1.Second, "#D6");
682
683                         t1 = DateTime.ParseExact ("2002-02-25T05:25:13", "s", null);
684                         Assert.AreEqual (myTicks [4], t1.Ticks, "#E1");
685
686                         t2 = DateTime.Today + new TimeSpan (5,25,0);
687                         t1 = DateTime.ParseExact ("05:25", "t", null);
688                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#E2");
689
690                         t2 = DateTime.Today + new TimeSpan (5,25,13);
691                         t1 = DateTime.ParseExact ("05:25:13", "T", null);
692                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#E3");
693
694                         t2 = new DateTime (2002, 2, 1);
695                         t1 = DateTime.ParseExact ("2002 February", "y", null);
696                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#E4");
697
698                         t2 = new DateTime (2002, 2, 1);
699                         t1 = DateTime.ParseExact ("2002 February", "Y", null);
700                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#E5");
701
702                         // Custom patterns
703                         t2 = new DateTime (DateTime.Now.Year, 1, 25);
704                         t1 = DateTime.ParseExact ("25", "%d", null);
705                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#F1");
706                         t1 = DateTime.ParseExact ("25", "dd", null);
707                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#F2");
708
709                         t2 = new DateTime (DateTime.Today.Year, 2, 1);
710                         t1 = DateTime.ParseExact ("2", "%M", null);
711                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#G1");
712                         t1 = DateTime.ParseExact ("02", "MM", null);
713                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#G2");
714                         t1 = DateTime.ParseExact ("Feb", "MMM", null);
715                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#G3");
716                         t1 = DateTime.ParseExact ("February", "MMMM", null);
717                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#G4");
718
719                         t2 = new DateTime (2005, 1, 1);
720                         t1 = DateTime.ParseExact ("5", "%y", null);
721                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#G5");
722                         t1 = DateTime.ParseExact ("05", "yy", null);
723                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#G6");
724                         t1 = DateTime.ParseExact ("2005", "yyyy", null);
725                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#G7");
726
727                         t2 = DateTime.Today + new TimeSpan (5, 0, 0);
728                         t1 = DateTime.ParseExact ("5A", "ht", null);
729                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#G8");
730                         t1 = DateTime.ParseExact ("05A", "hht", null);
731                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#G9");
732
733                         t2 = DateTime.Today + new TimeSpan (15, 0, 0);
734                         t1 = DateTime.ParseExact ("3P", "ht", null);
735                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#G10");
736                         t1 = DateTime.ParseExact ("03P", "hht", null);
737                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#G11");
738
739                         t2 = DateTime.Today + new TimeSpan (5, 0, 0);
740                         t1 = DateTime.ParseExact ("5", "%H", null);
741                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#G12");
742
743                         t2 = DateTime.Today + new TimeSpan (15, 0, 0);
744                         t1 = DateTime.ParseExact ("15", "%H", null);
745                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#G13");
746                         t1 = DateTime.ParseExact ("15", "HH", null);
747                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#G14");
748
749                         // Time zones
750 #if false
751                         // Fails durring DST for msft and mono
752                         t2 = DateTime.Today + new TimeSpan (17, 18, 0);
753                         t1 = DateTime.ParseExact ("11:18AM -5", "h:mmtt z", null);
754                         t1 = TimeZone.CurrentTimeZone.ToUniversalTime(t1);
755                         if (!TimeZone.CurrentTimeZone.IsDaylightSavingTime(t1))
756                                 t1 += new TimeSpan(1, 0, 0);
757                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#H1");
758                         
759                         t1 = DateTime.ParseExact ("11:18AM -05:00", "h:mmtt zzz", null);
760                         t1 = TimeZone.CurrentTimeZone.ToUniversalTime(t1);
761                         if (!TimeZone.CurrentTimeZone.IsDaylightSavingTime(t1))
762                                 t1 += new TimeSpan(1, 0, 0);
763                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#H2");
764
765                         t1 = DateTime.ParseExact ("7:18PM +03", "h:mmtt zz", null);
766                         t1 = TimeZone.CurrentTimeZone.ToUniversalTime(t1);
767                         if (!TimeZone.CurrentTimeZone.IsDaylightSavingTime(t1))
768                                 t1 += new TimeSpan(1, 0, 0);
769                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#H3");
770
771                         t1 = DateTime.ParseExact ("7:48PM +03:30", "h:mmtt zzz", null);
772                         t1 = TimeZone.CurrentTimeZone.ToUniversalTime(t1);
773                         if (!TimeZone.CurrentTimeZone.IsDaylightSavingTime(t1))
774                                 t1 += new TimeSpan(1, 0, 0);
775                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#H4");
776 #endif
777
778                         // Options
779                         t2 = DateTime.Today + new TimeSpan (16, 18, 0);
780                         t1 = DateTime.ParseExact ("11:18AM -5", "h:mmtt z",
781                                                   null, DateTimeStyles.AdjustToUniversal);
782                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#I1");
783
784                         t1 = DateTime.ParseExact ("Monday, 25 February 2002 05:25:13", "F",
785                                                   null, DateTimeStyles.AdjustToUniversal);
786                         Assert.AreEqual (myTicks [4], t1.Ticks, "#I2");
787                         t1 = DateTime.ParseExact ("Monday, 25 February 2002 05:25:13",
788                                                   "dddd, dd MMMM yyyy HH:mm:ss",
789                                                   null, DateTimeStyles.AdjustToUniversal);
790                         Assert.AreEqual (myTicks [4], t1.Ticks, "#I3");
791
792                         t1 = DateTime.ParseExact ("02/25/2002", "d", null,
793                                                   DateTimeStyles.AllowWhiteSpaces);
794                         Assert.AreEqual (myTicks [0], t1.Ticks, "#I4");
795
796                         t1 = DateTime.ParseExact ("    02/25/2002", "d", null,
797                                                   DateTimeStyles.AllowLeadingWhite);
798                         Assert.AreEqual (myTicks [0], t1.Ticks, "#I5");
799
800                         t1 = DateTime.ParseExact ("02/25/2002    ", "d", null,
801                                                   DateTimeStyles.AllowTrailingWhite);
802                         Assert.AreEqual (myTicks [0], t1.Ticks, "#I6");
803
804                         t1 = DateTime.ParseExact ("  02 / 25 / 2002    ", "d", null,
805                                                   DateTimeStyles.AllowWhiteSpaces);
806                         Assert.AreEqual (myTicks [0], t1.Ticks, "#I7");
807
808                         // Multi Custom Patterns
809                         string rfc1123_date = "r";
810                         string rfc850_date = "dddd, dd'-'MMM'-'yy HH':'mm':'ss 'GMT'";
811                         string asctime_date = "ddd MMM d HH':'mm':'ss yyyy";
812                         string [] formats = new string [] {rfc1123_date, rfc850_date, asctime_date};
813                         CultureInfo enUS = new CultureInfo("en-US", false);
814                         t1 = DateTime.ParseExact ("Sun, 06 Nov 1994 08:49:37 GMT", formats[0], enUS, 
815                                                 DateTimeStyles.AllowWhiteSpaces);
816                         Assert.AreEqual (myTicks [6], t1.Ticks, "#J1");
817                         t1 = DateTime.ParseExact ("Sunday, 06-Nov-94 08:49:37 GMT", formats[1], enUS, 
818                                                 DateTimeStyles.AllowWhiteSpaces);
819                         Assert.AreEqual (myTicks [6], t1.Ticks, "#J2");
820                         t1 = DateTime.ParseExact ("Sun Nov  6 08:49:37 1994", formats[2], enUS, 
821                                                 DateTimeStyles.AllowWhiteSpaces);
822                         Assert.AreEqual (myTicks [6], t1.Ticks, "#J3");
823                         t1 = DateTime.ParseExact ("Sun, 06 Nov 1994 08:49:37 GMT", formats, enUS, 
824                                                 DateTimeStyles.AllowWhiteSpaces);
825                         Assert.AreEqual (myTicks [6], t1.Ticks, "#J4");
826                         t1 = DateTime.ParseExact ("Sunday, 06-Nov-94 08:49:37 GMT", formats, enUS, 
827                                                 DateTimeStyles.AllowWhiteSpaces);
828                         Assert.AreEqual (myTicks [6], t1.Ticks, "#J5");
829                         t1 = DateTime.ParseExact ("Sun Nov  6 08:49:37 1994", formats, enUS, 
830                                                 DateTimeStyles.AllowWhiteSpaces);
831                         Assert.AreEqual (myTicks [6], t1.Ticks, "#J6");
832                         t1 = DateTime.ParseExact ("Monday, 25 February 2002 05:25:13",
833                                                 "ddddddd, dd MMMMMMM yyyy HHHHH:mmmmm:sssss",
834                                                 null, DateTimeStyles.AdjustToUniversal);
835                         Assert.AreEqual (myTicks[4], t1.Ticks, "#J7");
836                 
837                         // Bug 52274
838                         t1 = DateTime.ParseExact ("--12--", "--MM--" , null);
839                         Assert.AreEqual (12, t1.Month, "#K1");
840                         t1=DateTime.ParseExact ("--12-24", "--MM-dd" , null);
841                         Assert.AreEqual (24, t1.Day, "#K2");
842                         Assert.AreEqual (12, t1.Month, "#K3");
843                         t1=DateTime.ParseExact ("---24", "---dd" , null);
844                         Assert.AreEqual (24, t1.Day, "#K4");
845
846                         // Bug 63376
847                         t1 = DateTime.ParseExact ("18Aug2004 12:33:00", "ddMMMyyyy hh:mm:ss", new CultureInfo ("en-US"));
848                         Assert.AreEqual (0, t1.Hour, "hh allows 12, though it's useless");
849
850                         // Bug 74775
851                         DateTime.ParseExact ("Tue, 12 Apr 2005 10:10:04 +0100",
852                                 "Tue, 12 Apr 2005 10:10:04 +0100", enUS);
853                         try {
854                                 DateTime.ParseExact ("Tue, 12 Apr 2005 10:10:04 +00000",
855                                         "ddd, dd MMM yyyy HH':'mm':'ss zzz", enUS);
856                                 Assert.Fail ("#L1");
857                         } catch (FormatException) {
858                         }
859
860                         // Bug #75213 : literal escaping.
861                         t1 = DateTime.ParseExact ("20050707132527Z",
862                                 "yyyyMMddHHmmss\\Z", CultureInfo.InvariantCulture);
863                         Assert.AreEqual (632563395270000000, t1.Ticks, "#L2");
864
865                         // XAttributeTest.CastDateTimeOffsets():#6b
866                         // It is said broken, probably due to timezone difference.
867                         //t1 = DateTime.ParseExact ("2039-10-31T12:34:56.7552+00:00", "yyyy-MM-ddTHH:mm:ss.FFFFFFFzzz",
868                         //                        CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
869                         //Assert.AreEqual (643393064967552000, t1.Ticks, "#M");
870                 }
871
872                 [Test]
873                 public void TestParse2 ()
874                 {
875                         DateTime t1 = DateTime.Parse ("Mon, 25 Feb 2002 04:25:13 GMT");
876                         t1 = TimeZone.CurrentTimeZone.ToUniversalTime(t1);
877                         Assert.AreEqual (4, t1.Hour);
878                 }
879
880                 [Test]
881                 public void TestUtcOffset_Novell710512 ()
882                 {
883                         // test for bug Novell #710512
884                         if (TimeZoneInfo.Local.BaseUtcOffset == TimeSpan.Zero)
885                                 Assert.Ignore("Test doesn't apply with current time zone");
886
887                         var localTime = DateTime.Parse ("Mon, 25 Feb 2002 04:25:13 GMT");
888                         var utcTime = TimeZone.CurrentTimeZone.ToUniversalTime(localTime);
889                         Assert.AreEqual (TimeSpan.Zero, TimeZone.CurrentTimeZone.GetUtcOffset (utcTime));
890                 }
891
892                 [Test]
893                 public void TestParseDateFirst ()
894                 {
895                         // Standard patterns
896                         CultureInfo USCultureInfo = new CultureInfo("en-US");
897                         DateTime t1 = DateTime.Parse ("02/25/2002", USCultureInfo);
898                         Assert.AreEqual (myTicks [0], t1.Ticks, "#A1");
899                         t1 = DateTime.Parse ("2002-02-25", USCultureInfo);
900                         Assert.AreEqual (myTicks [0], t1.Ticks, "#A2");
901                         t1 = DateTime.Parse ("Monday, 25 February 2002");
902                         Assert.AreEqual (myTicks [0], t1.Ticks, "#A3");
903                         t1 = DateTime.Parse ("Monday, 25 February 2002 05:25");
904                         Assert.AreEqual (myTicks [3], t1.Ticks, "#A4");
905                         t1 = DateTime.Parse ("Monday, 25 February 2002 05:25:13");
906                         Assert.AreEqual (myTicks [4], t1.Ticks, "#A5");
907                         t1 = DateTime.Parse ("02/25/2002 05:25", USCultureInfo);
908                         Assert.AreEqual (myTicks [3], t1.Ticks, "#A6");
909                         t1 = DateTime.Parse ("02/25/2002 05:25:13", USCultureInfo);
910                         Assert.AreEqual (myTicks [4], t1.Ticks, "#A7");
911                         t1 = DateTime.Parse ("2002-02-25 04:25:13Z");
912                         t1 = TimeZone.CurrentTimeZone.ToUniversalTime(t1);
913                         Assert.AreEqual (2002, t1.Year, "#A8");
914                         Assert.AreEqual (02, t1.Month, "#A9");
915                         Assert.AreEqual (25, t1.Day, "#A10");
916                         Assert.AreEqual (04, t1.Hour, "#A11");
917                         Assert.AreEqual (25, t1.Minute, "#A12");
918                         Assert.AreEqual (13, t1.Second, "#A13");
919                         t1 = DateTime.Parse ("Mon,02/25/2002", USCultureInfo);
920                         Assert.AreEqual (myTicks [0], t1.Ticks, "#A14");
921                         DateTime t2 = new DateTime (1999, 1, 2, 0, 3, 4);
922                         t1 = DateTime.Parse (t2.ToLongTimeString ());
923                         Assert.AreEqual (0, t1.Hour, "#A14");
924
925                         // parsed as UTC string
926                         t1 = DateTime.Parse ("Mon, 25 Feb 2002 04:25:13 GMT");
927                         t1 = TimeZone.CurrentTimeZone.ToUniversalTime (t1);
928                         Assert.AreEqual (2002, t1.Year, "#C1");
929                         Assert.AreEqual (02, t1.Month, "#C2");
930                         Assert.AreEqual (25, t1.Day, "#C3");
931                         Assert.AreEqual (4, t1.Hour, "#C4");
932                         Assert.AreEqual (25, t1.Minute, "#C5");
933                         Assert.AreEqual (13, t1.Second, "#C6");
934
935                         // Some date 'T' time formats
936                         t1 = DateTime.Parse ("2002-02-25T05:25");
937                         Assert.AreEqual (myTicks [3], t1.Ticks, "#D1");
938
939                         t1 = DateTime.Parse ("2002-02-25T05:25:13");
940                         Assert.AreEqual (myTicks [4], t1.Ticks, "#D1");
941                         t1 = DateTime.Parse ("2002-02-25T05:25:13.008");
942                         Assert.AreEqual (myTicks [2], t1.Ticks, "#D1");
943                         t1 = DateTime.Parse ("02-2002-25T05:25:13");
944                         Assert.AreEqual (myTicks [4], t1.Ticks, "#D1");
945
946                         // Day month
947                         t2 = new DateTime (DateTime.Today.Year, 2, 25);
948                         t1 = DateTime.Parse ("February 25", USCultureInfo);
949                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#B1");
950
951                         t2 = new DateTime (DateTime.Today.Year, 2, 8);
952                         t1 = DateTime.Parse ("February 08", USCultureInfo);
953                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#B2");
954
955                         t2 = new DateTime (DateTime.Today.Year, 2, 8);
956                         t1 = DateTime.Parse ("February 8", USCultureInfo);
957                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#D6");
958
959                         // Month year
960                         t2 = new DateTime (2002, 2, 1);
961                         t1 = DateTime.Parse ("2002 February");
962                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#D4");
963
964                         t2 = new DateTime (2002, 2, 1);
965                         t1 = DateTime.Parse ("2002 February", new CultureInfo ("ja-JP"));
966                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#D5");
967
968                         // bug #72132
969                         t2 = new DateTime (2002, 2, 25, 5, 25, 22);
970                         t1 = DateTime.Parse ("Monday, 25 February 2002 05:25:22",
971                                 new CultureInfo ("hi-IN"));
972                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#D7");
973                         t2 = new DateTime (2002, 2, 25, 5, 25, 0);
974                         t1 = DateTime.Parse ("Monday, 25 February 2002 05:25",
975                                 new CultureInfo ("hi-IN"));
976                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#D8");
977
978                         // MM-yyyy-dd + different time formats
979                         t1 = DateTime.Parse ("02-2002-25 05:25", USCultureInfo);
980                         Assert.AreEqual (myTicks[3], t1.Ticks, "#E1");
981                         t1 = DateTime.Parse ("02-2002-25 05:25:13", USCultureInfo);
982                         Assert.AreEqual (myTicks[4], t1.Ticks, "#E1");
983                         t1 = DateTime.Parse ("02-2002-25 05:25:13 Mon", USCultureInfo);
984                         Assert.AreEqual (myTicks[4], t1.Ticks, "#E2");
985                         t1 = DateTime.Parse ("02-2002-25 05:25:13 Monday", USCultureInfo);
986                         Assert.AreEqual (myTicks[4], t1.Ticks, "#E3");
987                         t1 = DateTime.Parse ("02-2002-25 05:25:13.008", USCultureInfo);
988                         Assert.AreEqual (myTicks[2], t1.Ticks, "#E4");
989
990                         // Formats with timezone
991                         long offset = TimeZone.CurrentTimeZone.GetUtcOffset(t1).Ticks;
992                         long hourTicks = 36000000000L;
993                         long halfHourTicks = hourTicks / 2;
994                         t1 = DateTime.Parse ("02-2002-25 05:25+01", USCultureInfo);
995                         Assert.AreEqual (myTicks[3], t1.Ticks + hourTicks - offset, "#F1");
996                         t1 = DateTime.Parse ("02-2002-25 05:25-01", USCultureInfo);
997                         Assert.AreEqual (myTicks[3], t1.Ticks - hourTicks - offset, "#F2");
998                         t1 = DateTime.Parse ("02-2002-25 05:25+00:30", USCultureInfo);
999                         Assert.AreEqual (myTicks[3], t1.Ticks + hourTicks/2 - offset, "#F3");
1000                         t1 = DateTime.Parse ("02-2002-25 05:25:13+02", USCultureInfo);
1001                         Assert.AreEqual (myTicks[4], t1.Ticks + 2*hourTicks - offset, "#F4");
1002
1003                         // NET 1.0 doesn't accept second fractions and time zone.
1004                         t1 = DateTime.Parse ("2002-02-25 05:25:13.008-02");
1005                         Assert.AreEqual (myTicks[2], t1.Ticks - 2*hourTicks - offset, "#F5");
1006                         // NET 1.0 doesn't parse well time zone with AM afterwards.
1007                         t1 = DateTime.Parse ("02-25-2002 05:25:13-02 AM", USCultureInfo);
1008                         Assert.AreEqual (myTicks[4], t1.Ticks - 2*hourTicks - offset, "#F6");
1009                         t1 = DateTime.Parse ("25 Feb 2002 05:25:13-02 AM", USCultureInfo);
1010                         Assert.AreEqual (myTicks[4], t1.Ticks - 2*hourTicks - offset, "#F6");
1011                 }
1012
1013                 [Test]
1014                 public void TestParseTimeFirst ()
1015                 {
1016                         CultureInfo USCultureInfo = new CultureInfo("en-US");
1017
1018                         // Hour only patterns
1019                         DateTime t2 = DateTime.Today + new TimeSpan (5,25,0);
1020                         DateTime t1 = DateTime.Parse ("05:25");
1021                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#C1");
1022                         t2 = DateTime.Today + new TimeSpan (5,25,13);
1023                         t1 = DateTime.Parse ("05:25:13");
1024                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#B2");
1025
1026                         // Test with different date formats
1027                         t1 = DateTime.Parse ("05:25 02/25/2002", USCultureInfo);
1028                         Assert.AreEqual (myTicks[3], t1.Ticks, "#B1");
1029                         t1 = DateTime.Parse ("05:25:13 2002-02-25");
1030                         Assert.AreEqual (myTicks[4], t1.Ticks, "#B2");
1031                         t1 = DateTime.Parse ("05:25:13.008 02-2002-25");
1032                         Assert.AreEqual (myTicks[2], t1.Ticks, "#B3");
1033                         t1 = DateTime.Parse ("05:25:13.008 Feb 25 2002");
1034                         Assert.AreEqual (myTicks[2], t1.Ticks, "#B4");
1035                         t1 = DateTime.Parse ("05:25:13.008 25 Feb 2002");
1036                         Assert.AreEqual (myTicks[2], t1.Ticks, "#B5");
1037
1038                         // Add AM and day of the week
1039                         t1 = DateTime.Parse ("AM 05:25:13 2002-02-25");
1040                         Assert.AreEqual (myTicks[4], t1.Ticks, "#C1");
1041                         t1 = DateTime.Parse ("Monday05:25 02/25/2002", USCultureInfo);
1042                         Assert.AreEqual (myTicks[3], t1.Ticks, "#C2");
1043                         t1 = DateTime.Parse ("Mon 05:25 AM 02/25/2002", USCultureInfo);
1044                         Assert.AreEqual (myTicks[3], t1.Ticks, "#C3");
1045                         t1 = DateTime.Parse ("AM 05:25 Monday, 02/25/2002", USCultureInfo);
1046                         Assert.AreEqual (myTicks[3], t1.Ticks, "#C4");
1047                         t1 = DateTime.Parse ("05:25 02/25/2002 Monday", USCultureInfo);
1048                         Assert.AreEqual (myTicks[3], t1.Ticks, "#C5");
1049                         t1 = DateTime.Parse ("PM 03:25:13.008 02-2002-25");
1050                         Assert.AreEqual (myTicks[1], t1.Ticks, "#C6");
1051
1052                         // ASP.NET QuickStarts
1053                         t2 = new DateTime (2002, 10, 7, 15, 6, 0);
1054                         t1 = DateTime.Parse ("3:06 PM 10/7/2002", USCultureInfo);
1055                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#D1");
1056                         t2 = new DateTime (2002, 10, 7, 15, 6, 0);
1057                         t1 = DateTime.Parse ("3:06 pm 10/7/2002", USCultureInfo);
1058                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#D2");
1059                         t2 = new DateTime (2002, 10, 7, 3, 6, 0);
1060                         t1 = DateTime.Parse ("3:06 AM 10/7/2002", USCultureInfo);
1061                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#D3");
1062                         t2 = new DateTime (2002, 10, 7, 3, 6, 0);
1063                         t1 = DateTime.Parse ("3:06 am 10/7/2002", USCultureInfo);
1064                         Assert.AreEqual (t2.Ticks, t1.Ticks, "#D4");
1065                 }
1066
1067                 [Test]
1068                 public void TestParseWithDifferentShortDatePatterns ()
1069                 {
1070                         CultureInfo cultureInfo = new CultureInfo("en-US");
1071                         DateTimeFormatInfo dateFormatInfo = cultureInfo.DateTimeFormat;
1072                         DateTime t1 = DateTime.Parse ("02/01/2003", cultureInfo);
1073                         Assert.AreEqual (myTicks[7], t1.Ticks, "#A1");
1074
1075                         // Day, month year behaviour
1076                         dateFormatInfo.ShortDatePattern = "dd/MM/yyyy";
1077                         t1 = DateTime.Parse ("01/02/03", cultureInfo);
1078                         Assert.AreEqual (myTicks[7], t1.Ticks, "#B1");
1079                         t1 = DateTime.Parse ("01/02/2003", cultureInfo);
1080                         Assert.AreEqual (myTicks[7], t1.Ticks, "#B2");
1081                         t1 = DateTime.Parse ("2003/02/01", cultureInfo);
1082                         Assert.AreEqual (myTicks[7], t1.Ticks, "#B3");
1083                         t1 = DateTime.Parse ("01/Feb/03", cultureInfo);
1084                         Assert.AreEqual (myTicks[7], t1.Ticks, "#B4");
1085                         t1 = DateTime.Parse ("Feb/01/03", cultureInfo);
1086                         Assert.AreEqual (myTicks[7], t1.Ticks, "#B5");
1087
1088                         // Month, day year behaviour
1089                         dateFormatInfo.ShortDatePattern = "MM/dd/yyyy";
1090                         t1 = DateTime.Parse ("02/01/03", cultureInfo);
1091                         Assert.AreEqual (myTicks[7], t1.Ticks, "#C1");
1092                         t1 = DateTime.Parse ("02/01/2003", cultureInfo);
1093                         Assert.AreEqual (myTicks[7], t1.Ticks, "#C2");
1094                         t1 = DateTime.Parse ("2003/02/01", cultureInfo);
1095                         Assert.AreEqual (myTicks[7], t1.Ticks, "#C3");
1096                         t1 = DateTime.Parse ("01/Feb/03", cultureInfo);
1097                         Assert.AreEqual (myTicks[7], t1.Ticks, "#C4");
1098                         t1 = DateTime.Parse ("Feb/01/03", cultureInfo);
1099                         Assert.AreEqual (myTicks[7], t1.Ticks, "#C5");
1100
1101                         // Year, month day behaviour
1102                         dateFormatInfo.ShortDatePattern = "yyyy/MM/dd";
1103                         t1 = DateTime.Parse ("03/02/01", cultureInfo);
1104                         Assert.AreEqual (myTicks[7], t1.Ticks, "#D1");
1105                         t1 = DateTime.Parse ("02/01/2003", cultureInfo);
1106                         Assert.AreEqual (myTicks[7], t1.Ticks, "#D2");
1107                         t1 = DateTime.Parse ("2003/02/01", cultureInfo);
1108                         Assert.AreEqual (myTicks[7], t1.Ticks, "#D3");
1109                         t1 = DateTime.Parse ("03/Feb/01", cultureInfo);
1110                         Assert.AreEqual (myTicks[7], t1.Ticks, "#D4");
1111                         t1 = DateTime.Parse ("Feb/03/01", cultureInfo);
1112                         Assert.AreEqual (myTicks[7], t1.Ticks, "#D5");
1113
1114                         // Year, day month behaviour
1115                         // Note that no culture I am aware of has this pattern, and indeed
1116                         dateFormatInfo.ShortDatePattern = "yyyy/dd/MM";
1117                         t1 = DateTime.Parse ("03/01/02", cultureInfo);
1118                         Assert.AreEqual (myTicks[7], t1.Ticks, "#E1");
1119                         t1 = DateTime.Parse ("01/02/2003", cultureInfo);
1120                         Assert.AreEqual (myTicks[7], t1.Ticks, "#E2");
1121
1122                         t1 = DateTime.Parse ("2003/01/02", cultureInfo);
1123                         Assert.AreEqual (myTicks[7], t1.Ticks, "#E3");
1124
1125                         // For some reason the following throws an exception on .Net
1126                         // t1 = DateTime.Parse ("03/Feb/01", cultureInfo);
1127                         // Assert.AreEqual (myTicks[7], t1.Ticks, "#E4");
1128                         // t1 = DateTime.Parse ("03/01/Feb", cultureInfo);
1129                         // Assert.AreEqual (myTicks[7], t1.Ticks, "#E5");
1130                         // t1 = DateTime.Parse ("Feb/01/03", cultureInfo);
1131                         // Assert.AreEqual (myTicks[7], t1.Ticks, "#E6");
1132                 }
1133
1134                 [Test]
1135                 public void TestParseWithDifferentMonthDayPatterns ()
1136                 {
1137                         CultureInfo cultureInfo = new CultureInfo("en-US");
1138                         DateTimeFormatInfo dateFormatInfo = cultureInfo.DateTimeFormat;
1139                         DateTime t1 = DateTime.Parse ("Feb 03", cultureInfo);
1140                         Assert.AreEqual (2, t1.Month, "#A1");
1141                         Assert.AreEqual (3, t1.Day, "#A2");
1142
1143                         // Day month behaviour
1144                         dateFormatInfo.MonthDayPattern = "dd/MM";
1145
1146                         t1 = DateTime.Parse ("Feb 03", cultureInfo);
1147                         Assert.AreEqual (2, t1.Month, "#B1");
1148                         Assert.AreEqual (1, t1.Day, "#B2");
1149                         Assert.AreEqual (2003, t1.Year, "#B3");
1150
1151                         t1 = DateTime.Parse ("03/02", cultureInfo);
1152                         Assert.AreEqual (2, t1.Month, "#B6");
1153                         Assert.AreEqual (3, t1.Day, "#B7");
1154                         t1 = DateTime.Parse ("03 Feb", cultureInfo);
1155                         Assert.AreEqual (2, t1.Month, "#B8");
1156                         Assert.AreEqual (3, t1.Day, "#B9");
1157
1158                         // Month day behaviour
1159                         dateFormatInfo.MonthDayPattern = "MM/dd";
1160                         t1 = DateTime.Parse ("Feb 03", cultureInfo);
1161                         Assert.AreEqual (2, t1.Month, "#C1");
1162                         Assert.AreEqual (3, t1.Day, "#C2");
1163                         t1 = DateTime.Parse ("02/03", cultureInfo);
1164                         Assert.AreEqual (2, t1.Month, "#C3");
1165                         Assert.AreEqual (3, t1.Day, "#C4");
1166                         t1 = DateTime.Parse ("03 Feb", cultureInfo);
1167                         Assert.AreEqual (2, t1.Month, "#C5");
1168                         Assert.AreEqual (3, t1.Day, "#C6");
1169                 }
1170
1171                 [Test]
1172                 public void TestParse3 ()
1173                 {
1174                         string s = "Wednesday, 09 June 2004";
1175                         DateTime.ParseExact (s, "dddd, dd MMMM yyyy", CultureInfo.InvariantCulture);
1176                         try {
1177                                 DateTime.ParseExact (s, "dddd, dd MMMM yyyy", new CultureInfo ("ja-JP"));
1178                                 Assert.Fail ("ja-JP culture does not support format \"dddd, dd MMMM yyyy\"");
1179                         } catch (FormatException) {
1180                         }
1181
1182                         // Ok, now we can assume ParseExact() works expectedly.
1183
1184                         DateTime.Parse (s, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces);
1185                         DateTime.Parse (s, new CultureInfo ("ja-JP"), DateTimeStyles.AllowWhiteSpaces);
1186                         //DateTime.Parse (s, null); currently am not sure if it works for _every_ culture.
1187                 }
1188
1189
1190                 [Test] // bug #74936
1191                 public void TestParse4 ()
1192                 {
1193                         try {
1194                                 DateTime.Parse("1");
1195                                 Assert.Fail ("#1");
1196                         } catch (FormatException) {
1197                         }
1198
1199                         try {
1200                                 DateTime.Parse("1000");
1201                                 Assert.Fail ("#2");
1202                         } catch (FormatException) {
1203                         }
1204
1205                         try {
1206                                 DateTime.Parse("8:");
1207                                 Assert.Fail ("#3");
1208                         } catch (FormatException) {
1209                         }
1210                 }
1211
1212                 [Test] // bug #71289
1213                 public void Parse_Bug71289a ()
1214                 {
1215                         DateTime.Parse ("Sat,,,,,, 01 Oct 1994 03:00:00", CultureInfo.InvariantCulture);
1216                 }
1217
1218                 [Test]
1219                 public void Parse_Bug71289b ()
1220                 {
1221                         // more example...
1222                         DateTime.Parse ("Sat,,, 01,,, Oct,,, ,,,1994 03:00:00", CultureInfo.InvariantCulture);
1223                 }
1224
1225                 [Test]
1226                 [ExpectedException (typeof (FormatException))]
1227                 public void Parse_CommaAfterHours ()
1228                 {
1229                         // ',' after 03 is not allowed.
1230                         DateTime.Parse ("Sat,,, 01,,, Oct,,, ,,,1994 03,:00:00", CultureInfo.InvariantCulture);
1231                 }
1232
1233                 [Test] // bug #72788
1234                 public void Parse_Bug72788 ()
1235                 {
1236                         DateTime dt = DateTime.Parse ("21/02/05", new CultureInfo ("fr-FR"));
1237                         Assert.AreEqual (2005, dt.Year, "#1");
1238                         Assert.AreEqual (02, dt.Month, "#2");
1239                         Assert.AreEqual (21, dt.Day, "#3");
1240                 }
1241
1242                 [Test] // bug #322510
1243                 public void Parse_HourDesignator ()
1244                 {
1245                         DateTime dt;
1246                         DateTime now = DateTime.Now;
1247
1248                         dt = DateTime.Parse ("12:00:00 AM", new CultureInfo ("en-US"));
1249                         Assert.AreEqual (now.Year, dt.Year, "#A1");
1250                         Assert.AreEqual (now.Month, dt.Month, "#A2");
1251                         Assert.AreEqual (now.Day, dt.Day, "#A3");
1252                         Assert.AreEqual (0, dt.Hour, "#A4");
1253                         Assert.AreEqual (0, dt.Minute, "#A5");
1254                         Assert.AreEqual (0, dt.Second, "#A6");
1255                         Assert.AreEqual (0, dt.Millisecond, "#A7");
1256
1257                         dt = DateTime.Parse ("12:00:00 PM", new CultureInfo ("en-US"));
1258                         Assert.AreEqual (now.Year, dt.Year, "#B1");
1259                         Assert.AreEqual (now.Month, dt.Month, "#B2");
1260                         Assert.AreEqual (now.Day, dt.Day, "#B3");
1261                         Assert.AreEqual (12, dt.Hour, "#B4");
1262                         Assert.AreEqual (0, dt.Minute, "#B5");
1263                         Assert.AreEqual (0, dt.Second, "#B6");
1264                         Assert.AreEqual (0, dt.Millisecond, "#B7");
1265                 }
1266
1267                 [Test]
1268                 public void Parse_Bug53023b ()
1269                 {
1270                         foreach (CultureInfo ci in CultureInfo.GetCultures (CultureTypes.SpecificCultures)) {
1271                                 DateTime.Parse ("01-Sep-05", ci);
1272                                 DateTime.Parse ("4:35:35 AM", ci);
1273                         }
1274                 }
1275
1276                 [Test]
1277                 [ExpectedException (typeof (FormatException))]
1278                 public void Parse_RequireSpaceSeparator ()
1279                 {
1280                         DateTime.Parse ("05:25:132002-02-25", CultureInfo.InvariantCulture);
1281                 }
1282
1283                 [Test]
1284                 [ExpectedException (typeof (FormatException))]
1285                 public void Parse_DontAccept2DigitsYears ()
1286                 {
1287                         // don't allow 2 digit years where we require 4.
1288                         DateTime.ParseExact ("05", "yyyy", CultureInfo.InvariantCulture);
1289                 }
1290
1291                 [Test]
1292                 [ExpectedException (typeof (FormatException))]
1293                 public void Parse_DontAcceptEmptyHours ()
1294                 {
1295                         DateTime.ParseExact (":05", "H:m", CultureInfo.InvariantCulture);
1296                 }
1297
1298                 [Test]
1299                 [ExpectedException (typeof (FormatException))]
1300                 public void Parse_DontAcceptEmptyMinutes ()
1301                 {
1302                         DateTime.ParseExact ("0::0", "H:m:s", CultureInfo.InvariantCulture);
1303                 }
1304
1305                 [Test]
1306                 public void ParseCOMDependentFormat ()
1307                 {
1308                         // Japanese format.
1309                         DateTime.Parse (String.Format (
1310                                 "{0}\u5E74{1}\u6708{2}\u65E5 {3}\u6642{4}\u5206{5}\u79D2",
1311                                 2006, 3, 1, 15, 32, 42), new CultureInfo (""));
1312
1313                         try {
1314                                 // incorrect year mark.
1315                                 DateTime.Parse (String.Format (
1316                                         "{0}\u4E00{1}\u6708{2}\u65E5 {3}\u6642{4}\u5206{5}\u79D2",
1317                                         2006, 3, 1, 15, 32, 42), new CultureInfo (""));
1318                                 Assert.Fail ();
1319                         } catch (FormatException) {
1320                         }
1321                 }
1322
1323                 [Test]
1324                 [ExpectedException(typeof (FormatException))]
1325                 public void ParseFormatException1 ()
1326                 {
1327                         // Following string is not a correct French date i.e.
1328                         // MM/dd/yyyy HH:mm:ss since it expects d/M/yyyy HH:mm:ss
1329                         // instead (however fr-FR accepts both MM/dd/yyyy and
1330                         // dd/MM/yyyy, which means that we can't just throw exceptions 
1331                         // on overflow).
1332                         String frDateTime = "11/13/2003 11:28:15";
1333                         IFormatProvider format = new CultureInfo("fr-FR", true);
1334                         DateTime t1 = DateTime.Parse(frDateTime, format);
1335                 }
1336         
1337                 [Test]
1338                 [ExpectedException(typeof (FormatException))]
1339                 public void ParseFormatExceptionForInvalidYear ()
1340                 {
1341                         // Bug #77633.  In .NET 1..1, the expected exception is ArgumentOutOfRangeException
1342                         // In .NET 2.0, the expected exception is FormatException
1343                         // build a string with the year of 5 digits
1344                         string s = "1/1/10000";
1345                         DateTime dt = DateTime.Parse (s);
1346                 }
1347         
1348                 [Test]
1349                 public void TestOA ()
1350                 {
1351                         double number=5000.41443;
1352                         DateTime d = DateTime.FromOADate(number);
1353                         DTAssertEquals (d, new DateTime(1913, 9, 8, 9, 56, 46, 0), Resolution.Second, "#1");
1354                         Assert.AreEqual (d.ToOADate(), number, "#2");
1355                 }
1356
1357                 [Test]
1358                 public void ParseAllowsQueerString ()
1359                 {
1360                         DateTime.Parse ("Sat,,,,,, 01 Oct 1994 03:00:00", CultureInfo.InvariantCulture);
1361                 }
1362
1363                 [Test]
1364                 public void ParseUtcNonUtc ()
1365                 {
1366                         Thread.CurrentThread.CurrentCulture = new CultureInfo ("es-ES");
1367
1368                         CultureInfo ci;
1369                         string s, s2, s3, d;
1370                         DateTime dt;
1371                         DateTimeFormatInfo dfi = DateTimeFormatInfo.InvariantInfo;
1372                         s = dfi.UniversalSortableDateTimePattern;
1373                         s2 = "r";
1374
1375                         s3 = "s";
1376
1377                         long tick1 = 631789220960000000; // 2003-01-23 12:34:56 as is
1378                         long tick2 = TimeZone.CurrentTimeZone.ToLocalTime (new DateTime (tick1)).Ticks; // adjusted to local time
1379
1380                         // invariant
1381                         ci = CultureInfo.InvariantCulture;
1382
1383                         d = "2003/01/23 12:34:56";
1384                         dt = DateTime.Parse (d, ci);
1385                         Assert.AreEqual (tick1, dt.Ticks, "#1:" + d);
1386
1387                         d = "2003/01/23 12:34:56 GMT";
1388                         dt = DateTime.Parse (d, ci);
1389                         Assert.AreEqual (tick2, dt.Ticks, "#2:" + d);
1390
1391                         d = "Thu, 23 Jan 2003 12:34:56 GMT";
1392                         dt = DateTime.ParseExact (d, s2, ci);
1393                         Assert.AreEqual (tick1, dt.Ticks, "#3:" + d);
1394
1395                         d = "2003-01-23 12:34:56Z";
1396                         dt = DateTime.ParseExact (d, s, ci);
1397                         Assert.AreEqual (tick1, dt.Ticks, "#4:" + d);
1398
1399                         d = "2003-01-23T12:34:56";
1400                         dt = DateTime.ParseExact (d, s3, ci);
1401                         Assert.AreEqual (tick1, dt.Ticks, "#5:" + d);
1402
1403                         // ja-JP ... it should be culture independent
1404                         ci = new CultureInfo ("ja-JP");
1405
1406                         d = "2003/01/23 12:34:56";
1407                         dt = DateTime.Parse (d, ci);
1408                         Assert.AreEqual (tick1, dt.Ticks, "#6:" + d);
1409
1410                         d = "2003/01/23 12:34:56 GMT";
1411                         dt = DateTime.Parse (d, ci);
1412                         Assert.AreEqual (tick2, dt.Ticks, "#7:" + d);
1413
1414                         d = "Thu, 23 Jan 2003 12:34:56 GMT";
1415                         dt = DateTime.ParseExact (d, s2, ci);
1416                         Assert.AreEqual (tick1, dt.Ticks, "#8:" + d);
1417
1418                         d = "2003-01-23 12:34:56Z";
1419                         dt = DateTime.ParseExact (d, s, ci);
1420                         Assert.AreEqual (tick1, dt.Ticks, "#9:" + d);
1421
1422                         d = "2003-01-23T12:34:56";
1423                         dt = DateTime.ParseExact (d, s3, ci);
1424                         Assert.AreEqual (tick1, dt.Ticks, "#10:" + d);
1425                 }
1426
1427                 [Test]
1428                 public void TimeZoneAdjustment ()
1429                 {
1430                         CultureInfo ci = Thread.CurrentThread.CurrentCulture;
1431                         try {
1432                                 Thread.CurrentThread.CurrentCulture = new CultureInfo ("en-US");
1433                                 DateTime d1 = DateTime.ParseExact ("2004/06/30", "yyyy/MM/dd", null);
1434                                 DateTime d2 = DateTime.ParseExact ("2004/06/30Z", "yyyy/MM/dd'Z'", null);
1435                                 DateTime d3 = DateTime.ParseExact ("Wed, 30 Jun 2004 00:00:00 GMT", "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'", null);
1436                                 DateTime d4 = DateTime.ParseExact ("2004-06-30 00:00:00Z", "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", null);
1437                                 StringWriter sw = new StringWriter ();
1438                                 sw.Write ("{0} {1}", d1.Ticks, d1);
1439                                 Assert.AreEqual ("632241504000000000 6/30/2004 12:00:00 AM", sw.ToString (), "#1");
1440                                 sw.GetStringBuilder ().Length = 0;
1441                                 sw.Write ("{0} {1}", d2.Ticks, d2);
1442                                 Assert.AreEqual ("632241504000000000 6/30/2004 12:00:00 AM", sw.ToString (), "#2");
1443                                 sw.GetStringBuilder ().Length = 0;
1444                                 sw.Write ("{0} {1}", d3.Ticks, d3);
1445                                 Assert.AreEqual ("632241504000000000 6/30/2004 12:00:00 AM", sw.ToString (), "#3");
1446                                 sw.GetStringBuilder ().Length = 0;
1447                                 sw.Write ("{0} {1}", d4.Ticks, d4);
1448                                 Assert.AreEqual ("632241504000000000 6/30/2004 12:00:00 AM", sw.ToString (), "#4");
1449                         } finally {
1450                                 Thread.CurrentThread.CurrentCulture = ci;
1451                         }
1452
1453                         // bug #76082
1454                         Assert.AreEqual (DateTime.MinValue, DateTime.ParseExact ("00010101T00:00:00",
1455                                         "yyyyMMdd'T'HH':'mm':'ss", DateTimeFormatInfo.InvariantInfo), "#5");
1456                 }
1457
1458                 [Test]
1459                 public void DateTimeStylesAdjustToUniversal ()
1460                 {
1461                         // bug #75995 : AdjustToUniversal
1462                         DateTime t1 = DateTime.Parse ("2005-09-05T22:29:00Z",
1463                                 CultureInfo.InvariantCulture,
1464                                 DateTimeStyles.AdjustToUniversal);
1465                         Assert.AreEqual ("2005-09-05 22:29:00Z", t1.ToString ("u"));
1466                 }
1467
1468                 [Test]
1469                 [ExpectedException (typeof (ArgumentException))]
1470                 public void FromOADate_Min () 
1471                 {
1472                         // minimum documented value isn't inclusive
1473                         DateTime.FromOADate (-657435.0d);
1474                 }
1475
1476                 [Test]
1477                 [ExpectedException (typeof (ArgumentException))]
1478                 public void FromOADate_Max () 
1479                 {
1480                         // maximum documented value isn't inclusive
1481                         DateTime.FromOADate (2958466.0d);
1482                 }
1483
1484                 [Test]
1485                 public void FromOADate ()
1486                 {
1487                         // Note: OA (OLE Automation) dates aren't timezone sensitive
1488                         Assert.AreEqual (599264352000000000, DateTime.FromOADate (0.0d).Ticks, "#1");
1489                         Assert.AreEqual (31242239136000000, DateTime.FromOADate (-657434.999d).Ticks, "#2");
1490                         Assert.AreEqual (3155378975136000000, DateTime.FromOADate (2958465.999d).Ticks, "#3");
1491                 }
1492
1493                 [Test]
1494                 public void ToOADate ()
1495                 {
1496                         // Note: OA (OLE Automation) dates aren't timezone sensitive
1497                         DateTime d = new DateTime (0);
1498                         Assert.AreEqual (0.0d, d.ToOADate (), "#1");
1499                         d = new DateTime (599264352000000000);
1500                         Assert.AreEqual (0.0d, d.ToOADate (), "#2");
1501                         d = new DateTime (31242239136000000);
1502                         Assert.AreEqual (-657434.999d, d.ToOADate (), "#3");
1503                         d = new DateTime (3155378975136000000);
1504                         Assert.AreEqual (2958465.999d, d.ToOADate (), "#4");
1505                 }
1506
1507                 [Test]
1508                 public void ToOADate_OverMax ()
1509                 {
1510                         DateTime d = new DateTime (3155378975136000001);
1511                         Assert.AreEqual (2958465.999d, d.ToOADate ());
1512                 }
1513
1514                 [Test]
1515                 [Ignore ("This test is probably geo location dependent, at least fails on .NET 4.0 in Japan")]
1516                 public void ToOADate_MaxValue ()
1517                 {
1518                         Assert.AreEqual (2958465.99999999d, DateTime.MaxValue.ToOADate ());
1519                 }
1520
1521                 [Test]
1522                 public void ToOADate_UnderMin ()
1523                 {
1524                         DateTime d = new DateTime (31242239135999999);
1525                         Assert.AreEqual (-657434.999d, d.ToOADate ());
1526                 }
1527
1528                 [Test]
1529                 public void ToOADate_MinValue ()
1530                 {
1531                         Assert.AreEqual (0, DateTime.MinValue.ToOADate ());
1532                 }
1533
1534                 [Test] // bug52075
1535                 public void MaxValueYear ()
1536                 {
1537                         Assert.AreEqual ("9999", DateTime.MaxValue.Year.ToString ());
1538                 }
1539
1540                 [Test]
1541                 public void X509Certificate () 
1542                 {
1543                         // if this test fails then *ALL* or *MOST* X509Certificate tests will also fails
1544                         DateTime dt = DateTime.ParseExact ("19960312183847Z", "yyyyMMddHHmmssZ", null);
1545                         Assert.AreEqual (DateTimeKind.Local, dt.Kind, "#1");
1546                         dt = dt.ToUniversalTime ();
1547                         Assert.AreEqual (DateTimeKind.Utc, dt.Kind, "#2");
1548                         Assert.AreEqual ("03/12/1996 18:38:47", dt.ToString (), "#3");
1549
1550                         // technically this is invalid (PKIX) because of the missing seconds but it exists so...
1551                         dt = DateTime.ParseExact ("9602231915Z", "yyMMddHHmmZ", null);
1552                         Assert.AreEqual (DateTimeKind.Local, dt.Kind, "#4");
1553                         dt = dt.ToUniversalTime ();
1554                         Assert.AreEqual (DateTimeKind.Utc, dt.Kind, "#5");
1555                         Assert.AreEqual ("02/23/1996 19:15:00", dt.ToString (), "#6");
1556
1557                         dt = DateTime.ParseExact ("19960312183847Z", "yyyyMMddHHmmssZ", null, DateTimeStyles.AdjustToUniversal);
1558                         Assert.AreEqual (DateTimeKind.Utc, dt.Kind, "#7");
1559                 }
1560
1561                 [Test]
1562                 public void ZLiteral ()
1563                 {
1564                         // However, "Z" and "'Z'" are different.
1565                         DateTime dt = DateTime.ParseExact ("19960312183847Z", "yyyyMMddHHmmss'Z'", null);
1566                         DateTime dtz = DateTime.ParseExact ("19960312183847Z", "yyyyMMddHHmmssZ", null);
1567                         Assert.AreEqual (DateTimeKind.Unspecified, dt.Kind, "#1");
1568                         dt = dt.ToLocalTime ();
1569                         Assert.AreEqual (DateTimeKind.Local, dt.Kind, "#2");
1570                         Assert.AreEqual (DateTimeKind.Local, dtz.Kind, "#3");
1571                         Assert.AreEqual (dt, dtz, "#4");
1572                 }
1573
1574                 [Test] // bug 56436
1575                 public void QuotedFormat ()
1576                 {
1577                         string date = "28/Mar/2004:19:12:37 +0200";
1578                         string [] expectedFormats = {"dd\"/\"MMM\"/\"yyyy:HH:mm:ss zz\"00\""};
1579                         DateTime.ParseExact (date, expectedFormats, null, DateTimeStyles.AllowWhiteSpaces);
1580                 }
1581
1582                 [Test]
1583                 public void CultureIndependentTests ()
1584                 {
1585                         // Here I aggregated some tests mainly because of test 
1586                         // performance (iterating all the culture is heavy process).
1587                 
1588                         for (int i = 0; i < 32768; i++) {
1589                                 CultureInfo ci = null;
1590                                 string stage = "init";
1591                                 try {
1592                                         try {
1593                                                 ci = new CultureInfo (i);
1594                                                 // In fact InvatiantCulture is not neutral.
1595                                                 // See bug #59716.
1596                                                 if (ci.IsNeutralCulture && ci != CultureInfo.InvariantCulture)
1597                                                         continue;
1598                                         } catch (Exception) {
1599                                                 continue;
1600                                         }
1601                                         Thread.CurrentThread.CurrentCulture = ci;
1602                                         DateTime dt;
1603
1604                                         switch (ci.LCID) {
1605                                         case 1025: // ar-SA
1606                                         case 2559: // qps-plocm
1607                                                 continue; // fails too many tests below on .NET.
1608                                         }
1609
1610                                         // Common patterns
1611                                         // X509Certificate pattern is _always_ accepted.
1612                                         stage = "1";
1613                                         dt = DateTime.ParseExact ("19960312183847Z", "yyyyMMddHHmmssZ", null);
1614
1615                                         stage = "2";
1616                                         // fails with many cultures on .NET.
1617         //                              if (i != 127)
1618         //                                      dt = DateTime.Parse ("19960312183847Z");
1619
1620                                         stage = "3";
1621                                         dt = DateTime.Parse ("2004-05-26T03:29:01.1234567");
1622                                         stage = "4";
1623                                         dt = DateTime.Parse ("2004-05-26T03:29:01.1234567-07:00");
1624
1625                                         // memo: the least LCID is 127, and then 1025(ar-SA)
1626
1627                                         // "th-TH" locale rejects them since in
1628                                         // ThaiBuddhistCalendar the week of a day is different.
1629                                         // (and also for years).
1630                                         switch (ci.LCID) {
1631                                         case 1054:
1632                                         case 1128: // ha-Latn-NG
1633                                                 break;
1634                                         default:
1635                                                 try {
1636                                                         stage = "5";
1637                                                         dt = DateTime.Parse ("Sat, 29 Oct 1994 12:00:00 GMT", ci);
1638                                                 } catch (FormatException ex) {
1639                                                         Assert.Fail (String.Format ("stage 5.1 RFC1123: culture {0} {1} failed: {2}", i, ci, ex.Message));
1640                                                 }
1641
1642                                                 // bug #47720
1643                                                 if (dt != TimeZone.CurrentTimeZone.ToUniversalTime (dt))
1644                                                         Assert.IsTrue (12 != dt.Hour, String.Format ("bug #47720 on culture {0} {1}", ci.LCID, ci));
1645
1646                                                 // variant of RFC1123
1647                                                 try {
1648                                                         stage = "6";
1649                                                         dt = DateTime.Parse ("Sat, 1 Oct 1994 03:00:00", ci);
1650                                                 } catch (FormatException ex) {
1651                                                         Assert.Fail (String.Format ("stage 6.1 RFC1123 variant: culture {0} {1} failed: {2}", i, ci, ex.Message));
1652                                                 }
1653                                                 stage = "7";
1654                                                 Assert.AreEqual (3, dt.Hour, String.Format ("stage 7.1 RFC1123 variant on culture {0} {1}", ci.LCID, ci));
1655                                                 break;
1656                                         }
1657
1658                                         switch (ci.LCID) {
1659                                         case 1054: // th-TH
1660                                         case 1123: // ps-AF
1661                                         case 1125: // div-MV
1662                                         case 1164: // prs-AF
1663                                                 break;
1664                                         default:
1665                                                 stage = "8";
1666                                                 // 02/25/2002 04:25:13 as is
1667                                                 long tick1 = 631502079130000000;
1668                                                 long tick2 = TimeZone.CurrentTimeZone.ToLocalTime (new DateTime (tick1)).Ticks; // adjusted to local time
1669                                                 dt = DateTime.Parse ("Mon, 25 Feb 2002 04:25:13 GMT", ci);
1670                                                 Assert.AreEqual (tick2, dt.Ticks, String.Format ("GMT variant. culture={0} {1}", i, ci));
1671                                                 break;
1672                                         }
1673
1674
1675                                         // ka-GE rejects these formats under MS.NET. 
1676                                         // I wonder why. Also, those tests fail under .NET 1.0.
1677                                         if (ci.LCID != 1079) {
1678                                                 stage = "9";
1679                                                 dt = DateTime.Parse ("2002-02-25");
1680                                                 stage = "10";
1681                                                 dt = DateTime.Parse ("2002-02-25Z");
1682                                                 stage = "11";
1683                                                 dt = DateTime.Parse ("2002-02-25T19:20:00+09:00");
1684                                                 switch (ci.LCID) {
1685                                                 case 1038: // FIXME: MS passes this culture.
1686                                                 case 1062: // FIXME: MS passes this culture.
1687                                                 case 1078: // MS does not pass this culture. Dunno why.
1688                                                         break;
1689                                                 default:
1690                                                         break;
1691                                                 }
1692                                                 stage = "14";
1693                                                 dt = DateTime.Parse ("2002-02-25 12:01:03");
1694                                                 stage = "17";
1695                                                 if (ci.DateTimeFormat.TimeSeparator != ".")
1696                                                         dt = DateTime.Parse ("2002.02.25 12:01:03");
1697                                                 stage = "18";
1698                                                 dt = DateTime.Parse ("2003/01/23 01:34:56 GMT");
1699                                                 dt = TimeZone.CurrentTimeZone.ToUniversalTime (dt);
1700                                                 Assert.AreEqual (1, dt.Hour, String.Format ("stage 18.1 RFC1123 UTC {0} {1}", i, ci));
1701                                                 stage = "19";
1702                                                 // This test was fixed from 12:34:56 to
1703                                                 // 01:34:56 since 1078 af-ZA failed
1704                                                 // because of hour interpretation
1705                                                 // difference (af-ZA expects 0).
1706                                                 // (IMHO it is MS BUG though.)
1707                                                 dt = DateTime.Parse ("2003/01/23 12:34:56 GMT");
1708                                                 dt = TimeZone.CurrentTimeZone.ToUniversalTime (dt);
1709                                                 if (i != 1078)
1710                                                         Assert.AreEqual (12, dt.Hour, String.Format ("stage 18.1 RFC1123 UTC {0} {1}", i, ci));
1711                                         }
1712                                 } catch (FormatException ex) {
1713                                         Assert.Fail (String.Format ("stage {3}: Culture {0} {1} failed: {2}", i, ci, ex.Message, stage));
1714                                 }
1715                         }
1716                 }
1717
1718                 [Test]
1719                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1720                 public void ToFileTime_MinValue () 
1721                 {
1722                         DateTime.FromFileTime (Int64.MinValue);
1723                 }
1724
1725                 [Test]
1726                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1727                 public void ToFileTime_Negative () 
1728                 {
1729                         DateTime.FromFileTime (-1);
1730                 }
1731
1732                 [Test]
1733                 public void ToFileTime () 
1734                 {
1735                         long u = DateTime.FromFileTimeUtc (0).Ticks;
1736                         Assert.AreEqual (504911232000000000, u, "#A1");
1737                         long max = DateTime.MaxValue.Ticks - 504911232000000000; // w32file_epoch
1738                         Assert.AreEqual (3155378975999999999, DateTime.FromFileTimeUtc (max).Ticks, "#A2");
1739
1740                         long t = DateTime.FromFileTime (0).Ticks;
1741                         Assert.IsTrue (t > (u - TimeSpan.TicksPerDay), "#B1");
1742                         Assert.IsTrue (t < (u + TimeSpan.TicksPerDay), "#B2");
1743                 }
1744
1745                 [Test]
1746                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1747                 public void ToFileTimeUtc_MinValue () 
1748                 {
1749                         DateTime.FromFileTimeUtc (Int64.MinValue);
1750                 }
1751
1752                 [Test]
1753                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1754                 public void ToFileTimeUtc_Negative () 
1755                 {
1756                         DateTime.FromFileTimeUtc (-1);
1757                 }
1758
1759                 [Test]
1760                 public void ToFileTimeUtc ()
1761                 {
1762                         // Randomly generated time outside DST.
1763                         var utc = new DateTime (1993, 01, 28, 08, 49, 48, DateTimeKind.Utc);
1764                         var local = utc.ToLocalTime ();
1765                         var unspecified = new DateTime (1993, 01, 28, 08, 49, 48);
1766
1767                         Assert.AreEqual (DateTimeKind.Utc, utc.Kind);
1768                         Assert.AreEqual (DateTimeKind.Local, local.Kind);
1769                         Assert.AreEqual (DateTimeKind.Unspecified, unspecified.Kind);
1770
1771                         Assert.AreEqual (628638077880000000, utc.Ticks);
1772                         Console.WriteLine (local.Ticks - utc.Ticks);
1773
1774                         var offset = TimeZone.CurrentTimeZone.GetUtcOffset (local);
1775
1776                         var utcFt = utc.ToFileTime ();
1777                         var localFt = local.ToFileTime ();
1778                         var unspecifiedFt = unspecified.ToFileTime ();
1779
1780                         var utcUft = utc.ToFileTimeUtc ();
1781                         var localUft = local.ToFileTimeUtc ();
1782                         var unspecifiedUft = unspecified.ToFileTimeUtc ();
1783
1784                         Assert.AreEqual (123726845880000000, utcFt);
1785                         Assert.AreEqual (utcFt, localFt);
1786
1787                         Assert.AreEqual (offset.Ticks, utcFt - unspecifiedFt);
1788
1789                         Assert.AreEqual (utcFt, utcUft);
1790                         Assert.AreEqual (utcFt, localUft);
1791                         Assert.AreEqual (utcFt, unspecifiedUft);
1792                 }
1793                 
1794                 [Test]
1795                 public void FromFileTimeUtcTest ()
1796                 {
1797                         DateTime dt = DateTime.FromFileTimeUtc (123456);
1798                         Assert.AreEqual (dt.Kind, DateTimeKind.Utc, "#Kind");
1799                         Assert.AreEqual (dt.Ticks, 504911232000123456, "#Ticks");
1800                 }
1801
1802                 [Test]
1803                 public void Milliseconds ()
1804                 {
1805                         DateTime dt = DateTime.Parse ("2004-05-26T03:29:01.1234567-07:00");
1806                         dt = TimeZone.CurrentTimeZone.ToUniversalTime (dt);
1807                         Assert.AreEqual (632211641411234567, dt.Ticks);
1808                 }
1809
1810                 [Test]
1811                 [ExpectedException (typeof (FormatException))]
1812                 public void ParseNotExact ()
1813                 {
1814                         // The error reported is:
1815                         // String was not recognized as valid DateTime
1816                         DateTime dt = DateTime.Parse ("2004-05-26T03:29:01-07:00 foo");
1817                         dt = TimeZone.CurrentTimeZone.ToUniversalTime (dt);
1818                         Assert.AreEqual (632211641410000000, dt.Ticks);
1819                 }
1820
1821                 [Test]
1822                 public void ParseExact_Bug80094 ()
1823                 {
1824                         // we can safely change the curernt culture, as the original value will
1825                         // be restored on TearDown
1826                         Thread.CurrentThread.CurrentCulture = new CultureInfo ("ja-JP");
1827                         string y = string.Format ("{0}-{1}-{2} {3}", DateTime.Now.Year.ToString (),
1828                                 "11", "29", "06:34");
1829                         DateTime date = DateTime.ParseExact (y, "yyyy-MMM-dd hh:mm", null);
1830                         Assert.AreEqual (DateTime.Now.Year, date.Year, "#1");
1831                         Assert.AreEqual (11, date.Month, "#2");
1832                         Assert.AreEqual (29, date.Day, "#3");
1833                         Assert.AreEqual (6, date.Hour, "#4");
1834                         Assert.AreEqual (34, date.Minute, "#5");
1835                         Assert.AreEqual (0, date.Second, "#6");
1836                         Assert.AreEqual (0, date.Millisecond, "#7");
1837                 }
1838
1839                 [Test]
1840                 public void ParseExact_Bug324845 ()
1841                 {
1842                         DateTime ctime = new DateTime (2007, 7, 23, 19, 19, 45);
1843                         ctime = ctime.ToUniversalTime ();
1844                         string instr = ctime.ToString ("yyyyMMddHHmmss");
1845
1846                         DateTime t = DateTime.ParseExact (instr, "yyyyMMddHHmmss", null, DateTimeStyles.AssumeUniversal);
1847                         Assert.AreEqual (2007, t.Year);
1848                         Assert.AreEqual (7, t.Month);
1849                         Assert.AreEqual (23, t.Day);
1850                         Assert.AreEqual (19, t.Hour);
1851                         Assert.AreEqual (19, t.Minute);
1852                         Assert.AreEqual (45, t.Second);
1853
1854                 }
1855
1856                 [Test]
1857                 [ExpectedException (typeof (FormatException))]
1858                 public void ParseExactIsExact()
1859                 {
1860                         DateTime.ParseExact ("2004-05-26T03:29:01-07:00 foo", "yyyy-MM-ddTHH:mm:sszzz", null);
1861                 }
1862
1863                 [Test]
1864                 [ExpectedException (typeof (FormatException))]
1865                 public void ParseExactDoesNotEatZ ()
1866                 {
1867                         DateTime.ParseExact ("2004-05-26T03:29:01", "yyyy-MM-ddTHH:mm:ssZ", null);
1868                 }
1869
1870                 [Test]
1871                 public void ParseExactMilliseconds ()
1872                 {
1873                         DateTime dt = DateTime.ParseExact ("2004-05-26T03:29:01.1234567-07:00", "yyyy-MM-ddTHH:mm:ss.fffffffzzz", null);
1874                         dt = TimeZone.CurrentTimeZone.ToUniversalTime (dt);
1875                         Assert.AreEqual (632211641411234567, dt.Ticks);
1876                 }
1877
1878                 [Test]
1879                 public void NoColonTimeZone ()
1880                 {
1881                         Assert.IsTrue (DateTime.Parse ("2004-05-26T03:29:01-0700").Ticks
1882                                 != DateTime.Parse ("2004-05-26T03:29:01-0800").Ticks);
1883                 }
1884
1885                 [Test]
1886                 public void WithColonTimeZone ()
1887                 {
1888                         Assert.IsTrue (DateTime.Parse ("2004-05-26T03:29:01-07:00").Ticks
1889                                 != DateTime.Parse ("2004-05-26T03:29:01-08:00").Ticks);
1890                 }
1891
1892                 [Test]
1893                 [ExpectedException (typeof (FormatException))]
1894                 public void EmptyFormatPattern ()
1895                 {
1896                         DateTime.ParseExact (String.Empty, String.Empty, null);
1897                 }
1898
1899                 [Test]
1900                 [ExpectedException (typeof (InvalidCastException))]
1901                 public void IConvertible_ToType_Boolean () 
1902                 {
1903                         ((IConvertible)DateTime.Now).ToType (typeof (bool), null);
1904                 }
1905
1906                 [Test]
1907                 [ExpectedException (typeof (InvalidCastException))]
1908                 public void IConvertible_ToType_Byte () 
1909                 {
1910                         ((IConvertible)DateTime.Now).ToType (typeof (byte), null);
1911                 }
1912
1913                 [Test]
1914                 [ExpectedException (typeof (InvalidCastException))]
1915                 public void IConvertible_ToType_Char () 
1916                 {
1917                         ((IConvertible)DateTime.Now).ToType (typeof (char), null);
1918                 }
1919
1920                 [Test]
1921                 public void IConvertible_ToType_DateTime () 
1922                 {
1923                         DateTime dt = DateTime.Now;
1924                         DateTime dt2 = (DateTime) ((IConvertible)dt).ToType (typeof (DateTime), null);
1925                         Assert.IsTrue (dt.Equals (dt2));
1926                 }
1927
1928                 [Test]
1929                 [ExpectedException (typeof (InvalidCastException))]
1930                 public void IConvertible_ToType_DBNull () 
1931                 {
1932                         ((IConvertible)DateTime.Now).ToType (typeof (DBNull), null);
1933                 }
1934
1935                 [Test]
1936                 [ExpectedException (typeof (InvalidCastException))]
1937                 public void IConvertible_ToType_Decimal () 
1938                 {
1939                         ((IConvertible)DateTime.Now).ToType (typeof (decimal), null);
1940                 }
1941
1942                 [Test]
1943                 [ExpectedException (typeof (InvalidCastException))]
1944                 public void IConvertible_ToType_Double () 
1945                 {
1946                         ((IConvertible)DateTime.Now).ToType (typeof (double), null);
1947                 }
1948
1949                 [Test]
1950                 [ExpectedException (typeof (ArgumentNullException))]
1951                 public void IConvertible_ToType_Empty () 
1952                 {
1953                         ((IConvertible)DateTime.Now).ToType (null, null);
1954                 }
1955
1956                 [Test]
1957                 [ExpectedException (typeof (InvalidCastException))]
1958                 public void IConvertible_ToType_Int16 () 
1959                 {
1960                         ((IConvertible)DateTime.Now).ToType (typeof (short), null);
1961                 }
1962
1963                 [Test]
1964                 [ExpectedException (typeof (InvalidCastException))]
1965                 public void IConvertible_ToType_Int32 () 
1966                 {
1967                         ((IConvertible)DateTime.Now).ToType (typeof (int), null);
1968                 }
1969
1970                 [Test]
1971                 [ExpectedException (typeof (InvalidCastException))]
1972                 public void IConvertible_ToType_Int64 () 
1973                 {
1974                         ((IConvertible)DateTime.Now).ToType (typeof (long), null);
1975                 }
1976
1977                 [Test]
1978                 public void IConvertible_ToType_Object () 
1979                 {
1980                         DateTime dt = DateTime.Now;
1981                         object o = ((IConvertible)dt).ToType (typeof (object), null);
1982                         Assert.IsTrue (dt.Equals (o));
1983                 }
1984
1985                 [Test]
1986                 [ExpectedException (typeof (InvalidCastException))]
1987                 public void IConvertible_ToType_SByte () 
1988                 {
1989                         ((IConvertible)DateTime.Now).ToType (typeof (sbyte), null);
1990                 }
1991
1992                 [Test]
1993                 [ExpectedException (typeof (InvalidCastException))]
1994                 public void IConvertible_ToType_Single () 
1995                 {
1996                         ((IConvertible)DateTime.Now).ToType (typeof (float), null);
1997                 }
1998
1999                 [Test]
2000                 public void IConvertible_ToType_String () 
2001                 {
2002                         DateTime dt = DateTime.Now;
2003                         string s = (string) ((IConvertible)dt).ToType (typeof (string), null);
2004                         Assert.AreEqual (s, dt.ToString ());
2005                 }
2006
2007                 [Test]
2008                 [ExpectedException (typeof (InvalidCastException))]
2009                 public void IConvertible_ToType_UInt16 () 
2010                 {
2011                         ((IConvertible)DateTime.Now).ToType (typeof (ushort), null);
2012                 }
2013
2014                 [Test]
2015                 [ExpectedException (typeof (InvalidCastException))]
2016                 public void IConvertible_ToType_UInt32 () 
2017                 {
2018                         ((IConvertible)DateTime.Now).ToType (typeof (uint), null);
2019                 }
2020
2021                 [Test]
2022                 [ExpectedException (typeof (InvalidCastException))]
2023                 public void IConvertible_ToType_UInt64 () 
2024                 {
2025                         ((IConvertible)DateTime.Now).ToType (typeof (ulong), null);
2026                 }
2027
2028                 [Test]
2029                 public void Bug352210 ()
2030                 {
2031                         DateTime dt = DateTime.ParseExact ("2007-06-15T10:30:10.5", "yyyy-MM-ddTHH:mm:ss.f", null);
2032                         Assert.AreEqual (633175002105000000, dt.Ticks, "#1");
2033                         Assert.AreEqual (DateTimeKind.Unspecified, dt.Kind, "#2");
2034                 }
2035
2036                 [Test]
2037                 public void Bug352210_New ()
2038                 {
2039                         long ticksUTC = 633377759060000000;
2040                         long ticksLocal = ticksUTC + TimeZone.CurrentTimeZone.GetUtcOffset (new DateTime (ticksUTC)).Ticks;
2041                         CultureInfo ci = CultureInfo.InvariantCulture;
2042                         DateTime dt;
2043
2044                         // Should return same time with Unspecified kind
2045                         dt = DateTime.ParseExact ("2008-02-05 02:38:26", "yyyy-MM-dd HH:mm:ss", ci);
2046                         Assert.AreEqual (DateTimeKind.Unspecified, dt.Kind, "A1");
2047                         Assert.AreEqual (ticksUTC, dt.Ticks, "A2");
2048
2049                         // Should return same time with Unspecified kind
2050                         dt = DateTime.ParseExact ("2008-02-05 02:38:26Z", "u", ci);
2051                         Assert.AreEqual (DateTimeKind.Unspecified, dt.Kind, "B1");
2052                         Assert.AreEqual (ticksUTC, dt.Ticks, "B2");
2053
2054                         // Should adjust to local time with Local kind
2055                         dt = DateTime.ParseExact ("2008-02-05 00:38:26-02:00", "yyyy-MM-dd HH:mm:ssK", ci);
2056                         Assert.AreEqual (DateTimeKind.Local, dt.Kind, "C1");
2057                         Assert.AreEqual (ticksLocal, dt.Ticks, "C2");
2058
2059                         // Should ignore AssumeUniversal since a timezone specifier is in the format string
2060                         // and return time adjusted to local time with Local kind
2061                         dt = DateTime.ParseExact ("2008-02-05 00:38:26 -2", "yyyy-MM-dd HH:mm:ss z", ci, DateTimeStyles.AssumeUniversal);
2062                         Assert.AreEqual (DateTimeKind.Local, dt.Kind, "D1");
2063                         Assert.AreEqual (ticksLocal, dt.Ticks, "D2");
2064
2065                         try {
2066                                 // GMT in format string can be used to specify time zone
2067                                 dt = DateTime.ParseExact ("2008-02-05 02:38:26 GMT", "yyyy-MM-dd HH:mm:ss GMT", ci);
2068                                 Assert.AreEqual (DateTimeKind.Local, dt.Kind, "E1");
2069                                 Assert.AreEqual (ticksLocal, dt.Ticks, "E2");
2070                         }
2071                         catch {
2072                                 Assert.Fail ("E3");
2073                         }
2074
2075                         try {
2076                                 // Same as above even when surrounded with other characters
2077                                 dt = DateTime.ParseExact ("2008-02-05 02:38:26 qqGMTqq", "yyyy-MM-dd HH:mm:ss qqGMTqq", ci);
2078                                 Assert.AreEqual (DateTimeKind.Local, dt.Kind, "F1");
2079                                 Assert.AreEqual (ticksLocal, dt.Ticks, "F2");
2080                         }
2081                         catch {
2082                                 Assert.Fail ("F3");
2083                         }
2084
2085                         try {
2086                                 // But single quoted GMT in format string should not specify time zone
2087                                 dt = DateTime.ParseExact ("2008-02-05 02:38:26 GMT", "yyyy-MM-dd HH:mm:ss 'GMT'", ci);
2088                                 Assert.AreEqual (DateTimeKind.Unspecified, dt.Kind, "G1");
2089                                 Assert.AreEqual (ticksUTC, dt.Ticks, "G2");
2090                         }
2091                         catch {
2092                                 Assert.Fail ("G3");
2093                         }
2094
2095                         dt = DateTime.Parse ("GMT 2008-02-05 02:38:26", ci);
2096                         Assert.AreEqual (DateTimeKind.Local, dt.Kind, "H1");
2097                         Assert.AreEqual (ticksLocal, dt.Ticks, "H2");
2098                 }
2099
2100                 [Test]
2101                 public void Bug377042 ()
2102                 {
2103                         string [] f = new string [] {
2104                                 "yyyy-MM-ddTHH:mm:ssZ",
2105                                 "yyyy-MM-ddTHH:mm:sszzzz",
2106                                 "yyyy-MM-dd"
2107                                 };
2108                         DateTimeStyles dts = DateTimeStyles.AdjustToUniversal;
2109                         dts |= DateTimeStyles.AssumeUniversal;
2110                         DateTime result = DateTime.ParseExact ("2005-01-01T01:11:11+8:00", f, new DateTimeFormatInfo (), dts);
2111                 }
2112
2113         [Test]
2114         public void TestParseExactXmlTimeFormats()
2115         {
2116             //Xamarin Bug 16742
2117             string[] xmlTimeFormats = {
2118                 "HH:mm:ss", "HH:mm:ss.FFFFFFF",
2119                 "HH:mm:sszzz", "HH:mm:ss.FFFFFFFzzz",
2120                 "HH:mm:ssZ", "HH:mm:ss.FFFFFFFZ"
2121             };
2122             DateTimeStyles style = DateTimeStyles.AllowLeadingWhite | DateTimeStyles.AllowTrailingWhite;
2123
2124             //time local
2125             Assert.AreEqual(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000).Ticks,
2126                 DateTime.ParseExact("13:30:44", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2127             Assert.AreEqual(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000).Ticks,
2128                 DateTime.ParseExact("13:30:44.0", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2129             Assert.AreEqual(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000).Ticks,
2130                 DateTime.ParseExact("13:30:44.00", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2131             Assert.AreEqual(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000).Ticks,
2132                 DateTime.ParseExact("13:30:44.000", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2133             Assert.AreEqual(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000).Ticks,
2134                 DateTime.ParseExact("13:30:44.0000", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2135             Assert.AreEqual(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000).Ticks,
2136                 DateTime.ParseExact("13:30:44.00000", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2137             Assert.AreEqual(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000).Ticks,
2138                 DateTime.ParseExact("13:30:44.000000", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2139             Assert.AreEqual(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000).Ticks,
2140                 DateTime.ParseExact("13:30:44.0000000", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2141             Assert.AreEqual(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 123).Ticks,
2142                 DateTime.ParseExact("13:30:44.123", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2143
2144             //time with zero timezone
2145             Assert.AreEqual(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000, DateTimeKind.Utc).ToLocalTime().Ticks,
2146                 DateTime.ParseExact("13:30:44Z", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2147             Assert.AreEqual(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000, DateTimeKind.Utc).ToLocalTime().Ticks,
2148                 DateTime.ParseExact("13:30:44.0Z", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2149             Assert.AreEqual(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000, DateTimeKind.Utc).ToLocalTime().Ticks,
2150                 DateTime.ParseExact("13:30:44.00Z", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2151             Assert.AreEqual(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000, DateTimeKind.Utc).ToLocalTime().Ticks,
2152                 DateTime.ParseExact("13:30:44.000Z", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2153             Assert.AreEqual(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000, DateTimeKind.Utc).ToLocalTime().Ticks,
2154                 DateTime.ParseExact("13:30:44.0000Z", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2155             Assert.AreEqual(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000, DateTimeKind.Utc).ToLocalTime().Ticks,
2156                 DateTime.ParseExact("13:30:44.00000Z", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2157             Assert.AreEqual(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000, DateTimeKind.Utc).ToLocalTime().Ticks,
2158                 DateTime.ParseExact("13:30:44.000000Z", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2159             Assert.AreEqual(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000, DateTimeKind.Utc).ToLocalTime().Ticks,
2160                 DateTime.ParseExact("13:30:44.0000000Z", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2161             Assert.AreEqual(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 123, DateTimeKind.Utc).ToLocalTime().Ticks,
2162                 DateTime.ParseExact("13:30:44.123Z", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2163
2164             //time with timezone
2165             Assert.AreEqual(new DateTimeOffset(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000, new TimeSpan(13, 0, 0)).ToLocalTime().Ticks,
2166                 DateTime.ParseExact("13:30:44+13:00", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2167             Assert.AreEqual(new DateTimeOffset(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000, new TimeSpan(13, 0, 0)).ToLocalTime().Ticks,
2168                 DateTime.ParseExact("13:30:44.0+13:00", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2169             Assert.AreEqual(new DateTimeOffset(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000, new TimeSpan(13, 0, 0)).ToLocalTime().Ticks,
2170                 DateTime.ParseExact("13:30:44.00+13:00", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2171             Assert.AreEqual(new DateTimeOffset(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000, new TimeSpan(13, 0, 0)).ToLocalTime().Ticks,
2172                 DateTime.ParseExact("13:30:44.000+13:00", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2173             Assert.AreEqual(new DateTimeOffset(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000, new TimeSpan(13, 0, 0)).ToLocalTime().Ticks,
2174                 DateTime.ParseExact("13:30:44.0000+13:00", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2175             Assert.AreEqual(new DateTimeOffset(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000, new TimeSpan(13, 0, 0)).ToLocalTime().Ticks,
2176                 DateTime.ParseExact("13:30:44.00000+13:00", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2177             Assert.AreEqual(new DateTimeOffset(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000, new TimeSpan(13, 0, 0)).ToLocalTime().Ticks,
2178                 DateTime.ParseExact("13:30:44.000000+13:00", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2179             Assert.AreEqual(new DateTimeOffset(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 000, new TimeSpan(13, 0, 0)).ToLocalTime().Ticks,
2180                 DateTime.ParseExact("13:30:44.0000000+13:00", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2181             Assert.AreEqual(new DateTimeOffset(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 13, 30, 44, 123, new TimeSpan(13, 0, 0)).ToLocalTime().Ticks,
2182                 DateTime.ParseExact("13:30:44.123+13:00", xmlTimeFormats, DateTimeFormatInfo.InvariantInfo, style).Ticks);
2183         }
2184
2185                 [Test]
2186                 [ExpectedException (typeof (FormatException))]
2187                 public void EmptyString ()
2188                 {
2189                         DateTime.Parse ("");
2190                 }
2191
2192                 [Test]
2193                 public void TryEmptyString ()
2194                 {
2195                         DateTime date;
2196                         Assert.IsFalse (DateTime.TryParse ("", out date));
2197                 }
2198
2199                 [Test]
2200                 public void Kind ()
2201                 {
2202                         if (DateTime.Now == DateTime.UtcNow)
2203                                 return; // This test does not make sense.
2204                         if (TimeZone.CurrentTimeZone.GetUtcOffset (DateTime.UtcNow)
2205                                 != TimeZone.CurrentTimeZone.GetUtcOffset (DateTime.Now))
2206                                 return; // In this case it does not satisfy the test premises.
2207
2208                         Assert.AreEqual (DateTimeKind.Local, DateTime.Now.Kind, "#A1");
2209                         Assert.AreEqual (DateTimeKind.Local, DateTime.Today.Kind, "#A2");
2210
2211                         DateTime utc = DateTime.UtcNow;
2212                         DateTime now = new DateTime (utc.Ticks + TimeZone.
2213                                 CurrentTimeZone.GetUtcOffset (utc).Ticks, DateTimeKind.Local);
2214                         DateTime utctouniv = utc.ToUniversalTime ();
2215                         DateTime nowtouniv = now.ToUniversalTime ();
2216                         DateTime utctoloc = utc.ToLocalTime ();
2217                         DateTime nowtoloc = now.ToLocalTime ();
2218
2219                         Assert.AreEqual (DateTimeKind.Utc, utc.Kind, "#B1");
2220                         Assert.AreEqual (DateTimeKind.Local, now.Kind, "#B2");
2221                         Assert.AreEqual (DateTimeKind.Utc, utctouniv.Kind, "#B3");
2222                         Assert.AreEqual (DateTimeKind.Utc, nowtouniv.Kind, "#B4");
2223                         Assert.AreEqual (DateTimeKind.Local, utctoloc.Kind, "#B5");
2224                         Assert.AreEqual (DateTimeKind.Local, nowtoloc.Kind, "#B6");
2225                         Assert.AreEqual (utc, utctouniv, "#B7");
2226                         Assert.AreEqual (utc, nowtouniv, "#B8");
2227                         Assert.AreEqual (now, nowtoloc, "#B9");
2228                         Assert.AreEqual (now, utctoloc, "#B10");
2229                 }
2230
2231                 [Test]
2232                 public void InstanceMembersAndKind ()
2233                 {
2234                         Assert.AreEqual (DateTimeKind.Utc, DateTime.UtcNow.Date.Kind, "#1");
2235                         Assert.AreEqual (DateTimeKind.Utc, DateTime.UtcNow.Add (TimeSpan.FromMinutes (1)).Kind, "#2");
2236                         Assert.AreEqual (DateTimeKind.Utc, DateTime.UtcNow.Subtract (TimeSpan.FromMinutes (1)).Kind, "#3");
2237                         Assert.AreEqual (DateTimeKind.Utc, DateTime.UtcNow.AddDays (1).Kind, "#4");
2238                         Assert.AreEqual (DateTimeKind.Utc, DateTime.UtcNow.AddTicks (1).Kind, "#5");
2239                         Assert.AreEqual (DateTimeKind.Utc, DateTime.UtcNow.AddHours (1).Kind, "#6");
2240                         Assert.AreEqual (DateTimeKind.Utc, DateTime.UtcNow.AddMinutes (1).Kind, "#7");
2241                         Assert.AreEqual (DateTimeKind.Utc, DateTime.UtcNow.AddSeconds (1).Kind, "#8");
2242                         Assert.AreEqual (DateTimeKind.Utc, DateTime.UtcNow.AddMilliseconds (1).Kind, "#9");
2243                         Assert.AreEqual (DateTimeKind.Utc, DateTime.UtcNow.AddMonths (1).Kind, "#10");
2244                         Assert.AreEqual (DateTimeKind.Utc, DateTime.UtcNow.AddYears (1).Kind, "#11");
2245                         Assert.AreEqual (DateTimeKind.Utc, (DateTime.UtcNow + TimeSpan.FromMinutes (1)).Kind, "#12");
2246                         Assert.AreEqual (DateTimeKind.Utc, (DateTime.UtcNow - TimeSpan.FromMinutes (1)).Kind, "#13");
2247                 }
2248
2249                 [Test]
2250                 public void CompareTicks ()
2251                 {
2252                         // Only ticks are compared, not kind.
2253                         var d = new DateTime (0, DateTimeKind.Utc);
2254                         var f = new DateTime (0);
2255
2256                         Assert.AreEqual (d == f, true, "#1");
2257                 }
2258                 
2259                 [Test]
2260                 public void FromBinary ()
2261                 {
2262                         DateTime dt_utc = DateTime.FromBinary (0x4000000000000001);
2263                         Assert.AreEqual (DateTimeKind.Utc, dt_utc.Kind, "#1");
2264                         Assert.AreEqual (1, dt_utc.Ticks, "#2");
2265
2266                         DateTime dt_local = DateTime.FromBinary (unchecked ((long) 0x8000000000000001));
2267                         Assert.AreEqual (DateTimeKind.Local, dt_local.Kind, "#3");
2268
2269                         DateTime dt_unspecified = DateTime.FromBinary (0x0000000000000001);
2270                         Assert.AreEqual (DateTimeKind.Unspecified, dt_unspecified.Kind, "#4");
2271                         Assert.AreEqual (1, dt_unspecified.Ticks, "#5");
2272
2273                         DateTime dt_local2 = DateTime.FromBinary (unchecked ((long) 0xC000000000000001));
2274                         Assert.AreEqual (DateTimeKind.Local, dt_local2.Kind, "#6");
2275                         Assert.AreEqual (dt_local.Ticks, dt_local2.Ticks, "#7");
2276                 }
2277
2278                 [Test]
2279                 public void ToBinary ()
2280                 {
2281                         DateTime dt_local = new DateTime (1, DateTimeKind.Local);
2282                         Assert.AreEqual (1, (ulong) dt_local.ToBinary () >> 63, "#1");
2283                         Assert.AreEqual (1, dt_local.Ticks, "#2");
2284
2285                         DateTime dt_utc = new DateTime (1, DateTimeKind.Utc);
2286                         Assert.AreEqual (0x4000000000000001, dt_utc.ToBinary (), "#3");
2287                         Assert.AreEqual (1, dt_utc.Ticks, "#4");
2288
2289                         DateTime dt_unspecified = new DateTime (1, DateTimeKind.Unspecified);
2290                         Assert.AreEqual (1, dt_unspecified.ToBinary (), "#5");
2291                         Assert.AreEqual (1, dt_unspecified.Ticks, "#6");
2292                 }
2293
2294                 [Test]
2295                 public void RoundtripBinary ()
2296                 {
2297                         DateTime dt = DateTime.Now;
2298                         DateTime dt2 = DateTime.SpecifyKind (dt, DateTimeKind.Utc);
2299                         DateTime dt3 = DateTime.SpecifyKind (dt, DateTimeKind.Unspecified);
2300                         Assert.AreEqual (dt, DateTime.FromBinary (dt.ToBinary ()), "#1");
2301                         Assert.AreEqual (dt2, DateTime.FromBinary (dt2.ToBinary ()), "#2");
2302                         Assert.AreEqual (dt3, DateTime.FromBinary (dt3.ToBinary ()), "#3");
2303                         Assert.AreEqual (DateTimeKind.Local, DateTime.FromBinary (dt.ToBinary ()).Kind, "#4");
2304                         Assert.AreEqual (DateTimeKind.Utc, DateTime.FromBinary (dt2.ToBinary ()).Kind, "#5");
2305                         Assert.AreEqual (DateTimeKind.Unspecified, DateTime.FromBinary (dt3.ToBinary ()).Kind, "#6");
2306
2307                         Assert.AreEqual (TimeZone.CurrentTimeZone.GetUtcOffset (dt).Ticks, dt3.ToBinary () - (dt.ToBinary () & 0x7FFFFFFFFFFFFFFF), "#7");
2308                 }
2309
2310                 [Test]
2311                 public void TestMin ()
2312                 {
2313                         // This should never throw.
2314                         DateTime.MinValue.ToLocalTime ();
2315                 }
2316
2317                 [Test]
2318                 public void OmittedSecondsFraction ()
2319                 {
2320                         DateTime today = DateTime.Today;
2321                         Assert.AreEqual ("00:00:00.13579", today.AddTicks (1357900).ToString ("HH:mm:ss.FFFFFFF"), "#1");
2322                         DateTime dt = DateTime.ParseExact ("00:00:00.13579", "HH:mm:ss.FFFFFFF", CultureInfo.InvariantCulture);
2323                         Assert.AreEqual (today, dt.AddTicks (-1357900), "#2");
2324                         // it's more than strange ...
2325                         Assert.AreEqual (String.Empty, today.ToString (".FFFFFFF"), "#3");
2326                         Assert.AreEqual ("$", today.ToString ("$FFFFFFF"), "#4");
2327                 }
2328
2329                 [Test]
2330                 public void KindInPattern ()
2331                 {
2332                         // only 2.0 supports 'K'
2333                         Assert.AreEqual ("00:00:00", new DateTime (2000, 1, 1).ToString ("HH:mm:ssK"), "#1");
2334                         Assert.AreEqual ('Z', DateTime.Today.ToUniversalTime ().ToString ("HH:mm:ssK") [8], "#2");
2335                         Assert.AreEqual ("00:00:00+09:00".Length, DateTime.Today.ToString ("HH:mm:ssK").Length, "#3");
2336                 }
2337
2338                 [Test]
2339                 public void RoundtripPattern ()
2340                 {
2341                         // only 2.0 supports 'o'
2342                         Assert.AreEqual ("2000-01-01T00:00:00.0000000", new DateTime (2000, 1, 1).ToString ("o"), "#1");
2343                         Assert.AreEqual ("2000-01-01T00:00:00.0000000Z", DateTime.SpecifyKind (new DateTime (2000, 1, 1), DateTimeKind.Utc).ToString ("o"), "#2");
2344                         Assert.AreEqual ("2000-01-01T00:00:00.0000000+09:00".Length, DateTime.SpecifyKind (
2345                                 new DateTime (2000, 1, 1), DateTimeKind.Local).ToString ("o").Length, "#3");
2346
2347                         var culture = new CultureInfo ("ps-AF");
2348                         Assert.AreEqual ("1976-06-19T00:00:00.0000000", new DateTime(1976, 6, 19).ToString ("O", culture), "#4");
2349                         Assert.AreEqual ("1976-06-19T00:00:00.0000000", new DateTime(1976, 6, 19).ToString ("o", culture), "#5");
2350                 }
2351
2352                 [Test]
2353                 public void KindPattern ()
2354                 {
2355                         // no matter how the format string contains 'K' and the
2356                         // output string contains kind information, it does not
2357                         // assure that the string is parsed as roundtrip kind.
2358
2359                         // only 2.0 supports 'K'
2360                         string format = "yyyy-MM-dd'T'HH:mm:ss.fffK";
2361                         CultureInfo ci = CultureInfo.CurrentCulture;
2362                         DateTime dt = DateTime.SpecifyKind (new DateTime (2007, 11, 1, 2, 30, 45), DateTimeKind.Utc);
2363                         string s = dt.ToString (format);
2364                         DateTime d1 = DateTime.ParseExact (s, format, ci); // d1 is parsed as a local time.
2365                         Assert.AreEqual (dt.Ticks, d1.ToUniversalTime ().Ticks, "#1");
2366                         // .NET expects Local here, while s ends with 'Z' and should be parsed as UTC.
2367                         Assert.AreEqual (DateTimeKind.Local, d1.Kind, "#2");
2368
2369                         format = "yyyy-MM-dd'T'HH:mm:ssK";
2370                         ci = CultureInfo.CurrentCulture;
2371                         dt = new DateTime (2007, 11, 1, 2, 30, 45);
2372                         s = dt.ToString (format);
2373                         d1 = DateTime.ParseExact (s, format, ci);
2374                         Assert.AreEqual (dt.Ticks, d1.Ticks, "#3");
2375                         Assert.AreEqual (DateTimeKind.Unspecified, d1.Kind, "#4");
2376                 }
2377
2378                 [Test]
2379                 public void TestRoundTrip () {
2380                         DateTime result;
2381                         DateTimeStyles roundTripStyle = DateTimeStyles.RoundtripKind;
2382                         string utcDate = "2008-02-21T11:14:18.2721262Z";
2383                         string localDate = "2008-02-21T11:14:18.2721262+02:00";
2384                         string unspec = "2008-02-21T11:14:18.2721262";
2385                         String [] formats = {"yyyy-MM-ddTHH:mm:ssK", "yyyy-MM-ddTHH:mm:ss.FFFFFFFK"};
2386
2387                         result = DateTime.ParseExact (localDate, formats, CultureInfo.InvariantCulture, roundTripStyle);
2388                         Assert.AreEqual (result.Kind, DateTimeKind.Local);
2389                         Assert.AreEqual (result.ToUniversalTime ().Ticks, 633391820582721262);
2390                         
2391                         result = DateTime.ParseExact (unspec, formats, CultureInfo.InvariantCulture, roundTripStyle);
2392                         Assert.AreEqual (result.Kind, DateTimeKind.Unspecified);
2393                         Assert.AreEqual (result.Ticks, 633391892582721262);
2394                         
2395                         result = DateTime.ParseExact (utcDate, formats, CultureInfo.InvariantCulture, roundTripStyle);
2396                         Assert.AreEqual (result.Kind, DateTimeKind.Utc);
2397                         Assert.AreEqual (result.Ticks, 633391892582721262);
2398
2399                 }               
2400
2401                 [Test]
2402                 public void TestRegularStyle () {
2403                         DateTime result;
2404                         DateTimeStyles style = DateTimeStyles.AllowLeadingWhite | DateTimeStyles.AllowTrailingWhite;
2405                         string utcDate = "2008-02-21T11:14:18.2721262Z";
2406                         string localDate = "2008-02-21T11:14:18.2721262+02:00";
2407                         string unspec = "2008-02-21T11:14:18.2721262";
2408                         String [] formats = {"yyyy-MM-ddTHH:mm:ssK", "yyyy-MM-ddTHH:mm:ss.FFFFFFFK"};
2409
2410                         result = DateTime.ParseExact (localDate, formats, CultureInfo.InvariantCulture, style);
2411                         Assert.AreEqual (result.Kind, DateTimeKind.Local);
2412                         Assert.AreEqual (result.ToUniversalTime ().Ticks, 633391820582721262);
2413
2414                         result = DateTime.ParseExact (unspec, formats, CultureInfo.InvariantCulture, style);
2415                         Assert.AreEqual (result.Kind, DateTimeKind.Unspecified);                        
2416                         Assert.AreEqual (result.Ticks, 633391892582721262);
2417
2418                         result = DateTime.ParseExact (utcDate, formats, CultureInfo.InvariantCulture, style);
2419                         Assert.AreEqual (result.Kind, DateTimeKind.Local);
2420                         Assert.AreEqual (result.ToUniversalTime ().Ticks, 633391892582721262);
2421                 }
2422
2423                 [Test]
2424                 public void TestAssumeLocal () {
2425                         DateTime result;
2426                         DateTimeStyles assumeLocal =  DateTimeStyles.AssumeLocal;
2427                         string utcDate = "2008-02-21T11:14:18.2721262Z";
2428                         string localDate = "2008-02-21T11:14:18.2721262+02:00";
2429                         string unspec = "2008-02-21T11:14:18.2721262";
2430                         String [] formats = {"yyyy-MM-ddTHH:mm:ssK", "yyyy-MM-ddTHH:mm:ss.FFFFFFFK"};
2431
2432                         result = DateTime.ParseExact (localDate, formats, CultureInfo.InvariantCulture, assumeLocal);
2433                         Assert.AreEqual (result.Kind, DateTimeKind.Local);
2434                         Assert.AreEqual (result.ToUniversalTime ().Ticks, 633391820582721262);
2435
2436                         result = DateTime.ParseExact (unspec, formats, CultureInfo.InvariantCulture, assumeLocal);
2437                         Assert.AreEqual (result.Kind, DateTimeKind.Local);
2438                         Assert.AreEqual (result.Ticks, 633391892582721262);
2439
2440                         result = DateTime.ParseExact (utcDate, formats, CultureInfo.InvariantCulture, assumeLocal);
2441                         Assert.AreEqual (result.Kind, DateTimeKind.Local);
2442                         Assert.AreEqual (result.ToUniversalTime ().Ticks, 633391892582721262);
2443                 }
2444
2445                 [Test]
2446                 [ExpectedException (typeof (ArgumentException))]
2447                 public void IllegalStyleCombination1()
2448                 {
2449                         DateTimeStyles illegal = DateTimeStyles.RoundtripKind | DateTimeStyles.AssumeLocal;
2450                         DateTime.ParseExact ("", "", null, illegal);                    
2451                 }
2452
2453                 [Test]
2454                 [ExpectedException (typeof (ArgumentException))]
2455                 public void IllegalStyleCombination2()
2456                 {
2457                         DateTimeStyles illegal = DateTimeStyles.RoundtripKind | DateTimeStyles.AdjustToUniversal;
2458                         DateTime.ParseExact ("", "", null, illegal);
2459                 }
2460
2461                 [Test]
2462                 [ExpectedException (typeof (ArgumentException))]
2463                 public void IllegalStyleCombination3()
2464                 {
2465                         DateTimeStyles illegal = DateTimeStyles.RoundtripKind | DateTimeStyles.AssumeUniversal;
2466                         DateTime.ParseExact ("", "", null, illegal);
2467                 }
2468
2469                 [Test]
2470                 [ExpectedException (typeof (ArgumentException))]
2471                 public void IllegalStyleCombination4()
2472                 {
2473                         DateTimeStyles illegal = DateTimeStyles.AssumeLocal | DateTimeStyles.AssumeUniversal;
2474                         DateTime.ParseExact ("", "", null, illegal);
2475                 }
2476
2477                 [Test]
2478                 [ExpectedException (typeof (FormatException))]
2479                 public void TrailingDot ()
2480                 {
2481                         DateTime.ParseExact ("12:00:00", "HH:mm:ss.", null);
2482                 }
2483
2484                 [Test]
2485                 public void TrailingFlexibleMilliseconds ()
2486                 {
2487                         // bug #444103.
2488                         DateTime.ParseExact ("12:00:00", "HH:mm:ss.FFFFFFF", null);
2489                 }
2490                
2491                 [Test]
2492                 public void TryParseExact_NullString ()
2493                 {
2494                         DateTime dt;
2495                         DateTime.TryParseExact(null, "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'", CultureInfo.InvariantCulture,
2496                                                DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out dt);
2497                         Assert.AreEqual(default(DateTime), dt);
2498                 }
2499
2500                 [Test]
2501                 public void MSAndZ ()
2502                 {
2503                         CultureInfo cultureInfo = CultureInfo.GetCultureInfo ("en-US");
2504                         DateTime dt;
2505                         if (!DateTime.TryParse ("2009.02.24T13:57:07.000 -0800", cultureInfo.DateTimeFormat,
2506                                                 DateTimeStyles.None, out dt))
2507                                 Assert.Fail ("Failed");
2508                 }
2509
2510                 [Test]
2511                 public void Parse_InvalidShortDate ()
2512                 {
2513                         DateTime expected = new DateTime (2011, 03, 22, 07, 32, 00, DateTimeKind.Utc).ToLocalTime();
2514                         DateTime expected2 = new DateTime (2011, 03, 22, 08, 32, 00, DateTimeKind.Utc);
2515
2516                         string [] cultures = new string [] {"es-ES", "en-US", "en-GB", "de-DE", "fr-FR"
2517 #if NET_4_0
2518                                 ,"es", "en", "de", "fr"
2519 #endif
2520                                 };
2521                         
2522                         foreach (string culture in cultures) {
2523                                 CultureInfo ci = new CultureInfo (culture);
2524                                 ci.DateTimeFormat.ShortDatePattern = "d";
2525
2526                                 Assert.AreEqual (expected,  DateTime.Parse ("2011-03-22 08:32:00+01:00", ci, DateTimeStyles.RoundtripKind), "#a01 - " + culture);
2527                                 Assert.AreEqual (expected,  DateTime.Parse ("2011/03/22 08:32:00+01:00", ci, DateTimeStyles.RoundtripKind), "#a02 - " + culture);
2528                                 Assert.AreEqual (expected2, DateTime.Parse ("2011-03-22T08:32:00", ci, DateTimeStyles.RoundtripKind), "#a03 - " + culture);
2529                                 Assert.AreEqual (expected2, DateTime.Parse ("2011/03/22T08:32:00", ci, DateTimeStyles.RoundtripKind), "#a04 - " + culture);
2530                                 Assert.AreEqual (expected2, DateTime.Parse ("03/2011/22T08:32:00", ci, DateTimeStyles.RoundtripKind), "#a05 - " + culture);
2531                                 Assert.AreEqual (expected2, DateTime.Parse ("03-2011-22T08:32:00", ci, DateTimeStyles.RoundtripKind), "#a06 - " + culture);
2532                                 Assert.AreEqual (expected,  DateTime.Parse ("03/2011/22 08:32:00+01:00", ci, DateTimeStyles.RoundtripKind), "#a07 - " + culture);
2533                                 ci.DateTimeFormat.DateSeparator = "%";
2534                                 Assert.AreEqual (expected,  DateTime.Parse ("2011-03-22 08:32:00+01:00", ci, DateTimeStyles.RoundtripKind), "#b01 - " + culture);
2535                                 Assert.AreEqual (expected,  DateTime.Parse ("2011/03/22 08:32:00+01:00", ci, DateTimeStyles.RoundtripKind), "#b02 - " + culture);
2536                                 Assert.AreEqual (expected2, DateTime.Parse ("2011-03-22T08:32:00", ci, DateTimeStyles.RoundtripKind), "#b03 - " + culture);
2537                                 Assert.AreEqual (expected2, DateTime.Parse ("2011/03/22T08:32:00", ci, DateTimeStyles.RoundtripKind), "#b04 - " + culture);
2538                                 Assert.AreEqual (expected2, DateTime.Parse ("03/2011/22T08:32:00", ci, DateTimeStyles.RoundtripKind), "#b05 - " + culture);
2539                                 Assert.AreEqual (expected2, DateTime.Parse ("03-2011-22T08:32:00", ci, DateTimeStyles.RoundtripKind), "#b06 - " + culture);
2540                                 Assert.AreEqual (expected,  DateTime.Parse ("03/2011/22 08:32:00+01:00", ci, DateTimeStyles.RoundtripKind), "#b07 - " + culture);
2541                         }
2542                 }
2543
2544                 // Bug 3392
2545                 [Test]
2546                 public void Parse_DateWithTimeZone_TimeZoneShouldBeCorrectlyRead ()
2547                 {
2548                         string testDateWithTimeZoneInfo  = "2012-01-14T15:09:42.692875+03:00";
2549                         long expectedUtcTics = 634621397826928750;
2550
2551                         DateTimeOffset result = DateTimeOffset.Parse (testDateWithTimeZoneInfo, null, DateTimeStyles.RoundtripKind);
2552
2553                         Assert.AreEqual (expectedUtcTics, result.UtcTicks);
2554                 }
2555                 
2556                 [Test]
2557                 public void Foo ()
2558                 {
2559                         var ci = new CultureInfo ("ru-RU");
2560                         var dt = new DateTime (2012, 9, 15);
2561                         Assert.AreEqual ("сентября 15", dt.ToString ("m", ci));
2562                 }
2563         }
2564 }