public void ZoneWithAmbiguity_JustAfterTransition() { var actual = ZoneWithAmbiguity.GetZoneIntervalPair(TransitionPlus10 + Duration.Epsilon); var expected = ZoneIntervalPair.Unambiguous(IntervalAfterAmbiguity); Assert.AreEqual(expected, actual); }
public void ZoneWithAmbiguity_WellAfterTransition() { var actual = ZoneWithAmbiguity.GetZoneIntervalPair(YearAfterTransition); var expected = ZoneIntervalPair.Unambiguous(IntervalAfterAmbiguity); Assert.AreEqual(expected, actual); }
public void ZoneWithAmbiguity_JustBeforeAmbiguity() { var actual = ZoneWithAmbiguity.GetZoneIntervalPair(TransitionMinus5 - Duration.Epsilon); var expected = ZoneIntervalPair.Unambiguous(IntervalBeforeAmbiguity); Assert.AreEqual(expected, actual); }
public void ZoneWithAmbiguity_StartOfTime() { var actual = ZoneWithAmbiguity.GetZoneIntervalPair(LocalInstant.MinValue); var expected = ZoneIntervalPair.Unambiguous(IntervalBeforeAmbiguity); Assert.AreEqual(expected, actual); }
public void ZoneWithAmbiguity_EndOfTime() { var actual = ZoneWithAmbiguity.GetZoneIntervalPair(LocalInstant.MaxValue); var expected = ZoneIntervalPair.Unambiguous(IntervalAfterAmbiguity); Assert.AreEqual(expected, actual); }
public void ZoneWithGap_FirstTickAfterTransition() { var actual = ZoneWithGap.GetZoneIntervalPair(TransitionPlus10); var expected = ZoneIntervalPair.Unambiguous(IntervalAfterGap); Assert.AreEqual(expected, actual); }
public void ZoneWithGap_WellBeforeTransition() { var actual = ZoneWithGap.GetZoneIntervalPair(YearBeforeTransition); var expected = ZoneIntervalPair.Unambiguous(IntervalBeforeGap); Assert.AreEqual(expected, actual); }
public void ZoneWithAmbiguity_LastTickOfTransition() { var actual = ZoneWithAmbiguity.GetZoneIntervalPair(TransitionPlus10 - Duration.Epsilon); var expected = ZoneIntervalPair.Ambiguous(IntervalBeforeAmbiguity, IntervalAfterAmbiguity); Assert.AreEqual(expected, actual); }
public void ZoneWithAmbiguity_MidTransition() { var actual = ZoneWithAmbiguity.GetZoneIntervalPair(MidTransition); var expected = ZoneIntervalPair.Ambiguous(IntervalBeforeAmbiguity, IntervalAfterAmbiguity); Assert.AreEqual(expected, actual); }
/// <summary> /// Returns the earliest valid <see cref="ZonedDateTime"/> with the given local date. /// </summary> /// <remarks> /// If midnight exists unambiguously on the given date, it is returned. /// If the given date has an ambiguous start time (e.g. the clocks go back from 1am to midnight) /// then the earlier ZonedDateTime is returned. If the given date has no midnight (e.g. the clocks /// go forward from midnight to 1am) then the earliest valid value is returned; this will be the instant /// of the transition. /// </remarks> /// <param name="date">The local date to map in this time zone.</param> /// <exception cref="SkippedTimeException">The entire day was skipped due to a very large time zone transition. /// (This is extremely rare.)</exception> /// <returns>The <see cref="ZonedDateTime"/> representing the earliest time in the given date, in this time zone.</returns> public ZonedDateTime AtStartOfDay(LocalDate date) { LocalInstant localInstant = date.AtMidnight().LocalInstant; ZoneIntervalPair pair = GetZoneIntervalPair(localInstant); switch (pair.MatchingIntervals) { case 0: var interval = GetIntervalAfterGap(localInstant); var localDateTime = new LocalDateTime(interval.LocalStart, date.Calendar); // It's possible that the entire day is skipped. For example, Samoa skipped December 30th 2011. if (localDateTime.Date != date) { throw new SkippedTimeException(date + LocalTime.Midnight, this); } return(new ZonedDateTime(localDateTime, interval.WallOffset, this)); case 1: case 2: return(new ZonedDateTime(date.AtMidnight(), pair.EarlyInterval.WallOffset, this)); default: throw new InvalidOperationException("This won't happen."); } }
public void MatchingIntervals_TwoIntervals() { ZoneIntervalPair pair = ZoneIntervalPair.Ambiguous( new ZoneInterval("Foo", new Instant(0), new Instant(10), Offset.Zero, Offset.Zero), new ZoneInterval("Bar", new Instant(10), new Instant(20), Offset.Zero, Offset.Zero)); Assert.AreEqual(2, pair.MatchingIntervals); }
public void TrickyCase() { // 1am occurs unambiguously in the early zone. var zone = new SingleTransitionDateTimeZone(Transition, Offset.FromHours(3), Offset.FromHours(5)); var actual = zone.GetZoneIntervalPair(new LocalInstant(2000, 1, 1, 1, 0)); var expected = ZoneIntervalPair.Unambiguous(zone.EarlyInterval); Assert.AreEqual(expected, actual); }
/// <summary> /// Finds all zone intervals for the given local instant. Usually there's one (i.e. only a single /// instant is mapped to the given local instant within the time zone) but during DST transitions /// there can be either 0 (the given local instant doesn't exist, e.g. local time skipped from 1am to /// 2am, but you gave us 1.30am) or 2 (the given local instant is ambiguous, e.g. local time skipped /// from 2am to 1am, but you gave us 1.30am). /// </summary> /// <remarks> /// This method is implemented in terms of GetZoneInterval(Instant) within DateTimeZone, /// and should work for any zone. However, internal derived classes may override this method /// for optimization purposes, e.g. if the zone interval is always ambiguous with /// a fixed value. /// </remarks> /// <param name="localInstant">The local instant to find matching zone intervals for</param> /// <returns>The struct containing up to two ZoneInterval references.</returns> internal virtual ZoneIntervalPair GetZoneIntervalPair(LocalInstant localInstant) { Instant firstGuess = new Instant(localInstant.Ticks); ZoneInterval interval = GetZoneInterval(firstGuess); // Most of the time we'll go into here... the local instant and the instant // are close enough that we've found the right instant. if (interval.Contains(localInstant)) { ZoneInterval earlier = GetEarlierMatchingInterval(interval, localInstant); if (earlier != null) { return(ZoneIntervalPair.Ambiguous(earlier, interval)); } ZoneInterval later = GetLaterMatchingInterval(interval, localInstant); if (later != null) { return(ZoneIntervalPair.Ambiguous(interval, later)); } return(ZoneIntervalPair.Unambiguous(interval)); } else { // Our first guess was wrong. Either we need to change interval by one (either direction) // or we're in a gap. ZoneInterval earlier = GetEarlierMatchingInterval(interval, localInstant); if (earlier != null) { return(ZoneIntervalPair.Unambiguous(earlier)); } ZoneInterval later = GetLaterMatchingInterval(interval, localInstant); if (later != null) { return(ZoneIntervalPair.Unambiguous(later)); } return(ZoneIntervalPair.NoMatch); } }
public void MatchingIntervals_NoIntervals() { ZoneIntervalPair pair = ZoneIntervalPair.NoMatch; Assert.AreEqual(0, pair.MatchingIntervals); }
public void MatchingIntervals_SingleInterval() { ZoneIntervalPair pair = ZoneIntervalPair.Unambiguous(new ZoneInterval("Foo", new Instant(0), new Instant(10), Offset.Zero, Offset.Zero)); Assert.AreEqual(1, pair.MatchingIntervals); }