Beispiel #1
0
                /// <summary>
                /// Creates a hash table node with all the information for this period.
                /// We start off by finding the interval for the start of the period, and
                /// then repeatedly check whether that interval ends after the end of the
                /// period - at which point we're done. If not, find the next interval, create
                /// a new node referring to that interval and the previous interval, and keep going.
                /// </summary>
                internal static HashCacheNode CreateNode(int period, IZoneIntervalMap map)
                {
                    var periodStart = new Instant((long)period << PeriodShift);
                    var periodEnd   = new Instant((long)(period + 1) << PeriodShift);

                    var interval = map.GetZoneInterval(periodStart);
                    var node     = new HashCacheNode(interval, period, null);

                    // Keep going while the current interval ends before the period.
                    while (interval.End < periodEnd)
                    {
                        interval = map.GetZoneInterval(interval.End);
                        node     = new HashCacheNode(interval, period, node);
                    }

                    return(node);
                }
            /// <summary>
            /// Gets the zone offset period for the given instant. Null is returned if no period is
            /// defined by the time zone for the given instant.
            /// </summary>
            /// <param name="instant">The Instant to test.</param>
            /// <returns>The defined ZoneOffsetPeriod or null.</returns>
            public ZoneInterval GetZoneInterval(Instant instant)
            {
                int period = instant.DaysSinceEpoch >> PeriodShift;
                int index  = period & CachePeriodMask;
                var node   = instantCache[index];

                if (node == null || node.Period != period)
                {
                    node = HashCacheNode.CreateNode(period, map);
                    instantCache[index] = node;
                }

                // Note: moving this code into an instance method in HashCacheNode makes a surprisingly
                // large performance difference.
                while (node.Previous != null && node.Interval.RawStart > instant)
                {
                    node = node.Previous;
                }
                return(node.Interval);
            }
                /// <summary>
                /// Creates a hash table node with all the information for this period.
                /// We start off by finding the interval for the start of the period, and
                /// then repeatedly check whether that interval ends after the end of the
                /// period - at which point we're done. If not, find the next interval, create
                /// a new node referring to that interval and the previous interval, and keep going.
                /// </summary>
                internal static HashCacheNode CreateNode(int period, IZoneIntervalMap map)
                {
                    var days                = period << PeriodShift;
                    var periodStart         = new Instant(new Duration(Math.Max(days, Instant.MinDays), 0L));
                    var nextPeriodStartDays = days + (1 << PeriodShift);

                    var interval = map.GetZoneInterval(periodStart);
                    var node     = new HashCacheNode(interval, period, null);

                    // Keep going while the current interval ends before the period.
                    // (We only need to check the days, as every period lands on a
                    // day boundary.)
                    // If the raw end is the end of time, the condition will definitely
                    // evaluate to false.
                    while (interval.RawEnd.DaysSinceEpoch < nextPeriodStartDays)
                    {
                        interval = map.GetZoneInterval(interval.End);
                        node     = new HashCacheNode(interval, period, node);
                    }

                    return(node);
                }
 /// <summary>
 /// Initializes a new instance of the <see cref="HashCacheNode"/> class.
 /// </summary>
 /// <param name="interval">The zone interval.</param>
 /// <param name="period"></param>
 /// <param name="previous">The previous <see cref="HashCacheNode"/> node.</param>
 private HashCacheNode(ZoneInterval interval, int period, HashCacheNode previous)
 {
     this.Period   = period;
     this.Interval = interval;
     this.Previous = previous;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="HashCacheNode"/> class.
 /// </summary>
 /// <param name="interval">The zone interval.</param>
 /// <param name="period"></param>
 /// <param name="previous">The previous <see cref="HashCacheNode"/> node.</param>
 private HashCacheNode(ZoneInterval interval, int period, HashCacheNode previous)
 {
     this.Period = period;
     this.Interval = interval;
     this.Previous = previous;
 }
                /// <summary>
                /// Creates a hash table node with all the information for this period.
                /// We start off by finding the interval for the start of the period, and
                /// then repeatedly check whether that interval ends after the end of the
                /// period - at which point we're done. If not, find the next interval, create
                /// a new node referring to that interval and the previous interval, and keep going.
                /// </summary>
                internal static HashCacheNode CreateNode(int period, IZoneIntervalMap map)
                {
                    var days = period << PeriodShift;
                    var periodStart = new Instant(new Duration(Math.Max(days, Instant.MinDays), 0L));
                    var nextPeriodStartDays = days + (1 << PeriodShift);

                    var interval = map.GetZoneInterval(periodStart);
                    var node = new HashCacheNode(interval, period, null);

                    // Keep going while the current interval ends before the period.
                    // (We only need to check the days, as every period lands on a
                    // day boundary.)
                    // If the raw end is the end of time, the condition will definitely
                    // evaluate to false.
                    while (interval.RawEnd.DaysSinceEpoch < nextPeriodStartDays)
                    {
                        interval = map.GetZoneInterval(interval.End);
                        node = new HashCacheNode(interval, period, node);
                    }

                    return node;
                }
                /// <summary>
                /// Creates a hash table node with all the information for this period.
                /// We start off by finding the interval for the start of the period, and
                /// then repeatedly check whether that interval ends after the end of the
                /// period - at which point we're done. If not, find the next interval, create
                /// a new node referring to that interval and the previous interval, and keep going.
                /// </summary>
                internal static HashCacheNode CreateNode(int period, DateTimeZone zone)
                {
                    var periodStart = new Instant((long)period << PeriodShift);
                    var periodEnd = new Instant((long)(period + 1) << PeriodShift);

                    var interval = zone.GetZoneInterval(periodStart);
                    var node = new HashCacheNode(interval, period, null);

                    // Keep going while the current interval ends before the period.
                    while (interval.End < periodEnd)
                    {
                        interval = zone.GetZoneInterval(interval.End);
                        node = new HashCacheNode(interval, period, node);
                    }

                    return node;
                }