diff options
author | Eric Erhardt <eric.erhardt@microsoft.com> | 2015-08-18 15:46:55 -0700 |
---|---|---|
committer | Eric Erhardt <eric.erhardt@microsoft.com> | 2015-08-18 15:46:55 -0700 |
commit | 50ef79d48df81635e58ca59386620f0151df6022 (patch) | |
tree | fca7dd51b759e7c224c1af844417309a11dff2cd | |
parent | 8c369709553fc621156e0279bf96b91b2081f442 (diff) | |
parent | dd57af2f2711a4acbdf11be2e29cfd5c2f077cc1 (diff) | |
download | coreclr-50ef79d48df81635e58ca59386620f0151df6022.tar.gz coreclr-50ef79d48df81635e58ca59386620f0151df6022.tar.bz2 coreclr-50ef79d48df81635e58ca59386620f0151df6022.zip |
Merge pull request #1397 from eerhardt/master
Handle newer tzfiles by allowing for the "big bang" transition.
-rw-r--r-- | src/mscorlib/src/System/DateTimeOffset.cs | 12 | ||||
-rw-r--r-- | src/mscorlib/src/System/TimeZoneInfo.cs | 33 |
2 files changed, 36 insertions, 9 deletions
diff --git a/src/mscorlib/src/System/DateTimeOffset.cs b/src/mscorlib/src/System/DateTimeOffset.cs index 7db5c4ca8e..7f0348a838 100644 --- a/src/mscorlib/src/System/DateTimeOffset.cs +++ b/src/mscorlib/src/System/DateTimeOffset.cs @@ -43,7 +43,10 @@ namespace System { private const long UnixEpochTicks = TimeSpan.TicksPerDay * DateTime.DaysTo1970; // 621,355,968,000,000,000 private const long UnixEpochSeconds = UnixEpochTicks / TimeSpan.TicksPerSecond; // 62,135,596,800 private const long UnixEpochMilliseconds = UnixEpochTicks / TimeSpan.TicksPerMillisecond; // 62,135,596,800,000 - + + internal const long UnixMinSeconds = DateTime.MinTicks / TimeSpan.TicksPerSecond - UnixEpochSeconds; + internal const long UnixMaxSeconds = DateTime.MaxTicks / TimeSpan.TicksPerSecond - UnixEpochSeconds; + // Static Fields public static readonly DateTimeOffset MinValue = new DateTimeOffset(DateTime.MinTicks, TimeSpan.Zero); public static readonly DateTimeOffset MaxValue = new DateTimeOffset(DateTime.MaxTicks, TimeSpan.Zero); @@ -474,12 +477,9 @@ namespace System { } public static DateTimeOffset FromUnixTimeSeconds(long seconds) { - const long MinSeconds = DateTime.MinTicks / TimeSpan.TicksPerSecond - UnixEpochSeconds; - const long MaxSeconds = DateTime.MaxTicks / TimeSpan.TicksPerSecond - UnixEpochSeconds; - - if (seconds < MinSeconds || seconds > MaxSeconds) { + if (seconds < UnixMinSeconds || seconds > UnixMaxSeconds) { throw new ArgumentOutOfRangeException("seconds", - string.Format(Environment.GetResourceString("ArgumentOutOfRange_Range"), MinSeconds, MaxSeconds)); + string.Format(Environment.GetResourceString("ArgumentOutOfRange_Range"), UnixMinSeconds, UnixMaxSeconds)); } long ticks = seconds * TimeSpan.TicksPerSecond + UnixEpochTicks; diff --git a/src/mscorlib/src/System/TimeZoneInfo.cs b/src/mscorlib/src/System/TimeZoneInfo.cs index 900b5d0af7..bc8d76ed82 100644 --- a/src/mscorlib/src/System/TimeZoneInfo.cs +++ b/src/mscorlib/src/System/TimeZoneInfo.cs @@ -3621,8 +3621,15 @@ namespace System { Byte[] typeOfLocalTime, TZifType[] transitionTypes, Boolean[] StandardTime, Boolean[] GmtTime, string futureTransitionsPosixFormat) { // To generate AdjustmentRules, use the following approach: - // 1. The first AdjustmentRule goes from DateTime.Min to the first transition and uses the first standard transitionType - // (or the first transitionType if none of them are standard) + // The first AdjustmentRule will go from DateTime.MinValue to the first transition time greater than DateTime.MinValue. + // Each middle AdjustmentRule wil go from dts[index-1] to dts[index]. + // The last AdjustmentRule will go from dts[dts.Length-1] to Datetime.MaxValue. + + // 0. Skip any DateTime.MinValue transition times. In newer versions of the tzfile, there + // is a "big bang" transition time, which is before the year 0001. Since any times before year 0001 + // cannot be represented by DateTime, there is no reason to make AdjustmentRules for these unrepresentable time periods. + // 1. If there are no DateTime.MinValue times, the first AdjustmentRule goes from DateTime.MinValue + // to the first transition and uses the first standard transitionType (or the first transitionType if none of them are standard) // 2. Create an AdjustmentRule for each transition, i.e. from dts[index - 1] to dts[index]. // This rule uses the transitionType[index - 1] and the whole AdjustmentRule only describes a single offset - either // all daylight savings, or all stanard time. @@ -3630,6 +3637,11 @@ namespace System { // a. a POSIX-style timezone description ("futureTransitionsPosixFormat"), if there is one or // b. continue the last transition offset until DateTime.Max + while (index < dts.Length && dts[index] == DateTime.MinValue) + { + index++; + } + if (index == 0) { TZifType transitionType = TZif_GetEarlyDateTransitionType(transitionTypes); @@ -4128,6 +4140,21 @@ namespace System { } } + private static DateTime TZif_UnixTimeToDateTime(long unixTime) + { + if (unixTime < DateTimeOffset.UnixMinSeconds) + { + return DateTime.MinValue; + } + + if (unixTime > DateTimeOffset.UnixMaxSeconds) + { + return DateTime.MaxValue; + } + + return DateTimeOffset.FromUnixTimeSeconds(unixTime).UtcDateTime; + } + static private void TZif_ParseRaw(Byte[] data, out TZifHead t, out DateTime[] dts, out Byte[] typeOfLocalTime, out TZifType[] transitionType, out String zoneAbbreviations, out Boolean[] StandardTime, out Boolean[] GmtTime, out string futureTransitionsPosixFormat) { @@ -4170,7 +4197,7 @@ namespace System { // for (int i = 0; i < t.TimeCount; i++) { long unixTime = TZif_ToUnixTime(data, index, t.Version); - dts[i] = DateTimeOffset.FromUnixTimeSeconds(unixTime).UtcDateTime; + dts[i] = TZif_UnixTimeToDateTime(unixTime); index += timeValuesLength; } |