public void MinMaxOffsetsWithOtherTailZone() { var tailZone = new FixedDateTimeZone("TestFixed", Offset.FromHours(8)); var testZone = new PrecalculatedDateTimeZone("Test", new[] { FirstInterval, SecondInterval, ThirdInterval }, tailZone); Assert.AreEqual(Offset.FromHours(-5), testZone.MinOffset); Assert.AreEqual(Offset.FromHours(8), testZone.MaxOffset); }
public void MinMaxOffsetsWithNullTailZone() { var testZone = new PrecalculatedDateTimeZone("Test", new[] { FirstInterval, SecondInterval, ThirdInterval, new ZoneInterval("Last", ThirdInterval.End, Instant.AfterMaxValue, Offset.Zero, Offset.Zero) }, null); Assert.AreEqual(Offset.FromHours(-5), testZone.MinOffset); Assert.AreEqual(Offset.FromHours(4), testZone.MaxOffset); }
public void MapLocal_GapAroundAndInTailZoneTransition() { // Tail zone is -10 / +5, with the transition occurring just after // the transition *to* the tail zone from the precalculated zone. // A local time of one hour after the transition from the precalculated zone (which is -5) // will therefore be in the gap. var tailZone = new SingleTransitionDateTimeZone(ThirdInterval.End + Duration.FromHours(1), -10, +5); var gapZone = new PrecalculatedDateTimeZone("Test", new[] { FirstInterval, SecondInterval, ThirdInterval }, tailZone); var mapping = gapZone.MapLocal(ThirdInterval.IsoLocalEnd.PlusHours(1)); Assert.AreEqual(ThirdInterval, mapping.EarlyInterval); Assert.AreEqual(new ZoneInterval("Single-Early", ThirdInterval.End, tailZone.Transition, Offset.FromHours(-10), Offset.Zero), mapping.LateInterval); Assert.AreEqual(0, mapping.Count); }
public void GetZoneIntervals_NullTailZone_Eot() { ZoneInterval[] intervals = { new ZoneInterval("foo", Instant.BeforeMinValue, Instant.FromUnixTimeTicks(20), Offset.Zero, Offset.Zero), new ZoneInterval("foo", Instant.FromUnixTimeTicks(20), Instant.AfterMaxValue, Offset.Zero, Offset.Zero) }; var zone = new PrecalculatedDateTimeZone("Test", intervals, null); Assert.AreEqual(intervals[1], zone.GetZoneInterval(Instant.MaxValue)); }
public void MapLocal_SingleIntervalAroundTailZoneTransition() { // Tail zone is fixed at +5. A local instant of one hour before the transition // from the precalculated zone (which is -5) will therefore give an instant from // the tail zone which occurs before the precalculated-to-tail transition, // and can therefore be ignored, resulting in an overall unambiguous time. var tailZone = new FixedDateTimeZone(Offset.FromHours(5)); var gapZone = new PrecalculatedDateTimeZone("Test", new[] { FirstInterval, SecondInterval, ThirdInterval }, tailZone); var mapping = gapZone.MapLocal(ThirdInterval.IsoLocalEnd.PlusHours(-1)); Assert.AreEqual(ThirdInterval, mapping.EarlyInterval); Assert.AreEqual(ThirdInterval, mapping.LateInterval); Assert.AreEqual(1, mapping.Count); }
public void MapLocal_GapAroundTailZoneTransition() { // Tail zone is fixed at +5. A local time at the transition // from the precalculated zone (which is -5) will therefore give an instant from // the tail zone which occurs before the precalculated-to-tail transition, // and can therefore be ignored, resulting in an overall gap. var tailZone = new FixedDateTimeZone(Offset.FromHours(5)); var gapZone = new PrecalculatedDateTimeZone("Test", new[] { FirstInterval, SecondInterval, ThirdInterval }, tailZone); var mapping = gapZone.MapLocal(ThirdInterval.IsoLocalEnd); Assert.AreEqual(ThirdInterval, mapping.EarlyInterval); Assert.AreEqual(new ZoneInterval("UTC+05", ThirdInterval.End, Instant.AfterMaxValue, Offset.FromHours(5), Offset.Zero), mapping.LateInterval); Assert.AreEqual(0, mapping.Count); }
public void MapLocal_AmbiguousButTooEarlyInTailZoneTransition() { // Tail zone is +10 / +8, with the transition occurring just after // the transition *to* the tail zone from the precalculated zone. // A local instant of one hour before after the transition from the precalculated zone (which is -5) // will therefore be ambiguous, but the resulting instants from the ambiguity occur // before our transition into the tail zone, so are ignored. var tailZone = new SingleTransitionDateTimeZone(ThirdInterval.End + Duration.FromHours(1), 10, 8); var gapZone = new PrecalculatedDateTimeZone("Test", new[] { FirstInterval, SecondInterval, ThirdInterval }, tailZone); var mapping = gapZone.MapLocal(ThirdInterval.IsoLocalEnd.PlusHours(-1)); Assert.AreEqual(ThirdInterval, mapping.EarlyInterval); Assert.AreEqual(ThirdInterval, mapping.LateInterval); Assert.AreEqual(1, mapping.Count); }
/// <summary> /// Processes all the rules and builds a DateTimeZone. /// </summary> /// <param name="zoneId">Time zone ID to assign</param> public DateTimeZone ToDateTimeZone(String zoneId) { if (zoneId == null) { throw new ArgumentNullException("zoneId"); } var transitions = new List<ZoneTransition>(); DateTimeZone tailZone = null; Instant instant = Instant.MinValue; ZoneTransition nextTransition = null; int ruleSetCount = ruleSets.Count; for (int i = 0; i < ruleSetCount; i++) { var ruleSet = ruleSets[i]; var transitionIterator = ruleSet.Iterator(instant); nextTransition = transitionIterator.First(); if (nextTransition == null) { continue; } AddTransition(transitions, nextTransition); while ((nextTransition = transitionIterator.Next()) != null) { if (AddTransition(transitions, nextTransition)) { if (tailZone != null) { // Got the extra transition before DaylightSavingsTimeZone. nextTransition = transitionIterator.Next(); break; } } if (tailZone == null && i == ruleSetCount - 1) { tailZone = transitionIterator.BuildTailZone(zoneId); // If tailZone is not null, don't break out of main loop until at least one // more transition is calculated. This ensures a correct 'seam' to the // DaylightSavingsTimeZone. } } instant = ruleSet.GetUpperLimit(transitionIterator.Savings); } // Check if a simpler zone implementation can be returned. if (transitions.Count == 0) { return tailZone ?? new FixedDateTimeZone(zoneId, Offset.Zero); } if (transitions.Count == 1 && tailZone == null) { var transition = transitions[0]; return new FixedDateTimeZone(zoneId, transition.WallOffset); } var precalcedEnd = nextTransition != null ? nextTransition.Instant : Instant.MaxValue; var zone = new PrecalculatedDateTimeZone(zoneId, transitions, precalcedEnd, tailZone); return zone.IsCachable() ? CachedDateTimeZone.ForZone(zone) : zone; }
public void GetZoneIntervals_GapAroundAndInTailZoneTransition() { // Tail zone is -10 / +5, with the transition occurring just after // the transition *to* the tail zone from the precalculated zone. // A local instant of one hour after the transition from the precalculated zone (which is -5) // will therefore be in the gap. No zone interval matches, so the result is // an empty pair. var tailZone = new SingleTransitionZone(ThirdInterval.End + Duration.FromHours(1), -10, +5); var gapZone = new PrecalculatedDateTimeZone("Test", new[] { FirstInterval, SecondInterval, ThirdInterval }, tailZone); var pair = gapZone.GetZoneIntervals(ThirdInterval.LocalEnd + Duration.FromHours(1)); Assert.IsNull(pair.EarlyInterval); Assert.IsNull(pair.LateInterval); }
public void GetZoneIntervals_GapAroundTailZoneTransition() { // Tail zone is fixed at +5. A local instant of one hour after the transition // from the precalculated zone (which is -5) will therefore give an instant from // the tail zone which occurs before the precalculated-to-tail transition, // and can therefore be ignored, resulting in an overall gap. var tailZone = new FixedDateTimeZone(Offset.FromHours(5)); var gapZone = new PrecalculatedDateTimeZone("Test", new[] { FirstInterval, SecondInterval, ThirdInterval }, tailZone); var actual = gapZone.GetZoneIntervals(ThirdInterval.LocalEnd); var expected = ZoneIntervalPair.NoMatch; Assert.AreEqual(expected, actual); }
public void GetZoneIntervals_SingleIntervalAroundTailZoneTransition() { // Tail zone is fixed at +5. A local instant of one hour before the transition // from the precalculated zone (which is -5) will therefore give an instant from // the tail zone which occurs before the precalculated-to-tail transition, // and can therefore be ignored, resulting in an overall unambiguous time. var tailZone = new FixedDateTimeZone(Offset.FromHours(5)); var gapZone = new PrecalculatedDateTimeZone("Test", new[] { FirstInterval, SecondInterval, ThirdInterval }, tailZone); var pair = gapZone.GetZoneIntervals(ThirdInterval.LocalEnd - Duration.FromHours(1)); Assert.AreEqual(ThirdInterval, pair.EarlyInterval); Assert.IsNull(pair.LateInterval); }