Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit d2f3a64

Browse files
committed
Merge pull request #2641 from eerhardt/master
Fix all TimeZoneInfo tests on Linux.
2 parents 39fb86f + 6ed2164 commit d2f3a64

File tree

1 file changed

+144
-23
lines changed

1 file changed

+144
-23
lines changed

src/System.Runtime/tests/System/TimeZoneInfo.cs

Lines changed: 144 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

44
using System;
5+
using System.Globalization;
56
using System.Runtime.InteropServices;
67
using Xunit;
78

@@ -19,18 +20,27 @@ public static class TimeZoneInfoTests
1920
private static String s_strAmsterdam = s_isWindows ? "W. Europe Standard Time" : "Europe/Berlin";
2021
private static String s_strRussian = s_isWindows ? "Russian Standard Time" : "Europe/Moscow";
2122
private static String s_strLibya = s_isWindows ? "Libya Standard Time" : "Africa/Tripoli";
23+
private static String s_strCatamarca = s_isWindows ? "Argentina Standard Time" : "America/Catamarca";
24+
private static String s_strLisbon = s_isWindows ? "GMT Standard Time" : "Europe/Lisbon";
25+
private static String s_strNewfoundland = s_isWindows ? "Newfoundland Standard Time" : "America/St_Johns";
2226

2327
private static TimeZoneInfo s_myUtc = TimeZoneInfo.Utc;
2428
private static TimeZoneInfo s_myLocal = TimeZoneInfo.Local;
2529
private static TimeZoneInfo s_regLocal = TimeZoneInfo.FindSystemTimeZoneById(TimeZoneInfo.Local.Id); // in case DST is disabled on Local
2630
private static TimeZoneInfo s_GMTLondon = TimeZoneInfo.FindSystemTimeZoneById(s_strGMT);
2731
private static TimeZoneInfo s_nairobiTz = TimeZoneInfo.FindSystemTimeZoneById(s_strNairobi);
2832
private static TimeZoneInfo s_amsterdamTz = TimeZoneInfo.FindSystemTimeZoneById(s_strAmsterdam);
33+
private static TimeZoneInfo s_catamarcaTz = TimeZoneInfo.FindSystemTimeZoneById(s_strCatamarca);
34+
private static TimeZoneInfo s_LisbonTz = TimeZoneInfo.FindSystemTimeZoneById(s_strLisbon);
35+
private static TimeZoneInfo s_NewfoundlandTz = TimeZoneInfo.FindSystemTimeZoneById(s_strNewfoundland);
2936

3037
private static bool s_localIsPST = TimeZoneInfo.Local.Id == s_strPacific;
3138
private static bool s_regLocalSupportsDST = s_regLocal.SupportsDaylightSavingTime;
3239
private static bool s_localSupportsDST = TimeZoneInfo.Local.SupportsDaylightSavingTime;
3340

41+
// In 2006, Australia delayed ending DST by a week. However, Windows says it still ended the last week of March.
42+
private static readonly int s_sydneyOffsetLastWeekOfMarch2006 = s_isWindows ? 10 : 11;
43+
3444
[Fact]
3545
public static void TestKind()
3646
{
@@ -94,7 +104,6 @@ public static void ValidateLibyaTimeZoneTest()
94104
}
95105

96106
[Fact]
97-
[ActiveIssue(2465, PlatformID.AnyUnix)]
98107
public static void ValidateRussiaTimeZoneTest()
99108
{
100109
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById(s_strRussian);
@@ -158,17 +167,22 @@ public static void NearMinMaxDateTimeOffsetConvertTest()
158167
VerifyConvert(new DateTimeOffset(DateTime.MinValue.AddHours(5), new TimeSpan(-3, 0, 0)), s_strPacific, new DateTimeOffset(DateTime.MinValue, new TimeSpan(-8, 0, 0)));
159168

160169
VerifyConvert(DateTime.MaxValue, s_strPacific, s_strSydney, DateTime.MaxValue);
161-
if (s_isWindows) // [ActiveIssue(2465, PlatformID.AnyUnix)]
162-
{
163-
VerifyConvert(DateTime.MaxValue.AddHours(-19), s_strPacific, s_strSydney, DateTime.MaxValue);
164-
}
170+
VerifyConvert(DateTime.MaxValue.AddHours(-19), s_strPacific, s_strSydney, DateTime.MaxValue);
165171
VerifyConvert(DateTime.MaxValue.AddHours(-19.5), s_strPacific, s_strSydney, DateTime.MaxValue.AddHours(-0.5));
172+
166173
VerifyConvert(DateTime.MinValue, s_strSydney, s_strPacific, DateTime.MinValue);
167-
if (s_isWindows) // [ActiveIssue(2465, PlatformID.AnyUnix)]
174+
if (s_isWindows)
168175
{
169176
VerifyConvert(DateTime.MinValue.AddHours(19), s_strSydney, s_strPacific, DateTime.MinValue);
170177
VerifyConvert(DateTime.MinValue.AddHours(19.5), s_strSydney, s_strPacific, DateTime.MinValue.AddHours(0.5));
171178
}
179+
else
180+
{
181+
// for early times, IANA uses local mean time (LMT), which is based on the solar time.
182+
// The Pacific Standard Time LMT is UTC-07:53. For Sydney, LMT is UTC+10:04.
183+
VerifyConvert(DateTime.MinValue.AddHours(17).AddMinutes(57), s_strSydney, s_strPacific, DateTime.MinValue);
184+
VerifyConvert(DateTime.MinValue.AddHours(17.5).AddMinutes(57), s_strSydney, s_strPacific, DateTime.MinValue.AddHours(0.5));
185+
}
172186
}
173187

174188
[Fact]
@@ -315,7 +329,6 @@ public static void SameTimeZonesTest()
315329
}
316330

317331
[Fact]
318-
[ActiveIssue(846, PlatformID.AnyUnix)]
319332
public static void NearMinMaxDateTimeConvertTest()
320333
{
321334
DateTime time1 = new DateTime(2006, 5, 12);
@@ -327,13 +340,25 @@ public static void NearMinMaxDateTimeConvertTest()
327340
VerifyConvert(utcMaxValue, s_strPacific, DateTime.MaxValue.AddHours(-8));
328341
DateTime utcMinValue = DateTime.SpecifyKind(DateTime.MinValue, DateTimeKind.Utc);
329342
VerifyConvert(utcMinValue, s_strPacific, DateTime.MinValue);
330-
VerifyConvert(utcMinValue.AddHours(8), s_strPacific, DateTime.MinValue);
331-
VerifyConvert(utcMinValue.AddHours(8.5), s_strPacific, DateTime.MinValue.AddHours(0.5));
332-
VerifyConvert(utcMinValue, s_strSydney, DateTime.MinValue.AddHours(11));
343+
344+
if (s_isWindows)
345+
{
346+
VerifyConvert(utcMinValue.AddHours(8), s_strPacific, DateTime.MinValue);
347+
VerifyConvert(utcMinValue.AddHours(8.5), s_strPacific, DateTime.MinValue.AddHours(0.5));
348+
VerifyConvert(utcMinValue, s_strSydney, DateTime.MinValue.AddHours(11));
349+
}
350+
else
351+
{
352+
// for early times, IANA uses local mean time (LMT), which is based on the solar time.
353+
// The Pacific Standard Time LMT is UTC-07:53.
354+
VerifyConvert(utcMinValue.AddHours(8).AddMinutes(-7), s_strPacific, DateTime.MinValue);
355+
VerifyConvert(utcMinValue.AddHours(8.5).AddMinutes(-7), s_strPacific, DateTime.MinValue.AddHours(0.5));
356+
// For Sydney, LMT is UTC+10:04.
357+
VerifyConvert(utcMinValue, s_strSydney, DateTime.MinValue.AddHours(10).AddMinutes(4));
358+
}
333359
}
334360

335361
[Fact]
336-
[ActiveIssue(846, PlatformID.AnyUnix)]
337362
public static void DateTimeVariousSystemTimeZonesTest()
338363
{
339364
var time1utc = new DateTime(2006, 5, 12, 5, 17, 42, DateTimeKind.Utc);
@@ -345,7 +370,7 @@ public static void DateTimeVariousSystemTimeZonesTest()
345370
time1utc = new DateTime(2006, 3, 28, 9, 47, 12, DateTimeKind.Utc);
346371
time1 = new DateTime(2006, 3, 28, 9, 47, 12);
347372
VerifyConvert(time1utc, s_strPacific, time1.AddHours(-8));
348-
VerifyConvert(time1utc, s_strSydney, time1.AddHours(10));
373+
VerifyConvert(time1utc, s_strSydney, time1.AddHours(s_sydneyOffsetLastWeekOfMarch2006));
349374
time1utc = new DateTime(2006, 11, 5, 1, 3, 0, DateTimeKind.Utc);
350375
time1 = new DateTime(2006, 11, 5, 1, 3, 0);
351376
VerifyConvert(time1utc, s_strPacific, time1.AddHours(-8));
@@ -382,8 +407,8 @@ public static void DateTimeVariousSystemTimeZonesTest()
382407
VerifyConvert(time1, s_strPacific, s_strSydney, time1.AddHours(17));
383408
VerifyConvert(time1, s_strSydney, s_strPacific, time1.AddHours(-17));
384409
time1 = new DateTime(2006, 3, 28, 9, 47, 12);
385-
VerifyConvert(time1, s_strPacific, s_strSydney, time1.AddHours(18));
386-
VerifyConvert(time1, s_strSydney, s_strPacific, time1.AddHours(-18));
410+
VerifyConvert(time1, s_strPacific, s_strSydney, time1.AddHours(s_sydneyOffsetLastWeekOfMarch2006 + 8));
411+
VerifyConvert(time1, s_strSydney, s_strPacific, time1.AddHours(-(s_sydneyOffsetLastWeekOfMarch2006 + 8)));
387412
time1 = new DateTime(2006, 11, 5, 1, 3, 0);
388413
VerifyConvert(time1, s_strPacific, s_strSydney, time1.AddHours(19));
389414
VerifyConvert(time1, s_strSydney, s_strPacific, time1.AddHours(-19));
@@ -393,7 +418,6 @@ public static void DateTimeVariousSystemTimeZonesTest()
393418
}
394419

395420
[Fact]
396-
[ActiveIssue(846, PlatformID.AnyUnix)]
397421
public static void PerthRulesTest()
398422
{
399423
var time1utc = new DateTime(2005, 12, 31, 15, 59, 59, DateTimeKind.Utc);
@@ -424,11 +448,20 @@ public static void PerthRulesTest()
424448
time1utc = new DateTime(2006, 11, 30, 18, 0, 0, DateTimeKind.Utc);
425449
time1 = new DateTime(2006, 12, 1, 2, 0, 0);
426450
VerifyConvert(time1utc, s_strPerth, time1);
427-
// ambiguous time between rules
428-
// this is not ideal, but the way it works
451+
429452
time1utc = new DateTime(2006, 12, 31, 15, 59, 59, DateTimeKind.Utc);
430453
time1 = new DateTime(2006, 12, 31, 15, 59, 59);
431-
VerifyConvert(time1utc, s_strPerth, time1.AddHours(8));
454+
if (s_isWindows)
455+
{
456+
// ambiguous time between rules
457+
// this is not ideal, but the way it works
458+
VerifyConvert(time1utc, s_strPerth, time1.AddHours(8));
459+
}
460+
else
461+
{
462+
// Linux has the correct rules for Perth for days from December 3, 2006 to the end of the year
463+
VerifyConvert(time1utc, s_strPerth, time1.AddHours(9));
464+
}
432465

433466
// 2007 rule
434467
time1utc = new DateTime(2006, 12, 31, 20, 1, 2, DateTimeKind.Utc);
@@ -512,7 +545,6 @@ public static void UtcToLocalTest()
512545
}
513546

514547
[Fact]
515-
[ActiveIssue(846, PlatformID.AnyUnix)]
516548
public static void LocalToSystemTest()
517549
{
518550
var time1 = new DateTime(2006, 5, 12, 5, 17, 42);
@@ -522,13 +554,16 @@ public static void LocalToSystemTest()
522554
VerifyConvert(time1local, s_strSydney, time1.Subtract(localOffset).AddHours(10));
523555
VerifyConvert(time1, s_strPacific, time1.Subtract(localOffset).AddHours(-7));
524556
VerifyConvert(time1local, s_strPacific, time1.Subtract(localOffset).AddHours(-7));
557+
525558
time1 = new DateTime(2006, 3, 28, 9, 47, 12);
526559
time1local = new DateTime(2006, 3, 28, 9, 47, 12, DateTimeKind.Local);
527560
localOffset = TimeZoneInfo.Local.GetUtcOffset(time1);
528-
VerifyConvert(time1, s_strSydney, time1.Subtract(localOffset).AddHours(10));
529-
VerifyConvert(time1local, s_strSydney, time1.Subtract(localOffset).AddHours(10));
561+
VerifyConvert(time1, s_strSydney, time1.Subtract(localOffset).AddHours(s_sydneyOffsetLastWeekOfMarch2006));
562+
VerifyConvert(time1local, s_strSydney, time1.Subtract(localOffset).AddHours(s_sydneyOffsetLastWeekOfMarch2006));
563+
530564
VerifyConvert(time1, s_strPacific, time1.Subtract(localOffset).AddHours(-8));
531565
VerifyConvert(time1local, s_strPacific, time1.Subtract(localOffset).AddHours(-8));
566+
532567
time1 = new DateTime(2006, 11, 5, 1, 3, 0);
533568
time1local = new DateTime(2006, 11, 5, 1, 3, 0, DateTimeKind.Local);
534569
localOffset = TimeZoneInfo.Local.GetUtcOffset(time1);
@@ -603,7 +638,6 @@ public static void LocalToSystemTest()
603638
}
604639

605640
[Fact]
606-
[ActiveIssue(846, PlatformID.AnyUnix)]
607641
public static void LocalToLocalTest()
608642
{
609643
if (s_localIsPST)
@@ -662,7 +696,6 @@ public static void LocalToLocalTest()
662696
}
663697

664698
[Fact]
665-
[ActiveIssue(846, PlatformID.AnyUnix)]
666699
public static void LocalToUtcTest()
667700
{
668701
var time1 = new DateTime(1964, 6, 19, 12, 45, 10);
@@ -1630,6 +1663,88 @@ public static void InvalidTimeTests()
16301663
VerifyInv(s_amsterdamTz, new DateTime(2006, 12, 15, 12, 15, 44), false);
16311664
}
16321665

1666+
[Fact]
1667+
[PlatformSpecific(PlatformID.AnyUnix)]
1668+
public static void TestCatamarcaMultiYearDaylightSavings()
1669+
{
1670+
// America/Catamarca had DST from
1671+
// 1946-10-01T04:00:00.0000000Z {-03:00:00 DST=True}
1672+
// 1963-10-01T03:00:00.0000000Z {-04:00:00 DST=False}
1673+
1674+
VerifyDST(s_catamarcaTz, new DateTime(1946, 09, 30, 17, 00, 00, DateTimeKind.Utc), false);
1675+
VerifyDST(s_catamarcaTz, new DateTime(1946, 10, 01, 03, 00, 00, DateTimeKind.Utc), false);
1676+
VerifyDST(s_catamarcaTz, new DateTime(1946, 10, 01, 03, 59, 00, DateTimeKind.Utc), false);
1677+
VerifyDST(s_catamarcaTz, new DateTime(1946, 10, 01, 04, 00, 00, DateTimeKind.Utc), true);
1678+
VerifyDST(s_catamarcaTz, new DateTime(1950, 01, 01, 00, 00, 00, DateTimeKind.Utc), true);
1679+
VerifyDST(s_catamarcaTz, new DateTime(1953, 03, 01, 15, 00, 00, DateTimeKind.Utc), true);
1680+
VerifyDST(s_catamarcaTz, new DateTime(1955, 05, 01, 16, 00, 00, DateTimeKind.Utc), true);
1681+
VerifyDST(s_catamarcaTz, new DateTime(1957, 07, 01, 17, 00, 00, DateTimeKind.Utc), true);
1682+
VerifyDST(s_catamarcaTz, new DateTime(1959, 09, 01, 00, 00, 00, DateTimeKind.Utc), true);
1683+
VerifyDST(s_catamarcaTz, new DateTime(1961, 11, 01, 00, 00, 00, DateTimeKind.Utc), true);
1684+
VerifyDST(s_catamarcaTz, new DateTime(1963, 10, 01, 02, 00, 00, DateTimeKind.Utc), true);
1685+
VerifyDST(s_catamarcaTz, new DateTime(1963, 10, 01, 02, 59, 00, DateTimeKind.Utc), true);
1686+
VerifyDST(s_catamarcaTz, new DateTime(1963, 10, 01, 03, 00, 00, DateTimeKind.Utc), false);
1687+
}
1688+
1689+
[Theory]
1690+
[PlatformSpecific(PlatformID.AnyUnix)]
1691+
// in 1996 Europe/Lisbon changed from standard time to DST without changing the UTC offset
1692+
[InlineData("1995-09-30T17:00:00.0000000Z", false, "1:00:00")]
1693+
[InlineData("1996-03-31T00:59:59.0000000Z", false, "1:00:00")]
1694+
[InlineData("1996-03-31T01:00:00.0000000Z", true, "1:00:00")]
1695+
[InlineData("1996-03-31T01:00:01.0000000Z", true, "1:00:00")]
1696+
[InlineData("1996-03-31T11:00:01.0000000Z", true, "1:00:00")]
1697+
[InlineData("1996-08-31T11:00:00.0000000Z", true, "1:00:00")]
1698+
[InlineData("1996-10-27T00:00:00.0000000Z", true, "1:00:00")]
1699+
[InlineData("1996-10-27T00:59:59.0000000Z", true, "1:00:00")]
1700+
[InlineData("1996-10-27T01:00:00.0000000Z", false, "0:00:00")]
1701+
[InlineData("1996-10-28T01:00:00.0000000Z", false, "0:00:00")]
1702+
[InlineData("1997-03-30T00:59:59.0000000Z", false, "0:00:00")]
1703+
[InlineData("1997-03-30T01:00:00.0000000Z", true, "1:00:00")]
1704+
public static void TestLisbonDaylightSavingsWithNoOffsetChange(string dateTimeString, bool expectedDST, string expectedOffsetString)
1705+
{
1706+
DateTime dt = DateTime.ParseExact(dateTimeString, "o", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
1707+
VerifyDST(s_LisbonTz, dt, expectedDST);
1708+
1709+
TimeSpan offset = TimeSpan.Parse(expectedOffsetString, CultureInfo.InvariantCulture);
1710+
Assert.Equal(offset, s_LisbonTz.GetUtcOffset(dt));
1711+
}
1712+
1713+
[Theory]
1714+
// Newfoundland is UTC-3:30 standard and UTC-2:30 dst
1715+
// using non-UTC date times in this test to get some converage for non-UTC date times
1716+
[InlineData("2015-03-08T01:59:59", false, false, false, "-3:30:00", "-8:00:00")]
1717+
// since DST kicks in a 2AM, from 2AM - 3AM is Invalid
1718+
[InlineData("2015-03-08T02:00:00", false, true, false,"-3:30:00", "-8:00:00")]
1719+
[InlineData("2015-03-08T02:59:59", false, true, false,"-3:30:00", "-8:00:00")]
1720+
[InlineData("2015-03-08T03:00:00", true, false, false,"-2:30:00", "-8:00:00")]
1721+
[InlineData("2015-03-08T07:29:59", true, false, false,"-2:30:00", "-8:00:00")]
1722+
[InlineData("2015-03-08T07:30:00", true, false, false,"-2:30:00", "-7:00:00")]
1723+
[InlineData("2015-11-01T00:59:59", true, false, false, "-2:30:00", "-7:00:00")]
1724+
[InlineData("2015-11-01T01:00:00", false, false, true, "-3:30:00", "-7:00:00")]
1725+
[InlineData("2015-11-01T01:59:59", false, false, true, "-3:30:00", "-7:00:00")]
1726+
[InlineData("2015-11-01T02:00:00", false, false, false, "-3:30:00", "-7:00:00")]
1727+
[InlineData("2015-11-01T05:29:59", false, false, false, "-3:30:00", "-7:00:00")]
1728+
[InlineData("2015-11-01T05:30:00", false, false, false, "-3:30:00", "-8:00:00")]
1729+
public static void TestNewfoundlandTimeZone(string dateTimeString, bool expectedDST, bool isInvalidTime, bool isAmbiguousTime,
1730+
string expectedOffsetString, string pacificOffsetString)
1731+
{
1732+
DateTime dt = DateTime.ParseExact(dateTimeString, "s", CultureInfo.InvariantCulture);
1733+
VerifyInv(s_NewfoundlandTz, dt, isInvalidTime);
1734+
1735+
if (!isInvalidTime)
1736+
{
1737+
VerifyDST(s_NewfoundlandTz, dt, expectedDST);
1738+
VerifyAmbiguous(s_NewfoundlandTz, dt, isAmbiguousTime);
1739+
1740+
TimeSpan offset = TimeSpan.Parse(expectedOffsetString, CultureInfo.InvariantCulture);
1741+
Assert.Equal(offset, s_NewfoundlandTz.GetUtcOffset(dt));
1742+
1743+
TimeSpan pacificOffset = TimeSpan.Parse(pacificOffsetString, CultureInfo.InvariantCulture);
1744+
VerifyConvert(dt, s_strNewfoundland, s_strPacific, dt - (offset - pacificOffset));
1745+
}
1746+
}
1747+
16331748
//
16341749
// Helper Methods
16351750
//
@@ -1740,4 +1855,10 @@ private static void VerifyInv(TimeZoneInfo tz, DateTime dt, bool expectedInvalid
17401855
bool ret = tz.IsInvalidTime(dt);
17411856
Assert.True(expectedInvalid == ret, String.Format("Test with the zone {0} and date {1} failed", tz.Id, dt));
17421857
}
1858+
1859+
private static void VerifyAmbiguous(TimeZoneInfo tz, DateTime dt, bool expectedAmbiguous)
1860+
{
1861+
bool ret = tz.IsAmbiguousTime(dt);
1862+
Assert.True(expectedAmbiguous == ret, String.Format("Test with the zone {0} and date {1} failed", tz.Id, dt));
1863+
}
17431864
}

0 commit comments

Comments
 (0)