2009-07-11 Michael Barker <mike@middlesoft.co.uk>
[mono.git] / mcs / class / corlib / Test / System / DateTimeOffsetTest.cs
1 //
2 // DateTimeOffsetTest.cs - NUnit Test Cases for the System.DateTimeOffset struct
3 //
4 // Authors:
5 //      Stephane Delcroix  (sdelcroix@novell.com)
6 //
7 // Copyright (C) 2007 Novell, Inc (http://www.novell.com)
8 //
9
10 #if NET_2_0
11 using System.Globalization;
12 using NUnit.Framework;
13 using System;
14
15 namespace MonoTests.System {
16
17         [TestFixture]
18         public class DateTimeOffsetTest
19         {
20                 //ctor exception checking...
21                 [Test]
22                 [ExpectedException (typeof (ArgumentException))]
23                 public void UtcWithWrongOffset ()
24                 {
25                         DateTime dt = DateTime.SpecifyKind (DateTime.Now, DateTimeKind.Utc);
26                         TimeSpan offset = new TimeSpan (2, 0, 0);
27                         new DateTimeOffset (dt, offset);
28                 }
29
30                 [Test]
31                 [ExpectedException (typeof (ArgumentException))]
32                 public void LocalWithWrongOffset ()
33                 {
34                         DateTime dt = DateTime.SpecifyKind (DateTime.Now, DateTimeKind.Local);
35                         TimeSpan offset = TimeZone.CurrentTimeZone.GetUtcOffset (dt) + new TimeSpan (1,0,0);
36                         new DateTimeOffset (dt, offset);
37                 }
38
39                 [Test]
40                 [ExpectedException (typeof (ArgumentException))]
41                 public void OffsetNotInWholeminutes ()
42                 {
43                         DateTime dt = DateTime.SpecifyKind (DateTime.Now, DateTimeKind.Unspecified);
44                         TimeSpan offset = new TimeSpan (1,0,59);
45                         new DateTimeOffset (dt, offset);
46                 }
47
48                 [Test]
49                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
50                 public void OffsetOutOfRange1 ()
51                 {
52                         DateTime dt = DateTime.SpecifyKind (DateTime.Now, DateTimeKind.Unspecified);
53                         TimeSpan offset = new TimeSpan (14, 1, 0);
54                         new DateTimeOffset (dt, offset);
55                 }
56
57                 [Test]
58                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
59                 public void OffsetOutOfRange2 ()
60                 {
61                         DateTime dt = DateTime.SpecifyKind (DateTime.Now, DateTimeKind.Unspecified);
62                         TimeSpan offset = new TimeSpan (-14, -1, 0);
63                         new DateTimeOffset (dt, offset);
64                 }
65
66                 [Test]
67                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
68                 public void UtcDateTimeOutOfRange1 ()
69                 {
70                         DateTime dt = DateTime.SpecifyKind (DateTime.MinValue, DateTimeKind.Unspecified);
71                         TimeSpan offset = new TimeSpan (1, 0, 0);
72                         new DateTimeOffset (dt, offset);
73                 }
74
75                 [Test]
76                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
77                 public void UtcDateTimeOutOfRange2 ()
78                 {
79                         DateTime dt = DateTime.SpecifyKind (DateTime.MaxValue, DateTimeKind.Unspecified);
80                         TimeSpan offset = new TimeSpan (-1, 0, 0);
81                         new DateTimeOffset (dt, offset);
82                 }
83
84                 [Test]
85                 public void CompareTwoDateInDiffTZ ()
86                 {
87                         DateTimeOffset dt1 = new DateTimeOffset (2007, 12, 16, 15, 06, 00, new TimeSpan (1, 0, 0));
88                         DateTimeOffset dt2 = new DateTimeOffset (2007, 12, 16, 9, 06, 00, new TimeSpan (-5, 0, 0));
89                         DateTimeOffset dt3 = new DateTimeOffset (2007, 12, 16, 14, 06, 00, new TimeSpan (1, 0, 0));
90                         object o = dt1;
91                         Assert.IsTrue (dt1.CompareTo (dt2) == 0);
92                         Assert.IsTrue (DateTimeOffset.Compare (dt1, dt2) == 0);
93                         Assert.IsTrue (dt1 == dt2);
94                         Assert.IsTrue (dt1.Equals (dt2));
95                         Assert.IsFalse (dt1 == dt3);
96                         Assert.IsTrue (dt1 != dt3);
97                         Assert.IsFalse (dt1.EqualsExact (dt2));
98                         Assert.IsTrue (dt1.CompareTo (dt3) > 0);
99                         Assert.IsTrue (((IComparable)dt1).CompareTo (o) == 0);
100                 }
101
102                 [Test]
103                 public void UtcDateTime ()
104                 {
105                         DateTimeOffset dt = new DateTimeOffset (2007, 12, 16, 15, 49, 00, new TimeSpan (1, 0, 0));
106                         object o = dt.UtcDateTime;
107                         Assert.IsTrue (o is DateTime);
108                         Assert.IsTrue (dt.UtcDateTime == new DateTime (2007,12,16,14,49,00,DateTimeKind.Utc));
109                 }
110
111                 [Test]
112                 public void ParameterlessToString ()
113                 {
114                         DateTimeOffset dt = new DateTimeOffset (2007, 12, 18, 12, 16, 30, new TimeSpan (1, 0, 0));
115                         Assert.AreEqual ("12/18/2007 12:16:30 PM +01:00", dt.ToString (new CultureInfo ("en-us")));
116                         dt = new DateTimeOffset (2007, 12, 18, 12, 16, 30, new TimeSpan (-5, 0, 0));
117                         Assert.AreEqual ("12/18/2007 12:16:30 PM -05:00", dt.ToString (new CultureInfo ("en-us")));
118                         dt = new DateTimeOffset (2007, 12, 18, 12, 16, 30, TimeSpan.Zero);
119                         Assert.AreEqual ("12/18/2007 12:16:30 PM +00:00", dt.ToString (new CultureInfo ("en-us")));
120                 }
121
122                 [Test]
123                 public void ToStringWithCultureInfo ()
124                 {
125                         DateTimeOffset dto = new DateTimeOffset(2007, 5, 1, 9, 0, 0, TimeSpan.Zero);
126                         Assert.AreEqual ("05/01/2007 09:00:00 +00:00", dto.ToString (CultureInfo.InvariantCulture));
127                         Assert.AreEqual ("5/1/2007 9:00:00 AM +00:00", dto.ToString (new CultureInfo ("en-us")));
128                         Assert.AreEqual ("01/05/2007 09:00:00 +00:00", dto.ToString (new CultureInfo ("fr-fr")));
129                         Assert.AreEqual ("01.05.2007 09:00:00 +00:00", dto.ToString (new CultureInfo ("de-DE")));
130                         Assert.AreEqual ("01/05/2007 9:00:00 +00:00", dto.ToString (new CultureInfo ("es-ES")));
131                 }
132
133                 [Test]
134                 [ExpectedException (typeof (FormatException))]
135                 public void ToStringExceptionalCase1 ()
136                 {
137                         DateTimeOffset.Now.ToString (";");
138                 }
139
140                 [Test]
141                 [ExpectedException (typeof (FormatException))]
142                 public void ToStringExceptionalCase2 ()
143                 {
144                         DateTimeOffset.Now.ToString ("U");
145                 }
146
147                 [Test]
148                 public void ToStringWithFormat ()
149                 {
150                         DateTimeOffset dto = new DateTimeOffset (2007, 10, 31, 21, 0, 0, new TimeSpan(-8, 0, 0));
151                         Assert.AreEqual ("10/31/2007", dto.ToString ("d", new CultureInfo ("en-us")));
152                         Assert.AreEqual ("Wednesday, October 31, 2007", dto.ToString ("D", new CultureInfo ("en-us")));
153                         Assert.AreEqual ("9:00 PM", dto.ToString ("t", new CultureInfo ("en-us")));
154                         Assert.AreEqual ("9:00:00 PM", dto.ToString ("T", new CultureInfo ("en-us")));
155                         Assert.AreEqual ("Wednesday, October 31, 2007 9:00 PM", dto.ToString ("f", new CultureInfo ("en-us")));
156                         Assert.AreEqual ("Wednesday, October 31, 2007 9:00:00 PM", dto.ToString ("F", new CultureInfo ("en-us")));
157                         Assert.AreEqual ("10/31/2007 9:00 PM", dto.ToString ("g", new CultureInfo ("en-us")));
158                         Assert.AreEqual ("10/31/2007 9:00:00 PM", dto.ToString ("G", new CultureInfo ("en-us")));
159                         Assert.AreEqual ("October 31", dto.ToString ("M", new CultureInfo ("en-us")));
160                         Assert.AreEqual (dto.ToString ("m", new CultureInfo ("en-us")), dto.ToString ("M", new CultureInfo ("en-us")));
161                         Assert.AreEqual ("Thu, 01 Nov 2007 05:00:00 GMT", dto.ToString ("R", new CultureInfo ("en-us")));
162                         Assert.AreEqual (dto.ToString ("r", new CultureInfo ("en-us")), dto.ToString ("R", new CultureInfo ("en-us")));
163                         Assert.AreEqual ("2007-10-31T21:00:00", dto.ToString ("s", new CultureInfo ("en-us")));
164                         Assert.AreEqual ("2007-11-01 05:00:00Z", dto.ToString ("u", new CultureInfo ("en-us")));
165                         Assert.AreEqual ("October, 2007", dto.ToString ("Y", new CultureInfo ("en-us")));
166                         Assert.AreEqual (dto.ToString ("y", new CultureInfo ("en-us")), dto.ToString ("Y", new CultureInfo ("en-us")));
167                 }
168
169                 [Test]
170                 public void ToStringWithFormatAndCulture ()
171                 {
172                         DateTimeOffset dto = new DateTimeOffset (2007, 11, 1, 9, 0, 0, new TimeSpan(-7, 0, 0));
173                         string format = "dddd, MMM dd yyyy HH:mm:ss zzz";
174                         if (CultureInfo.CurrentCulture == CultureInfo.InvariantCulture)
175                                 Assert.AreEqual ("Thursday, Nov 01 2007 09:00:00 -07:00", dto.ToString (format, null as DateTimeFormatInfo), "ts1");
176                         Assert.AreEqual ("Thursday, Nov 01 2007 09:00:00 -07:00", dto.ToString (format, CultureInfo.InvariantCulture), "ts2");
177                         Assert.AreEqual ("jeudi, nov. 01 2007 09:00:00 -07:00", dto.ToString (format, new CultureInfo ("fr-FR")), "ts3");
178                         Assert.AreEqual ("jueves, nov 01 2007 09:00:00 -07:00", dto.ToString (format, new CultureInfo ("es-ES")), "ts4");
179                 }
180
181                 [Test]
182                 public void ParseExactDatesOnly ()
183                 {
184                         DateTimeOffset dto = DateTimeOffset.Now;
185                         CultureInfo fp = CultureInfo.InvariantCulture;
186
187                         string[] formats = {
188                                 "d",
189                                 "M/dd/yyyy",
190                                 "M/d/y",
191                                 "M/d/yy",
192                                 "M/d/yyy",
193                                 "M/d/yyyy",
194                                 "M/d/yyyyy",
195                                 "M/d/yyyyyy",
196                                 "M/dd/yyyy",
197                                 "MM/dd/yyyy",
198                         };
199
200                         foreach (string format in formats)
201                         {
202                                 string serialized = dto.ToString (format, fp);
203                                 //Console.WriteLine ("{0} {1} {2}", format, dto, serialized);
204                                 Assert.AreEqual (dto.Date, DateTimeOffset.ParseExact (serialized, format, fp).Date, format);
205
206                         }
207                 }
208
209                 [Test]
210                 public void ParseExactTest ()
211                 {
212                         CultureInfo fp = CultureInfo.InvariantCulture;
213                         DateTimeOffset[] dtos = {
214                                 new DateTimeOffset (2008, 01, 14, 13, 21, 0, new TimeSpan (1,0,0)),
215                                 new DateTimeOffset (2008, 01, 14, 13, 21, 0, new TimeSpan (-5,0,0)),
216                         };
217
218                         string[] formats = {
219                                 "M/dd/yyyy HH:m zzz",  "MM/dd/yyyy HH:m zzz",
220                                 "M/d/yyyy HH:m zzz",   "MM/d/yyyy HH:m zzz",
221                                 "M/dd/yy HH:m zzz",    "MM/dd/yy HH:m zzz",
222                                 "M/d/yy HH:m zzz",     "M/d/yy HH:m zzz",
223                                 "M/dd/yyyy H:m zzz",   "MM/dd/yyyy H:m zzz",
224                                 "M/d/yyyy H:m zzz",    "MM/d/yyyy H:m zzz",
225                                 "M/dd/yy H:m zzz",     "MM/dd/yy H:m zzz",
226                                 "M/d/yy H:m zzz",      "MM/d/yy H:m zzz",
227                                 "M/dd/yyyy HH:mm zzz", "MM/dd/yyyy HH:mm zzz",
228                                 "M/d/yyyy HH:mm zzz",  "MM/d/yyyy HH:mm zzz",
229                                 "M/dd/yy HH:mm zzz",   "MM/dd/yy HH:mm zzz",
230                                 "M/d/yy HH:mm zzz",    "M/d/yy HH:mm zzz",
231                                 "M/dd/yyyy H:m zzz",   "MM/dd/yyyy H:m zzz",
232                                 "M/d/yyyy H:m zzz",    "MM/d/yyyy H:m zzz",
233                                 "M/dd/yy H:m zzz",     "MM/dd/yy H:m zzz",
234                                 "M/d/yy H:m zzz",      "M/d/yy H:m zzz",
235                                 "ddd dd MMM yyyy h:mm tt zzz", 
236                         };
237
238                         foreach (DateTimeOffset dto in dtos)
239                                 foreach (string format in formats)
240                                 {
241                                         string serialized = dto.ToString (format, fp);
242                                         //Console.WriteLine ("{0} {1} {2}", format, dto, serialized);
243                                         Assert.AreEqual (dto, DateTimeOffset.ParseExact (serialized, format, fp), format);
244                                 }
245                 }
246                 [Test]
247                 public void ParseExactYearFormat ()
248                 {
249                         CultureInfo fp = CultureInfo.InvariantCulture;
250                         DateTimeOffset[] dtos = {
251                                 new DateTimeOffset (2008, 01, 14, 13, 21, 0, new TimeSpan (1,0,0)),
252                                 new DateTimeOffset (2008, 01, 14, 13, 21, 0, new TimeSpan (-5,0,0)),
253                                 new DateTimeOffset (1978, 02, 16, 13, 21, 0, new TimeSpan (2,0,0)),
254                                 new DateTimeOffset (999, 9, 9, 9, 9, 0, new TimeSpan (3,0,0)),
255                         };
256
257                         string[] formats = {
258                                 "M/d/yyy H:m zzz",
259                                 "M/d/yyyy H:m zzz",
260                                 "M/d/yyyyy H:m zzz",
261                                 "M/d/yyyyyy H:m zzz",
262                                 "M/d/yyyyyyy H:m zzz",
263                         };
264
265                         foreach (DateTimeOffset dto in dtos)
266                                 foreach (string format in formats)
267                                 {
268                                         string serialized = dto.ToString (format, fp);
269                                         //Console.WriteLine ("{0} {1} {2}", format, dto, serialized);
270                                         Assert.AreEqual (dto, DateTimeOffset.ParseExact (serialized, format, fp), format);
271                                 }
272                         
273                 }
274
275                 [Test]
276                 [ExpectedException (typeof (FormatException))]
277                 public void ParseExactYearException ()
278                 {
279                         CultureInfo fp = CultureInfo.InvariantCulture;
280                         string format = "M/d/yyyy H:m zzz";
281                         string date = "1/15/999 10:58 +01:00";
282                         DateTimeOffset.ParseExact(date, format, fp);    
283                 }
284
285                 [Test]
286                 [ExpectedException (typeof (FormatException))]
287                 public void ParseExactFormatException1 ()
288                 {
289                         CultureInfo fp = CultureInfo.InvariantCulture;
290                         string format = "d";
291                         string date = "1/14/2008";
292                         DateTimeOffset.ParseExact(date, format, fp);
293                 }
294
295                 [Test]
296                 [ExpectedException (typeof (FormatException))]
297                 public void ParseExactFormatException2 ()
298                 {
299                         CultureInfo fp = CultureInfo.InvariantCulture;
300                         string format = "ddd dd MMM yyyy h:mm tt zzz";
301                         string date = "Mon 14 Jan 2008 2:56 PM +01";
302                         DateTimeOffset.ParseExact(date, format, fp);
303                 }
304
305                 [Test]
306                 [ExpectedException (typeof (FormatException))]
307                 public void ParseExactFormatException3 ()
308                 {
309                         CultureInfo fp = CultureInfo.InvariantCulture;
310                         string format = "ddd dd MMM yyyy h:mm tt zzz";
311                         string date = "Mon 14 Jan 2008 2:56 PM +01:1";
312                         DateTimeOffset.ParseExact(date, format, fp);
313                 }
314
315                 [Test]
316                 [ExpectedException (typeof (FormatException))]
317                 public void ParseExactFormatException4 ()
318                 {
319                         CultureInfo fp = CultureInfo.InvariantCulture;
320                         string format = "ddd dd MMM yyyy h:mm tt zzz";
321                         string date = "Mon 14 Jan 2008 2:56 PM +01: 00";
322                         DateTimeOffset.ParseExact(date, format, fp);
323                 }
324
325                 [Test]
326                 public void ParseExactWithSeconds ()
327                 {
328                         CultureInfo fp = CultureInfo.InvariantCulture;
329                         DateTimeOffset[] dtos = {
330                                 new DateTimeOffset (2008, 01, 14, 13, 21, 25, new TimeSpan (1,0,0)),
331                                 new DateTimeOffset (2008, 01, 14, 13, 21, 5, new TimeSpan (-5,0,0)),
332                         };
333
334                         string[] formats = {
335                                 "dddd, dd MMMM yyyy HH:mm:ss zzz",
336                         };
337
338                         foreach (DateTimeOffset dto in dtos)
339                                 foreach (string format in formats)
340                                 {
341                                         string serialized = dto.ToString (format, fp);
342                                         //Console.WriteLine ("{0} {1} {2}", format, dto, serialized);
343                                         Assert.AreEqual (dto, DateTimeOffset.ParseExact (serialized, format, fp), format);
344                                 }
345                 }
346
347                 [Test]
348                 public void ParseDateOnly ()
349                 {
350                         DateTimeOffset dto = DateTimeOffset.Parse ("2009/06/14");
351                         Assert.AreEqual (14, dto.Day, "Day");
352                         Assert.AreEqual (6, dto.Month, "Month");
353                         Assert.AreEqual (2009, dto.Year, "Year");
354                 }
355
356                 [Test]
357                 public void ParseTimeOnly ()
358                 {
359                         DateTimeOffset dto = DateTimeOffset.Parse ("2:3:4");
360                         Assert.AreEqual (2, dto.Hour, "Hour");
361                         Assert.AreEqual (3, dto.Minute, "Minute");
362                         Assert.AreEqual (4, dto.Second, "Second");
363                 }
364
365                 [Test]
366                 public void ParseTimeTZ ()
367                 {
368                         DateTimeOffset dto = DateTimeOffset.Parse ("2:30:40 +3:4");
369                         Assert.AreEqual (2, dto.Hour, "Hour");
370                         Assert.AreEqual (30, dto.Minute, "Minute");
371                         Assert.AreEqual (40, dto.Second, "Second");
372                         Assert.AreEqual (3, dto.Offset.Hours, "Offset Hours");
373                         Assert.AreEqual (4, dto.Offset.Minutes, "Offset Minutes");
374                 }
375
376                 [Test]
377                 public void ParseTimePMTZ ()
378                 {
379                         DateTimeOffset dto = DateTimeOffset.Parse ("3:30:40 PM -3:4");
380                         Assert.AreEqual (15, dto.Hour, "Hour");
381                         Assert.AreEqual (30, dto.Minute, "Minute");
382                         Assert.AreEqual (40, dto.Second, "Second");
383                         Assert.AreEqual (-3, dto.Offset.Hours, "Offset Hours");
384                         Assert.AreEqual (-4, dto.Offset.Minutes, "Offset Minutes");
385                 }
386
387                 [Test]
388                 public void ParseFull1 ()
389                 {
390                         DateTimeOffset dto = DateTimeOffset.Parse ("2009/06/14 2:30:40 AM -03:04");
391                         Assert.AreEqual (14, dto.Day, "Day");
392                         Assert.AreEqual (6, dto.Month, "Month");
393                         Assert.AreEqual (2009, dto.Year, "Year");
394                         Assert.AreEqual (2, dto.Hour, "Hour");
395                         Assert.AreEqual (30, dto.Minute, "Minute");
396                         Assert.AreEqual (40, dto.Second, "Second");
397                         Assert.AreEqual (-3, dto.Offset.Hours, "Offset Hours");
398                         Assert.AreEqual (-4, dto.Offset.Minutes, "Offset Minutes");
399                 }
400
401                 [Test]
402                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
403                 public void ParseUnderflow ()
404                 {
405                         DateTimeOffset.Parse ("01/01/0001 0:0 +09:00");
406                 }
407
408                 [Test]
409                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
410                 public void ParseOverflow ()
411                 {
412                         DateTimeOffset.Parse ("12/31/9999 23:59 -09:00");
413                 }
414
415                 [Test]
416                 public void ParseExactWithFractions ()
417                 {
418                         CultureInfo fp = CultureInfo.InvariantCulture;
419                         DateTimeOffset[] dtos = {
420                                 new DateTimeOffset (2008, 1, 15, 14, 36, 44, 900, TimeSpan.Zero),
421                         };
422
423                         string[] formats = {
424                                 "M/d/yyyy H:m:ss,f zzz",
425                                 "M/d/yyyy H:m:ss,ff zzz",
426                                 "M/d/yyyy H:m:ss,fff zzz",
427                                 "M/d/yyyy H:m:ss,ffff zzz",
428                                 "M/d/yyyy H:m:ss,fffff zzz",
429                                 "M/d/yyyy H:m:ss,ffffff zzz",
430                                 "M/d/yyyy H:m:ss,fffffff zzz",
431                                 "M/d/yyyy H:m:ss,F zzz",
432                                 "M/d/yyyy H:m:ss,FF zzz",
433                                 "M/d/yyyy H:m:ss,FFF zzz",
434                                 "M/d/yyyy H:m:ss,FFFF zzz",
435                                 "M/d/yyyy H:m:ss,FFFFF zzz",
436                                 "M/d/yyyy H:m:ss,FFFFFF zzz",
437                                 "M/d/yyyy H:m:ss,FFFFFFF zzz",
438                         };
439
440                         foreach (DateTimeOffset dto in dtos)
441                                 foreach (string format in formats)
442                                 {
443                                         string serialized = dto.ToString (format, fp);
444                                         //Console.WriteLine ("{0} {1} {2}", format, dto, serialized);
445                                         Assert.AreEqual (dto, DateTimeOffset.ParseExact (serialized, format, fp), format);
446                                 }
447                 }
448
449                 [Test]
450                 public void EqualsObject ()
451                 {
452                         DateTimeOffset offset1 = new DateTimeOffset ();
453                         Assert.IsFalse (offset1.Equals (null), "null"); // found using Gendarme :)
454                         Assert.IsTrue (offset1.Equals (offset1), "self");
455                         DateTimeOffset offset2 = new DateTimeOffset (DateTime.Today);
456                         Assert.IsFalse (offset1.Equals (offset2), "1!=2");
457                         Assert.IsFalse (offset2.Equals (offset1), "2!=1");
458                 }
459
460                 [Test]
461                 public void Serialization()
462                 {
463                         global::System.IO.MemoryStream dst = new global::System.IO.MemoryStream ();
464                         global::System.Runtime.Serialization.IFormatter fmtr
465                                 = new global::System.Runtime.Serialization.Formatters.Binary.BinaryFormatter ();
466                         for (int i = 0; i < SerializationCases.Length; ++i) {
467                                 dst.SetLength (0);
468                                 DateTimeOffset cur = SerializationCases[i].Input;
469                                 fmtr.Serialize (dst, cur);
470                                 String result = BitConverter.ToString (dst.GetBuffer (), 0, (int)dst.Length);
471                                 Assert.AreEqual (SerializationCases[i].ResultBinaryString, result, "resultToString #" + i);
472                         }//for
473                 }
474
475                 [Test]
476                 public void Deserialization()
477                 {
478                         global::System.Runtime.Serialization.IFormatter fmtr
479                                 = new global::System.Runtime.Serialization.Formatters.Binary.BinaryFormatter ();
480                         global::System.IO.MemoryStream src;
481                         for (int i = 0; i < SerializationCases.Length; ++i) {
482                                 src = new global::System.IO.MemoryStream (
483                                         BitConverter_ByteArray_FromString (SerializationCases[i].ResultBinaryString));
484                                 DateTimeOffset result = (DateTimeOffset)fmtr.Deserialize (src);
485 #if false // DUMP_TO_CONSOLE
486                                 Console.WriteLine ("#{0} input.o/s : {1}", i, SerializationCases[i].Input.Offset);
487                                 Console.WriteLine ("#{0} result.o/s: {1}", i, result.Offset);
488                                 Console.WriteLine ("#{0} input.dt : {1}={1:R}={1:u}", i, SerializationCases[i].Input.DateTime);
489                                 Console.WriteLine ("#{0} result.dt: {1}={1:R}={1:u}", i, result.DateTime);
490                                 Console.WriteLine ("#{0} input.dtK: {1}", i, SerializationCases[i].Input.DateTime.Kind);
491                                 Console.WriteLine ("#{0} input : {1}={1:R}={1:u}", i, SerializationCases[i].Input);
492                                 Console.WriteLine ("#{0} result: {1}={1:R}={1:u}", i, result);
493 #endif
494                                 Assert.AreEqual (SerializationCases[i].Input.Offset, result.Offset, ".Offset #" + i);
495                                 Assert.AreEqual (SerializationCases[i].Input.DateTime, result.DateTime, ".DateTime #" + i);
496                                 Assert.AreEqual (SerializationCases[i].Input, result, "equals #" + i);
497                                 // DateTimeOffset always stores as Kind==Unspecified
498                                 Assert.AreEqual (DateTimeKind.Unspecified, SerializationCases[i].Input.DateTime.Kind, ".DateTime.Kind==unspec #" + i);
499                                 Assert.AreEqual (SerializationCases[i].Input.DateTime.Kind, result.DateTime.Kind, ".DateTime.Kind #" + i);
500                         }//for
501                 }
502
503                 public class TestRow
504                 {
505                         public DateTimeOffset Input;
506                         public String ResultBinaryString;
507
508                         public TestRow(DateTimeOffset input, String resultBinaryString)
509                         {
510                                 this.Input = input;
511                                 this.ResultBinaryString = resultBinaryString;
512                         }
513                 }
514                 readonly TestRow[] SerializationCases = {
515                         // Multiple tests of Unspecified and different timezone offsets; one 
516                         // for UTC; and one for Local which is disabled as it suits only a machine
517                         // in GMT or similar.
518 #if ___MACHINE_TIMEZONE_HAS_ZERO_OFFSET
519                         // The "new DateTimeOffset(new DateTime(...)))" expression results in a 
520                         // DTO that has an offset set to the machine timezone offset.  So, as 
521                         // with the test case at the bottom we can't test this around the world.
522                         new TestRow (new DateTimeOffset (new DateTime (2007, 01, 02, 12, 30, 50)),
523                                 "00-01-00-00-00-FF-FF-FF-FF-01-00-00-00-00-00-00-"
524                                 + "00-04-01-00-00-00-15-53-79-73-74-65-6D-2E-44-61-"
525                                 + "74-65-54-69-6D-65-4F-66-66-73-65-74-02-00-00-00-"
526                                 + "08-44-61-74-65-54-69-6D-65-0D-4F-66-66-73-65-74-"
527                                 + "4D-69-6E-75-74-65-73-00-00-0D-07-00-39-75-F8-80-"
528                                 + "FC-C8-08-00-00-0B"),
529 #endif
530                         new TestRow (new DateTimeOffset (new DateTime (2007, 01, 02, 12, 30, 50), new TimeSpan (0, 0, 0)),
531                                 "00-01-00-00-00-FF-FF-FF-FF-01-00-00-00-00-00-00-"
532                                 + "00-04-01-00-00-00-15-53-79-73-74-65-6D-2E-44-61-"
533                                 + "74-65-54-69-6D-65-4F-66-66-73-65-74-02-00-00-00-"
534                                 + "08-44-61-74-65-54-69-6D-65-0D-4F-66-66-73-65-74-"
535                                 + "4D-69-6E-75-74-65-73-00-00-0D-07-00-39-75-F8-80-"
536                                 + "FC-C8-08-00-00-0B"),
537                         new TestRow (new DateTimeOffset (new DateTime (2007, 01, 02, 12, 30, 50), new TimeSpan (1, 0, 0)),
538                                 "00-01-00-00-00-FF-FF-FF-FF-01-00-00-00-00-00-00-"
539                                 + "00-04-01-00-00-00-15-53-79-73-74-65-6D-2E-44-61-"
540                                 + "74-65-54-69-6D-65-4F-66-66-73-65-74-02-00-00-00-"
541                                 + "08-44-61-74-65-54-69-6D-65-0D-4F-66-66-73-65-74-"
542                                 + "4D-69-6E-75-74-65-73-00-00-0D-07-00-D1-B0-96-78-"
543                                 + "FC-C8-08-3C-00-0B"),
544                         new TestRow (new DateTimeOffset (new DateTime (2007, 01, 02, 12, 30, 50), new TimeSpan (0, 30, 0)),
545                                 "00-01-00-00-00-FF-FF-FF-FF-01-00-00-00-00-00-00-"
546                                 + "00-04-01-00-00-00-15-53-79-73-74-65-6D-2E-44-61-"
547                                 + "74-65-54-69-6D-65-4F-66-66-73-65-74-02-00-00-00-"
548                                 + "08-44-61-74-65-54-69-6D-65-0D-4F-66-66-73-65-74-"
549                                 + "4D-69-6E-75-74-65-73-00-00-0D-07-00-05-93-C7-7C-"
550                                 + "FC-C8-08-1E-00-0B"),
551                         new TestRow (new DateTimeOffset (new DateTime (2007, 01, 02, 12, 30, 50), new TimeSpan (-5, 0, 0)),
552                                 "00-01-00-00-00-FF-FF-FF-FF-01-00-00-00-00-00-00-"
553                                 + "00-04-01-00-00-00-15-53-79-73-74-65-6D-2E-44-61-"
554                                 + "74-65-54-69-6D-65-4F-66-66-73-65-74-02-00-00-00-"
555                                 + "08-44-61-74-65-54-69-6D-65-0D-4F-66-66-73-65-74-"
556                                 + "4D-69-6E-75-74-65-73-00-00-0D-07-00-41-4B-E1-AA-"
557                                 + "FC-C8-08-D4-FE-0B"),
558                         new TestRow (new DateTimeOffset (new DateTime (2007, 01, 02, 12, 30, 50), new TimeSpan (-10, 30, 0)),
559                                 "00-01-00-00-00-FF-FF-FF-FF-01-00-00-00-00-00-00-"
560                                 + "00-04-01-00-00-00-15-53-79-73-74-65-6D-2E-44-61-"
561                                 + "74-65-54-69-6D-65-4F-66-66-73-65-74-02-00-00-00-"
562                                 + "08-44-61-74-65-54-69-6D-65-0D-4F-66-66-73-65-74-"
563                                 + "4D-69-6E-75-74-65-73-00-00-0D-07-00-15-3F-99-D0-"
564                                 + "FC-C8-08-C6-FD-0B"),
565                         // invalid case: .ctor ArgEx "non whole minutes"
566                         //      new DateTimeOffset(new DateTime(2007, 01, 02, 12, 30, 50), new TimeSpan(1, 2, 3));
567                         //----
568                         new TestRow (new DateTimeOffset (new DateTime (2007, 01, 02, 12, 30, 50, DateTimeKind.Utc)),
569                                 "00-01-00-00-00-FF-FF-FF-FF-01-00-00-00-00-00-00-"
570                                 + "00-04-01-00-00-00-15-53-79-73-74-65-6D-2E-44-61-"
571                                 + "74-65-54-69-6D-65-4F-66-66-73-65-74-02-00-00-00-"
572                                 + "08-44-61-74-65-54-69-6D-65-0D-4F-66-66-73-65-74-"
573                                 + "4D-69-6E-75-74-65-73-00-00-0D-07-00-39-75-F8-80-"
574                                 + "FC-C8-08-00-00-0B"),
575                         //----
576 #if ___MACHINE_TIMEZONE_HAS_ZERO_OFFSET
577                         // Local needs offset to be the same as the machine timezone,
578                         // not easy to cope with the tests being run around the world!
579                         // This one works in UK, etc.
580                         new TestRow (new DateTimeOffset (new DateTime (2007, 01, 02, 12, 30, 50, DateTimeKind.Local), new TimeSpan (0,0,0)),
581                                 "00-01-00-00-00-FF-FF-FF-FF-01-00-00-00-00-00-00-"
582                                 + "00-04-01-00-00-00-15-53-79-73-74-65-6D-2E-44-61-"
583                                 + "74-65-54-69-6D-65-4F-66-66-73-65-74-02-00-00-00-"
584                                 + "08-44-61-74-65-54-69-6D-65-0D-4F-66-66-73-65-74-"
585                                 + "4D-69-6E-75-74-65-73-00-00-0D-07-00-39-75-F8-80-"
586                                 + "FC-C8-08-00-00-0B"),
587 #endif
588                 };
589
590                 static byte[] BitConverter_ByteArray_FromString(String hexString)
591                 {
592                         String[] numbers = hexString.Split('-');
593                         byte[] result = new byte[numbers.Length];
594                         for (int i = 0; i < numbers.Length; ++i) {
595                                 byte x = Byte.Parse (numbers[i], NumberStyles.HexNumber, global::System.Globalization.CultureInfo.InvariantCulture);
596                                 result[i] = x;
597                         }
598                         return result;
599                 }
600
601         }
602 }
603 #endif
604