Ejemplo n.º 1
0
        /// <summary>
        /// Returns the given instant adjusted one year forward taking into account leap years and other
        /// adjustments like day of week.
        /// </summary>
        /// <remarks>
        /// If the given instant is before the starting year, the year of the given instant is
        /// adjusted to the beginning of the starting year. The first transition after the
        /// adjusted instant is determined. If the next adjustment is after the ending year, this
        /// method returns null; otherwise the next transition is returned.
        /// </remarks>
        /// <param name="instant">The <see cref="Instant"/> lower bound for the next transition.</param>
        /// <param name="standardOffset">The <see cref="Offset"/> standard offset.</param>
        /// <param name="previousSavings">The <see cref="Offset"/> savings adjustment at the given Instant.</param>
        /// <returns>The next transition, or null if there is no next transition.</returns>
        internal Transition?Next(Instant instant, Offset standardOffset, Offset previousSavings)
        {
            CalendarSystem calendar = CalendarSystem.Iso;

            Offset wallOffset = standardOffset + previousSavings;

            int year = instant == Instant.MinValue ? Int32.MinValue : calendar.GetYear(instant.Plus(wallOffset));

            if (year < fromYear)
            {
                // First advance instant to start of from year.
                instant = calendar.GetLocalInstant(fromYear, 1, 1, 0, 0).Minus(wallOffset);
                // Back off one tick to account for next recurrence being exactly at the beginning
                // of the year.
                instant = instant - Duration.Epsilon;
            }

            Instant next = yearOffset.Next(instant, standardOffset, previousSavings);

            if (next >= instant)
            {
                year = calendar.GetYear(next.Plus(wallOffset));
                if (year > toYear)
                {
                    return(null);
                }
            }

            return(new Transition(next, wallOffset, standardOffset + Savings));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Returns the given instant adjusted one year backward taking into account leap years and other
        /// adjustments like day of week.
        /// </summary>
        /// <param name="instant">The <see cref="Instant"/> lower bound for the next trasnition.</param>
        /// <param name="standardOffset">The <see cref="Offset"/> standard offset.</param>
        /// <param name="previousSavings">The <see cref="Offset"/> savings adjustment at the given Instant.</param>
        /// <returns>The previous transition, or null if there is no previous transition.</returns>
        internal Transition?Previous(Instant instant, Offset standardOffset, Offset previousSavings)
        {
            CalendarSystem calendar = CalendarSystem.Iso;

            Offset wallOffset = standardOffset + previousSavings;

            int year = instant == Instant.MaxValue ? Int32.MaxValue : calendar.GetYear(instant.Plus(wallOffset));

            if (year > toYear)
            {
                // First pull instant back to the start of the year after toYear
                instant = calendar.GetLocalInstant(toYear + 1, 1, 1, 0, 0).Minus(wallOffset);
            }

            Instant previous = yearOffset.Previous(instant, standardOffset, previousSavings);

            if (previous <= instant)
            {
                year = calendar.GetYear(previous.Plus(wallOffset));
                if (year < fromYear)
                {
                    return(null);
                }
            }

            return(new Transition(previous, wallOffset, standardOffset + Savings));
        }
Ejemplo n.º 3
0
            private ZoneTransition GetNext(Instant nextInstant)
            {
                // Find next matching rule.
                ZoneRecurrence nextRule  = null;
                Instant        nextTicks = Instant.MaxValue;

                for (int i = 0; i < rules.Count; i++)
                {
                    ZoneRecurrence rule           = rules[i];
                    Transition?    nextTransition = rule.Next(nextInstant, ruleSet.StandardOffset, savings);
                    Instant?       next           = nextTransition == null ? (Instant?)null : nextTransition.Value.Instant;
                    if (!next.HasValue || next.Value <= nextInstant)
                    {
                        rules.RemoveAt(i);
                        i--;
                        continue;
                    }
                    // Even if next is same as previous next, choose the rule in order for more
                    // recently added rules to override.
                    if (next.Value <= nextTicks)
                    {
                        // Found a better match.
                        nextRule  = rule;
                        nextTicks = next.Value;
                    }
                }

                if (nextRule == null)
                {
                    return(null);
                }

                // Stop precalculating if year reaches some arbitrary limit. We can cheat in the
                // conversion because it is an approximation anyway.
                if (calendar.GetYear(nextTicks.Plus(Offset.Zero)) >= YearLimit)
                {
                    return(null);
                }

                // Check if upper limit reached or passed.
                if (ruleSet.upperYear < Int32.MaxValue)
                {
                    Instant upperTicks = ruleSet.upperYearOffset.MakeInstant(ruleSet.upperYear, ruleSet.StandardOffset, savings);
                    if (nextTicks >= upperTicks)
                    {
                        // At or after upper limit.
                        return(null);
                    }
                }
                return(new ZoneTransition(nextTicks, nextRule.Name, ruleSet.StandardOffset, nextRule.Savings));
            }