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