2008-01-22 Stephane Delcroix <sdelcroix@novell.com>
[mono.git] / mcs / class / System.Core / Test / System / TimeZoneInfoTest.cs
1 /*
2  * TimeZoneInfo.Tests
3  *
4  * Author(s)
5  *      Stephane Delcroix <stephane@delcroix.org>
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining
8  * a copy of this software and associated documentation files (the
9  * "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  * 
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the Software.
17  * 
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  */
26
27 using System;
28 using System.Collections;
29
30 using NUnit.Framework;
31 #if NET_2_0
32 namespace MonoTests.System
33 {
34         public class TimeZoneInfoTest
35         {
36                 [TestFixture]
37                 public class PropertiesTests
38                 {
39                         [Test]
40                         public void GetLocal ()
41                         {
42                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
43                                         return;
44                                 TimeZoneInfo local = TimeZoneInfo.Local;
45                                 Assert.IsTrue (true);
46                         }
47                 }
48
49                 [TestFixture]
50                 public class CreateCustomTimezoneTests
51                 {
52                         [Test]
53                         [ExpectedException (typeof (ArgumentNullException))]
54                         public void IdIsNullException ()
55                         {
56                                 TimeZoneInfo.CreateCustomTimeZone (null, new TimeSpan (0), null, null); 
57                         }
58                 
59                         [Test]
60                         [ExpectedException (typeof (ArgumentException))]
61                         public void IdIsEmptyString ()
62                         {
63                                 TimeZoneInfo.CreateCustomTimeZone ("", new TimeSpan (0), null, null);   
64                         }
65                 
66                         [Test]
67                         [ExpectedException (typeof (ArgumentException))]
68                         public void OffsetIsNotMinutes ()
69                         {
70                                 TimeZoneInfo.CreateCustomTimeZone ("mytimezone", new TimeSpan (0, 0, 55), null, null);  
71                         }
72                 
73                         [Test]
74                         [ExpectedException (typeof (ArgumentOutOfRangeException))]
75                         public void OffsetTooBig ()
76                         {
77                                 TimeZoneInfo.CreateCustomTimeZone ("mytimezone", new TimeSpan (14, 1, 0), null, null);
78                         }
79                 
80                         [Test]
81                         [ExpectedException (typeof (ArgumentOutOfRangeException))]
82                         public void OffsetTooSmall ()
83                         {
84                                 TimeZoneInfo.CreateCustomTimeZone ("mytimezone", - new TimeSpan (14, 1, 0), null, null);
85                         }
86                 
87                 #if STRICT
88                         [Test]
89                         [ExpectedException (typeof (ArgumentException))]
90                         public void IdLongerThan32 ()
91                         {
92                                 TimeZoneInfo.CreateCustomTimeZone ("12345678901234567890123456789012345", new TimeSpan (0), null, null);        
93                         }       
94                 #endif
95                 
96                         [Test]
97                         [ExpectedException (typeof (InvalidTimeZoneException))]
98                         public void AdjustmentRulesOverlap ()
99                         {
100                                 TimeZoneInfo.TransitionTime s1 = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,4,0,0), 3, 2, DayOfWeek.Sunday);
101                                 TimeZoneInfo.TransitionTime e1 = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,4,0,0), 10, 2, DayOfWeek.Sunday);
102                                 TimeZoneInfo.AdjustmentRule r1 = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule (new DateTime (2000,1,1), new DateTime (2005,1,1), new TimeSpan (1,0,0), s1, e1);
103                                 TimeZoneInfo.TransitionTime s2 = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,4,0,0), 2, 2, DayOfWeek.Sunday);
104                                 TimeZoneInfo.TransitionTime e2 = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,4,0,0), 11, 2, DayOfWeek.Sunday);
105                                 TimeZoneInfo.AdjustmentRule r2 = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule (new DateTime (2004,1,1), new DateTime (2007,1,1), new TimeSpan (1,0,0), s2, e2);
106                                 TimeZoneInfo.CreateCustomTimeZone ("mytimezone", new TimeSpan (6,0,0),null,null,null,new TimeZoneInfo.AdjustmentRule[] {r1, r2});
107                         }
108                 
109                         [Test]
110                         [ExpectedException (typeof (InvalidTimeZoneException))]
111                         public void RulesNotOrdered ()
112                         {
113                                 TimeZoneInfo.TransitionTime s1 = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,4,0,0), 3, 2, DayOfWeek.Sunday);
114                                 TimeZoneInfo.TransitionTime e1 = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,4,0,0), 10, 2, DayOfWeek.Sunday);
115                                 TimeZoneInfo.AdjustmentRule r1 = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule (new DateTime (2000,1,1), new DateTime (2005,1,1), new TimeSpan (1,0,0), s1, e1);
116                                 TimeZoneInfo.TransitionTime s2 = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,4,0,0), 2, 2, DayOfWeek.Sunday);
117                                 TimeZoneInfo.TransitionTime e2 = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,4,0,0), 11, 2, DayOfWeek.Sunday);
118                                 TimeZoneInfo.AdjustmentRule r2 = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule (new DateTime (2006,1,1), new DateTime (2007,1,1), new TimeSpan (1,0,0), s2, e2);
119                                 TimeZoneInfo.CreateCustomTimeZone ("mytimezone", new TimeSpan (6,0,0),null,null,null,new TimeZoneInfo.AdjustmentRule[] {r2, r1});
120                         }
121                 
122                         [Test]
123                         [ExpectedException (typeof (InvalidTimeZoneException))]
124                         public void OffsetOutOfRange ()
125                         {
126                                 TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,4,0,0), 3, 2, DayOfWeek.Sunday);
127                                 TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,4,0,0), 10, 2, DayOfWeek.Sunday);
128                                 TimeZoneInfo.AdjustmentRule rule = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule (new DateTime (2000,1,1), new DateTime (2005,1,1), new TimeSpan (3,0,0), startTransition, endTransition);
129                                 TimeZoneInfo.CreateCustomTimeZone ("mytimezone", new TimeSpan (12,0,0),null,null,null,new TimeZoneInfo.AdjustmentRule[] {rule});
130                         }
131                 
132                         [Test]
133                         [ExpectedException (typeof (InvalidTimeZoneException))]
134                         public void NullRule ()
135                         {
136                                 TimeZoneInfo.CreateCustomTimeZone ("mytimezone", new TimeSpan (12,0,0),null,null,null,new TimeZoneInfo.AdjustmentRule[] {null});
137                         }
138                 
139                         [Test]
140                         [ExpectedException (typeof (InvalidTimeZoneException))]
141                         public void MultiplesRulesForDate ()
142                         {
143                                 TimeZoneInfo.TransitionTime s1 = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,4,0,0), 3, 2, DayOfWeek.Sunday);
144                                 TimeZoneInfo.TransitionTime e1 = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,4,0,0), 10, 2, DayOfWeek.Sunday);
145                                 TimeZoneInfo.AdjustmentRule r1 = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule (new DateTime (2000,1,1), new DateTime (2005,1,1), new TimeSpan (1,0,0), s1, e1);
146                                 TimeZoneInfo.TransitionTime s2 = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,4,0,0), 2, 2, DayOfWeek.Sunday);
147                                 TimeZoneInfo.TransitionTime e2 = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,4,0,0), 11, 2, DayOfWeek.Sunday);
148                                 TimeZoneInfo.AdjustmentRule r2 = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule (new DateTime (2005,1,1), new DateTime (2007,1,1), new TimeSpan (1,0,0), s2, e2);
149                                 TimeZoneInfo.CreateCustomTimeZone ("mytimezone", new TimeSpan (6,0,0),null,null,null,new TimeZoneInfo.AdjustmentRule[] {r1, r2});
150                         }
151                 }
152                 
153                 [TestFixture]
154                 public class IsDaylightSavingTimeTests
155                 {
156                         TimeZoneInfo london;
157                 
158                         [SetUp]
159                         public void CreateTimeZones ()
160                         {
161                                 TimeZoneInfo.TransitionTime start = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,1,0,0), 3, 5, DayOfWeek.Sunday);
162                                 TimeZoneInfo.TransitionTime end = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,2,0,0), 10, 5, DayOfWeek.Sunday);
163                                 TimeZoneInfo.AdjustmentRule rule = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule (DateTime.MinValue.Date, DateTime.MaxValue.Date, new TimeSpan (1,0,0), start, end);
164                                 london = TimeZoneInfo.CreateCustomTimeZone ("Europe/London", new TimeSpan (0), "Europe/London", "British Standard Time", "British Summer Time", new TimeZoneInfo.AdjustmentRule [] {rule});
165                         }
166                 
167                         [Test]
168                         public void NoDSTInUTC ()
169                         {
170                                 DateTime june01 = new DateTime (2007, 06, 01);
171                                 Assert.IsFalse (TimeZoneInfo.Utc.IsDaylightSavingTime (june01));
172                         }
173                 
174                         [Test]
175                         public void DSTInLondon ()
176                         {
177                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
178                                         return;
179                                 DateTime june01 = new DateTime (2007, 06, 01);
180                                 DateTime xmas = new DateTime (2007, 12, 25);
181                                 Assert.IsTrue (london.IsDaylightSavingTime (june01), "June 01 is DST in London");
182                                 Assert.IsFalse (london.IsDaylightSavingTime (xmas), "Xmas is not DST in London");
183                         }
184                 
185                         [Test]
186                         public void DSTTransisions ()
187                         {
188                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
189                                         return;
190                                 DateTime beforeDST = new DateTime (2007, 03, 25, 0, 59, 59, DateTimeKind.Unspecified);
191                                 DateTime startDST = new DateTime (2007, 03, 25, 2, 0, 0, DateTimeKind.Unspecified);
192                                 DateTime endDST = new DateTime (2007, 10, 28, 1, 59, 59, DateTimeKind.Unspecified);
193                                 DateTime afterDST = new DateTime (2007, 10, 28, 2, 0, 0, DateTimeKind.Unspecified);
194                                 Assert.IsFalse (london.IsDaylightSavingTime (beforeDST), "Just before DST");
195                                 Assert.IsTrue (london.IsDaylightSavingTime (startDST), "the first seconds of DST");
196                                 Assert.IsTrue (london.IsDaylightSavingTime (endDST), "The last seconds of DST");
197                                 Assert.IsFalse (london.IsDaylightSavingTime (afterDST), "Just after DST");
198                         }
199                 
200                         [Test]
201                         public void DSTTransisionsUTC ()
202                         {
203                                 DateTime beforeDST = new DateTime (2007, 03, 25, 0, 59, 59, DateTimeKind.Utc);
204                                 DateTime startDST = new DateTime (2007, 03, 25, 1, 0, 0, DateTimeKind.Utc);
205                                 DateTime endDST = new DateTime (2007, 10, 28, 0, 59, 59, DateTimeKind.Utc);
206                                 DateTime afterDST = new DateTime (2007, 10, 28, 1, 0, 0, DateTimeKind.Utc);
207                                 Assert.IsFalse (london.IsDaylightSavingTime (beforeDST), "Just before DST");
208                                 Assert.IsTrue (london.IsDaylightSavingTime (startDST), "the first seconds of DST");
209                                 Assert.IsTrue (london.IsDaylightSavingTime (endDST), "The last seconds of DST");
210                                 Assert.IsFalse (london.IsDaylightSavingTime (afterDST), "Just after DST");
211                         }
212                 
213                 #if SLOW_TESTS
214                         [Test]
215                         public void MatchTimeZoneBehavior ()
216                         {
217                                 TimeZone tzone = TimeZone.CurrentTimeZone;
218                                 TimeZoneInfo local = TimeZoneInfo.Local;
219                                 for (DateTime date = new DateTime (2007, 01, 01, 0, 0, 0, DateTimeKind.Local); date < new DateTime (2007, 12, 31, 23, 59, 59); date += new TimeSpan (0,1,0)) {
220                                         date = DateTime.SpecifyKind (date, DateTimeKind.Local);
221                                         if (local.IsInvalidTime (date))
222                                                 continue;
223                                         Assert.IsTrue (tzone.IsDaylightSavingTime (date) == local.IsDaylightSavingTime (date));
224                                 }
225                         }
226                 #endif
227                 }
228                 
229                 [TestFixture]
230                 public class ConvertTimeTests
231                 {
232                         TimeZoneInfo london;
233                 
234                         [SetUp]
235                         public void CreateTimeZones ()
236                         {
237                                 TimeZoneInfo.TransitionTime start = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,1,0,0), 3, 5, DayOfWeek.Sunday);
238                                 TimeZoneInfo.TransitionTime end = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,2,0,0), 10, 5, DayOfWeek.Sunday);
239                                 TimeZoneInfo.AdjustmentRule rule = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule (DateTime.MinValue.Date, DateTime.MaxValue.Date, new TimeSpan (1,0,0), start, end);
240                                 london = TimeZoneInfo.CreateCustomTimeZone ("Europe/London", new TimeSpan (0), "Europe/London", "British Standard Time", "British Summer Time", new TimeZoneInfo.AdjustmentRule [] {rule});
241                         }
242                 
243                         [Test]
244                         [ExpectedException (typeof (ArgumentException))]
245                         public void ConvertFromUtc_KindIsLocalException ()
246                         {
247                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
248                                         throw new ArgumentException ();
249                                 TimeZoneInfo.ConvertTimeFromUtc (new DateTime (2007, 5, 3, 11, 8, 0, DateTimeKind.Local), TimeZoneInfo.Local);  
250                         }
251                 
252                         [Test]
253                         [ExpectedException (typeof (ArgumentNullException))]
254                         public void ConvertFromUtc_DestinationTimeZoneIsNullException ()
255                         {
256                                 TimeZoneInfo.ConvertTimeFromUtc (new DateTime (2007, 5, 3, 11, 8, 0), null);            
257                         }
258                 
259                         [Test]
260                         public void ConvertFromUtc_DestinationIsUTC ()
261                         {
262                                 DateTime now = DateTime.UtcNow;
263                                 DateTime converted = TimeZoneInfo.ConvertTimeFromUtc (now, TimeZoneInfo.Utc);
264                                 Assert.AreEqual (now, converted);
265                         }
266                         
267                         [Test]
268                         public void ConvertFromUTC_ConvertInWinter ()
269                         {
270                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
271                                         return;
272                                 DateTime utc = new DateTime (2007, 12, 25, 12, 0, 0);
273                                 DateTime converted = TimeZoneInfo.ConvertTimeFromUtc (utc, london);
274                                 Assert.AreEqual (utc, converted);
275                         }
276                 
277                         [Test]
278                         public void ConvertFromUtc_ConvertInSummer ()
279                         {
280                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
281                                         return;
282                                 DateTime utc = new DateTime (2007, 06, 01, 12, 0, 0);
283                                 DateTime converted = TimeZoneInfo.ConvertTimeFromUtc (utc, london);
284                                 Assert.AreEqual (utc + new TimeSpan (1,0,0), converted);
285                         }
286                 
287                         [Test]
288                         public void ConvertToUTC_KindIsUtc ()
289                         {
290                                 DateTime now = DateTime.UtcNow;
291                                 Assert.AreEqual (now.Kind, DateTimeKind.Utc);
292                                 DateTime converted = TimeZoneInfo.ConvertTimeToUtc (now);
293                                 Assert.AreEqual (now, converted);
294                         }
295                 
296                         [Test]
297                         [ExpectedException (typeof (ArgumentException))]
298                         public void ConvertToUTC_KindIsUTCButSourceIsNot ()
299                         {
300                                 TimeZoneInfo.ConvertTimeToUtc (new DateTime (2007, 5, 3, 12, 8, 0, DateTimeKind.Utc), london);
301                         }
302                 
303                         [Test]
304                         [ExpectedException (typeof (ArgumentException))]
305                         public void ConvertToUTC_KindIsLocalButSourceIsNot ()
306                         {
307                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
308                                         throw new ArgumentException ();
309                                 TimeZoneInfo.ConvertTimeToUtc (new DateTime (2007, 5, 3, 12, 8, 0, DateTimeKind.Local), london);        
310                         }
311                 
312                         [Test]
313                         [ExpectedException (typeof (ArgumentException))]
314                         public void ConvertToUTC_InvalidDate ()
315                         {
316                                 TimeZoneInfo.ConvertTimeToUtc (new DateTime (2007, 3, 25, 1, 30, 0), london);
317                         }
318                 
319                         [Test]
320                         [ExpectedException (typeof (ArgumentNullException))]
321                         public void ConvertToUTC_SourceIsNull ()
322                         {
323                                 TimeZoneInfo.ConvertTimeToUtc (new DateTime (2007, 5, 3, 12, 16, 0), null);
324                         }
325                 
326                 #if SLOW_TESTS
327                         [Test]
328                         public void ConvertToUtc_MatchDateTimeBehavior ()
329                         {
330                                 for (DateTime date = new DateTime (2007, 01, 01, 0, 0, 0); date < new DateTime (2007, 12, 31, 23, 59, 59); date += new TimeSpan (0,1,0)) {
331                                         Assert.AreEqual (TimeZoneInfo.ConvertTimeToUtc (date), date.ToUniversalTime ());
332                                 }
333                         }
334                 #endif
335                 
336                         [Test]
337                         public void ConvertFromToUtc ()
338                         {
339                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
340                                         return;
341                                 DateTime utc = DateTime.UtcNow;
342                                 Assert.AreEqual (utc.Kind, DateTimeKind.Utc);
343                                 DateTime converted = TimeZoneInfo.ConvertTimeFromUtc (utc, london);
344                                 Assert.AreEqual (converted.Kind, DateTimeKind.Unspecified);
345                                 DateTime back = TimeZoneInfo.ConvertTimeToUtc (converted, london);
346                                 Assert.AreEqual (back.Kind, DateTimeKind.Utc);
347                                 Assert.AreEqual (utc, back);
348                 
349                         }
350                 }
351                 
352                 [TestFixture]
353                 public class IsInvalidTimeTests
354                 {
355                         TimeZoneInfo london;
356                 
357                         [SetUp]
358                         public void CreateTimeZones ()
359                         {
360                                 TimeZoneInfo.TransitionTime start = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,1,0,0), 3, 5, DayOfWeek.Sunday);
361                                 TimeZoneInfo.TransitionTime end = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,2,0,0), 10, 5, DayOfWeek.Sunday);
362                                 TimeZoneInfo.AdjustmentRule rule = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule (DateTime.MinValue.Date, DateTime.MaxValue.Date, new TimeSpan (1,0,0), start, end);
363                                 london = TimeZoneInfo.CreateCustomTimeZone ("Europe/London", new TimeSpan (0), "Europe/London", "British Standard Time", "British Summer Time", new TimeZoneInfo.AdjustmentRule [] {rule});
364                         }
365                 
366                 #if SLOW_TESTS
367                         [Test]
368                         public void UTCDate ()
369                         {
370                                 for (DateTime date = new DateTime (2007, 01, 01, 0, 0, 0); date < new DateTime (2007, 12, 31, 23, 59, 59); date += new TimeSpan (0,1,0)) {
371                                         date = DateTime.SpecifyKind (date, DateTimeKind.Utc);
372                                         Assert.IsFalse (london.IsInvalidTime (date));
373                                 }
374                         }
375                 #endif
376                         [Test]
377                         public void InvalidDates ()
378                         {
379                                 Assert.IsFalse (london.IsInvalidTime (new DateTime (2007, 03, 25, 0, 59, 59)));
380                                 Assert.IsTrue (london.IsInvalidTime (new DateTime (2007, 03, 25, 1, 0, 0)));
381                                 Assert.IsTrue (london.IsInvalidTime (new DateTime (2007, 03, 25, 1, 59, 59)));
382                                 Assert.IsFalse (london.IsInvalidTime (new DateTime (2007, 03, 25, 2, 0, 0)));
383                         }
384                 }
385                 
386                 [TestFixture]
387                 public class IsAmbiguousTimeTests
388                 {
389                         TimeZoneInfo london;
390                 
391                         [SetUp]
392                         public void CreateTimeZones ()
393                         {
394                                 TimeZoneInfo.TransitionTime start = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,1,0,0), 3, 5, DayOfWeek.Sunday);
395                                 TimeZoneInfo.TransitionTime end = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,2,0,0), 10, 5, DayOfWeek.Sunday);
396                                 TimeZoneInfo.AdjustmentRule rule = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule (DateTime.MinValue.Date, DateTime.MaxValue.Date, new TimeSpan (1,0,0), start, end);
397                                 london = TimeZoneInfo.CreateCustomTimeZone ("Europe/London", new TimeSpan (0), "Europe/London", "British Standard Time", "British Summer Time", new TimeZoneInfo.AdjustmentRule [] {rule});
398                         }
399                 
400                         [Test]
401                         public void AmbiguousDates ()
402                         {
403                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
404                                         return;
405                                 Assert.IsFalse (london.IsAmbiguousTime (new DateTime (2007, 10, 28, 1, 0, 0)));
406                                 Assert.IsTrue (london.IsAmbiguousTime (new DateTime (2007, 10, 28, 1, 0, 1)));
407                                 Assert.IsTrue (london.IsAmbiguousTime (new DateTime (2007, 10, 28, 2, 0, 0)));
408                                 Assert.IsFalse (london.IsAmbiguousTime (new DateTime (2007, 10, 28, 2, 0, 1)));
409                         }
410                 
411                         [Test]
412                         public void AmbiguousUTCDates ()
413                         {
414                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
415                                         return;
416                                 Assert.IsFalse (london.IsAmbiguousTime (new DateTime (2007, 10, 28, 0, 0, 0, DateTimeKind.Utc)));
417                                 Assert.IsTrue (london.IsAmbiguousTime (new DateTime (2007, 10, 28, 0, 0, 1, DateTimeKind.Utc)));
418                                 Assert.IsTrue (london.IsAmbiguousTime (new DateTime (2007, 10, 28, 0, 59, 59, DateTimeKind.Utc)));
419                                 Assert.IsFalse (london.IsAmbiguousTime (new DateTime (2007, 10, 28, 1, 0, 0, DateTimeKind.Utc)));
420                         }
421                 
422                 #if SLOW_TESTS
423                         [Test]
424                         public void AmbiguousInUTC ()
425                         {
426                                 for (DateTime date = new DateTime (2007, 01, 01, 0, 0, 0); date < new DateTime (2007, 12, 31, 23, 59, 59); date += new TimeSpan (0,1,0)) {
427                                         Assert.IsFalse (TimeZoneInfo.Utc.IsAmbiguousTime (date));
428                                 }
429                         }
430                 #endif
431                 }
432                 
433                 [TestFixture]
434                 public class GetSystemTimeZonesTests
435                 {
436                         [Test]
437                         public void NotEmpty ()
438                         {
439                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
440                                         return;
441                                 global::System.Collections.ObjectModel.ReadOnlyCollection<TimeZoneInfo> systemTZ = TimeZoneInfo.GetSystemTimeZones ();
442                                 Assert.IsNotNull(systemTZ, "SystemTZ is null");
443                                 Assert.IsFalse (systemTZ.Count == 0, "SystemTZ is empty");
444                         }
445                 
446                         [Test]
447                         public void ContainsBrussels ()
448                         {
449                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
450                                         return;
451                                 global::System.Collections.ObjectModel.ReadOnlyCollection<TimeZoneInfo> systemTZ = TimeZoneInfo.GetSystemTimeZones ();
452                                 foreach (TimeZoneInfo tz in systemTZ) {
453                                         if (tz.Id == "Europe/Brussels")
454                                                 return;
455                                 }
456                                 Assert.Fail ("Europe/Brussels not found in SystemTZ");
457                         }
458                 }
459                 
460                 [TestFixture]
461                 public class FindSystemTimeZoneByIdTests
462                 {
463                         [Test]
464                         [ExpectedException (typeof (ArgumentNullException))]
465                         public void NullId ()
466                         {
467                                 TimeZoneInfo.FindSystemTimeZoneById (null);
468                         }
469                 
470                         [Test]
471                         [ExpectedException (typeof (TimeZoneNotFoundException))]
472                         public void NonSystemTimezone ()
473                         {
474                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
475                                         throw new TimeZoneNotFoundException ();
476                                 TimeZoneInfo.FindSystemTimeZoneById ("Neverland/The_Lagoon");
477                         }
478                 
479                         [Test]
480                         public void FindBrusselsTZ ()
481                         {
482                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
483                                         return;
484                                 TimeZoneInfo brussels = TimeZoneInfo.FindSystemTimeZoneById ("Europe/Brussels");
485                                 Assert.IsNotNull (brussels);
486                         }
487                 
488                         [Test]
489                         public void OffsetIsCorrectInKinshasa ()
490                         {
491                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
492                                         return;
493                                 TimeZoneInfo kin = TimeZoneInfo.FindSystemTimeZoneById ("Africa/Kinshasa");
494                                 Assert.AreEqual (new TimeSpan (1,0,0), kin.BaseUtcOffset, "BaseUtcOffset in Kinshasa is not +1h");
495                         }
496                 
497                         [Test]
498                         public void OffsetIsCorrectInBrussels ()
499                         {
500                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
501                                         return;
502                                 TimeZoneInfo brussels = TimeZoneInfo.FindSystemTimeZoneById ("Europe/Brussels");
503                                 Assert.AreEqual (new TimeSpan (1,0,0), brussels.BaseUtcOffset, "BaseUtcOffset for Brussels is not +1h");
504                         }
505                 
506                         [Test]
507                         public void NoDSTInKinshasa ()
508                         {
509                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
510                                         return;
511                                 TimeZoneInfo kin = TimeZoneInfo.FindSystemTimeZoneById ("Africa/Kinshasa");
512                                 Assert.IsFalse (kin.SupportsDaylightSavingTime);
513                         }
514                 
515                         [Test]
516                         public void BrusselsSupportsDST ()
517                         {
518                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
519                                         return;
520                                 TimeZoneInfo brussels = TimeZoneInfo.FindSystemTimeZoneById ("Europe/Brussels");
521                                 Assert.IsTrue (brussels.SupportsDaylightSavingTime);
522                         }
523                 
524                         [Test]
525                         public void MelbourneSupportsDST ()
526                         {
527                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
528                                         return;
529                                 TimeZoneInfo melbourne = TimeZoneInfo.FindSystemTimeZoneById ("Australia/Melbourne");
530                                 Assert.IsTrue (melbourne.SupportsDaylightSavingTime);
531                         }
532                 
533                         [Test]
534                         public void RomeAndVaticanSharesTime ()
535                         {
536                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
537                                         return;
538                                 TimeZoneInfo rome = TimeZoneInfo.FindSystemTimeZoneById ("Europe/Rome");
539                                 TimeZoneInfo vatican = TimeZoneInfo.FindSystemTimeZoneById ("Europe/Vatican");
540                                 Assert.IsTrue (rome.HasSameRules (vatican));
541                         }
542                 
543                 #if SLOW_TESTS
544                         [Test]
545                         public void BrusselsAdjustments ()
546                         {
547                                 TimeZoneInfo.TransitionTime start = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,2,0,0), 3, 5, DayOfWeek.Sunday);
548                                 TimeZoneInfo.TransitionTime end = TimeZoneInfo.TransitionTime.CreateFloatingDateRule (new DateTime (1,1,1,3,0,0), 10, 5, DayOfWeek.Sunday);
549                                 TimeZoneInfo.AdjustmentRule rule = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule (DateTime.MinValue.Date, DateTime.MaxValue.Date, new TimeSpan (1,0,0), start, end);
550                                 TimeZoneInfo brussels = TimeZoneInfo.CreateCustomTimeZone ("Europe/Brussels", new TimeSpan (1, 0, 0), "Europe/Brussels", "", "", new TimeZoneInfo.AdjustmentRule [] {rule});
551                 
552                                 TimeZoneInfo brussels_sys = TimeZoneInfo.FindSystemTimeZoneById ("Europe/Brussels");
553                 
554                                 for (DateTime date = new DateTime (2006, 01, 01, 0, 0, 0, DateTimeKind.Local); date < new DateTime (2007, 12, 31, 23, 59, 59); date += new TimeSpan (0,30,0)) {
555                                         Assert.AreEqual (brussels.GetUtcOffset (date), brussels_sys.GetUtcOffset (date));
556                                         Assert.AreEqual (brussels.IsDaylightSavingTime (date), brussels_sys.IsDaylightSavingTime (date));
557                                 }               
558                         }
559                 #endif
560                 }
561                 
562                 [TestFixture]
563                 public class GetAmbiguousTimeOffsetsTests
564                 {
565                         [Test]
566                         [ExpectedException (typeof(ArgumentException))]
567                         public void DateIsNotAmbiguous ()
568                         {
569                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
570                                         throw new ArgumentException ();
571                                 TimeZoneInfo brussels = TimeZoneInfo.FindSystemTimeZoneById ("Europe/Brussels");
572                                 DateTime date = new DateTime (2007, 05, 11, 11, 40, 00);
573                                 brussels.GetAmbiguousTimeOffsets (date);
574                         }
575                 
576                         [Test]
577                         public void AmbiguousOffsets ()
578                         {
579                                 if (Environment.OSVersion.Platform != PlatformID.Unix)
580                                         return;
581                                 TimeZoneInfo brussels = TimeZoneInfo.FindSystemTimeZoneById ("Europe/Brussels");
582                                 DateTime date = new DateTime (2007, 10, 28, 2, 30, 00);
583                                 Assert.IsTrue (brussels.IsAmbiguousTime (date));
584                                 Assert.AreEqual (2, brussels.GetAmbiguousTimeOffsets (date).Length);
585                                 Assert.AreEqual (new TimeSpan[] {new TimeSpan (1, 0, 0), new TimeSpan (2, 0, 0)}, brussels.GetAmbiguousTimeOffsets (date));
586                         }
587                 }
588         }
589 }
590 #endif