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