/// <summary> /// Finds the recurrence containing the given instant, if any. /// </summary> /// <returns>The recurrence containing the given instant, or null if /// the instant occurs before the start of the earlier recurrence.</returns> private ZoneRecurrence FindMatchingRecurrence(Instant instant) { // Find the transitions which start *after* the one we're currently in - then // pick the later of them, which will be the same "polarity" as the one we're currently // in. // Both transitions must be non-null, as our recurrences are infinite. Transition nextDstStart = dstRecurrence.NextOrFail(instant, standardOffset, standardRecurrence.Savings); Transition nextStandardStart = standardRecurrence.NextOrFail(instant, standardOffset, dstRecurrence.Savings); return(nextDstStart.Instant > nextStandardStart.Instant ? dstRecurrence : standardRecurrence); }
/// <summary> /// Returns the transition occurring strictly after the specified instant. The <paramref name="recurrence"/> /// parameter will be populated with the recurrence the transition goes *from*. /// </summary> /// <param name="instant">The instant after which to consider transitions.</param> /// <param name="recurrence">Receives the savings offset for the transition.</param> private Transition NextTransition(Instant instant, out ZoneRecurrence recurrence) { // Both recurrences are infinite, so they'll both have next transitions (possibly at infinity). Transition dstTransition = dstRecurrence.NextOrFail(instant, standardOffset, Offset.Zero); Transition standardTransition = standardRecurrence.NextOrFail(instant, standardOffset, dstRecurrence.Savings); var standardTransitionInstant = standardTransition.Instant; var dstTransitionInstant = dstTransition.Instant; if (standardTransitionInstant < dstTransitionInstant) { // Next transition is from DST to standard. recurrence = dstRecurrence; return(standardTransition); } else if (standardTransitionInstant > dstTransitionInstant) { // Next transition is from standard to DST. recurrence = standardRecurrence; return(dstTransition); } else { // Okay, the transitions happen at the same time. If they're not at infinity, we're stumped. if (standardTransitionInstant.IsValid) { throw new InvalidOperationException("Zone recurrence rules have identical transitions. This time zone is broken."); } // Okay, the two transitions must be to the end of time. Find which recurrence has the later *previous* transition... var previousDstTransition = dstRecurrence.PreviousOrSameOrFail(instant, standardOffset, Offset.Zero); var previousStandardTransition = standardRecurrence.PreviousOrSameOrFail(instant, standardOffset, dstRecurrence.Savings); // No point in checking for equality here... they can't go back from the end of time to the start... if (previousDstTransition.Instant > previousStandardTransition.Instant) { // The previous transition is from standard to DST. Therefore the next one is from DST to standard. recurrence = dstRecurrence; return(standardTransition); } else { // The previous transition is from DST to standard. Therefore the next one is from standard to DST. recurrence = standardRecurrence; return(dstTransition); } } }