/// <summary> /// Returns if this rule represents the same rule and offsets as another. /// When two <c>TimeZoneRule</c> objects differ only its names, this /// method returns true. /// </summary> /// /// <param name="other">The <c>TimeZoneRule</c> object to be compared with.</param> /// <returns>true if the other <c>TimeZoneRule</c> is the same as this /// one.</returns> /// @draft ICU 3.8 /// @provisional This API might change or be removed in a future release. public virtual bool IsEquivalentTo(TimeZoneRule other) { if (rawOffset == other.rawOffset && dstSavings == other.dstSavings) { return(true); } return(false); }
/// <summary> /// /// </summary> /// /// @draft ICU 3.8 /// @provisional This API might change or be removed in a future release. public override bool IsEquivalentTo(TimeZoneRule other) { if (other is InitialTimeZoneRule) { return(base.IsEquivalentTo(other)); } return(false); }
/// <summary> /// /// </summary> /// /// @draft ICU 3.8 /// @provisional This API might change or be removed in a future release. public override bool IsEquivalentTo(TimeZoneRule other) { if (!(other is TimeArrayTimeZoneRule)) { return(false); } if (timeType == ((TimeArrayTimeZoneRule)other).timeType && ILOG.J2CsMapping.Collections.Arrays.Equals(startTimes, ((TimeArrayTimeZoneRule)other).startTimes)) { return(base.IsEquivalentTo(other)); } return(false); }
/// <summary> /// /// </summary> /// /// @draft ICU 3.8 /// @provisional This API might change or be removed in a future release. public override bool IsEquivalentTo(TimeZoneRule other) { if (!(other is AnnualTimeZoneRule)) { return(false); } AnnualTimeZoneRule otherRule = (AnnualTimeZoneRule)other; if (startYear == otherRule.startYear && endYear == otherRule.endYear && dateTimeRule.Equals(otherRule.dateTimeRule)) { return(base.IsEquivalentTo(other)); } return(false); }
// BasicTimeZone methods /// <summary> /// /// </summary> /// /// @draft ICU 3.8 /// @provisional This API might change or be removed in a future release. public override TimeZoneRule[] GetTimeZoneRules() { int size = 1; if (historicRules != null) { size += historicRules.Count; } if (finalRules != null) { if (finalRules[1] != null) { size += 2; } else { size++; } } TimeZoneRule[] rules = new TimeZoneRule[size]; rules[0] = initialRule; int idx = 1; if (historicRules != null) { for (; idx < historicRules.Count + 1; idx++) { rules[idx] = (TimeZoneRule)historicRules[idx - 1]; } } if (finalRules != null) { rules[idx++] = finalRules[0]; if (finalRules[1] != null) { rules[idx] = finalRules[1]; } } return(rules); }
/// <summary> /// Adds the <c>TimeZoneRule</c> which represents time transitions. The /// <c>TimeZoneRule</c> must have start times, that is, the result of<see cref="M:IBM.ICU.Util.TimeZoneRule.IsTransitionRule"/> must be true. /// Otherwise, <c>IllegalArgumentException</c> is thrown. /// </summary> /// /// <param name="rule">The <c>TimeZoneRule</c>.</param> /// @draft ICU 3.8 /// @provisional This API might change or be removed in a future release. public void AddTransitionRule(TimeZoneRule rule) { if (!rule.IsTransitionRule()) { throw new ArgumentException("Rule must be a transition rule"); } if (rule is AnnualTimeZoneRule && ((AnnualTimeZoneRule)rule).GetEndYear() == IBM.ICU.Util.AnnualTimeZoneRule.MAX_YEAR) { // One of the final rules applicable in future forever if (finalRules == null) { finalRules = new AnnualTimeZoneRule[2]; finalRules[0] = (AnnualTimeZoneRule)rule; } else if (finalRules[1] == null) { finalRules[1] = (AnnualTimeZoneRule)rule; } else { // Only a pair of AnnualTimeZoneRule is allowed. throw new InvalidOperationException("Too many final rules"); } } else { // If this is not a final rule, add it to the historic rule list if (historicRules == null) { historicRules = new ArrayList(); } ILOG.J2CsMapping.Collections.Generics.Collections.Add(historicRules, rule); } // Mark dirty, so transitions are recalculated when offset information // is // accessed next time. upToDate = false; }
/// <summary> /// Constructs a <c>TimeZoneTransition</c> with the time and the rules /// before/after the transition. /// </summary> /// /// <param name="time_0">The time of transition in milliseconds since the base time.</param> /// <param name="from_1">The time zone rule used before the transition.</param> /// <param name="to_2">The time zone rule used after the transition.</param> /// @draft ICU 3.8 /// @provisional This API might change or be removed in a future release. public TimeZoneTransition(long time_0, TimeZoneRule from_1, TimeZoneRule to_2) { this.time = time_0; this.from = from_1; this.to = to_2; }
/// <summary> /// Gets the array of <c>TimeZoneRule</c> which represents the rule of /// this time zone object near the specified date. Some applications are not /// capable to handle historic time zone rule changes. Also some applications /// can only handle certain type of rule definitions. This method returns /// either a single <c>InitialTimeZoneRule</c> if this time zone does /// not have any daylight saving time within 1 year from the specified time, /// or a pair of <c>AnnualTimeZoneRule</c> whose rule type is /// <c>DateTimeRule.DOW</c> for date and /// <c>DateTimeRule.WALL_TIME</c> for time with a single /// <c>InitialTimeZoneRule</c> representing the initial time, when this /// time zone observes daylight saving time near the specified date. Thus, /// the result may be only valid for dates around the specified date. /// </summary> /// /// <param name="date">The date to be used for <c>TimeZoneRule</c> extraction.</param> /// <returns>The array of <c>TimeZoneRule</c>, either a single /// <c>InitialTimeZoneRule</c> object, or a pair of /// <c>AnnualTimeZoneRule</c> with a single /// <c>InitialTimeZoneRule</c>. The first element in the array /// is always a <c>InitialTimeZoneRule</c>.</returns> /// @draft ICU 3.8 /// @provisional This API might change or be removed in a future release. public TimeZoneRule[] GetSimpleTimeZoneRulesNear(long date) { AnnualTimeZoneRule[] annualRules = null; TimeZoneRule initialRule = null; // Get the next transition TimeZoneTransition tr = GetNextTransition(date, false); if (tr != null) { String initialName = tr.GetFrom().GetName(); int initialRaw = tr.GetFrom().GetRawOffset(); int initialDst = tr.GetFrom().GetDSTSavings(); // Check if the next transition is either DST->STD or STD->DST and // within roughly 1 year from the specified date long nextTransitionTime = tr.GetTime(); if (((tr.GetFrom().GetDSTSavings() == 0 && tr.GetTo() .GetDSTSavings() != 0) || (tr.GetFrom().GetDSTSavings() != 0 && tr .GetTo().GetDSTSavings() == 0)) && date + MILLIS_PER_YEAR > nextTransitionTime) { // Get the next next transition annualRules = new AnnualTimeZoneRule[2]; int[] dtfields = IBM.ICU.Impl.Grego.TimeToFields( nextTransitionTime + tr.GetFrom().GetRawOffset() + tr.GetFrom().GetDSTSavings(), null); int weekInMonth = IBM.ICU.Impl.Grego.GetDayOfWeekInMonth(dtfields[0], dtfields[1], dtfields[2]); // Create DOW rule DateTimeRule dtr = new DateTimeRule(dtfields[1], weekInMonth, dtfields[3], dtfields[5], IBM.ICU.Util.DateTimeRule.WALL_TIME); annualRules[0] = new AnnualTimeZoneRule(tr.GetTo().GetName(), tr.GetTo().GetRawOffset(), tr.GetTo().GetDSTSavings(), dtr, dtfields[0], IBM.ICU.Util.AnnualTimeZoneRule.MAX_YEAR); tr = GetNextTransition(nextTransitionTime, false); AnnualTimeZoneRule secondRule = null; if (tr != null) { // Check if the next next transition is either DST->STD or // STD->DST // and within roughly 1 year from the next transition if (((tr.GetFrom().GetDSTSavings() == 0 && tr.GetTo() .GetDSTSavings() != 0) || (tr.GetFrom() .GetDSTSavings() != 0 && tr.GetTo().GetDSTSavings() == 0)) && nextTransitionTime + MILLIS_PER_YEAR > tr .GetTime()) { // Generate another DOW rule dtfields = IBM.ICU.Impl.Grego.TimeToFields(tr.GetTime() + tr.GetFrom().GetRawOffset() + tr.GetFrom().GetDSTSavings(), dtfields); weekInMonth = IBM.ICU.Impl.Grego.GetDayOfWeekInMonth(dtfields[0], dtfields[1], dtfields[2]); dtr = new DateTimeRule(dtfields[1], weekInMonth, dtfields[3], dtfields[5], IBM.ICU.Util.DateTimeRule.WALL_TIME); secondRule = new AnnualTimeZoneRule(tr.GetTo() .GetName(), tr.GetTo().GetRawOffset(), tr .GetTo().GetDSTSavings(), dtr, dtfields[0] - 1, IBM.ICU.Util.AnnualTimeZoneRule.MAX_YEAR); // Make sure this rule can be applied to the specified // date DateTime d = secondRule.GetPreviousStart(date, tr.GetFrom() .GetRawOffset(), tr.GetFrom().GetDSTSavings(), true); if (d != null && (d.Ticks / 10000) <= date && initialRaw == tr.GetTo().GetRawOffset() && initialDst == tr.GetTo().GetDSTSavings()) { // We can use this rule as the second transition // rule annualRules[1] = secondRule; } } } if (annualRules[1] == null) { // Try previous transition tr = GetPreviousTransition(date, true); if (tr != null) { // Check if the previous transition is either DST->STD // or STD->DST. // The actual transition time does not matter here. if ((tr.GetFrom().GetDSTSavings() == 0 && tr.GetTo() .GetDSTSavings() != 0) || (tr.GetFrom().GetDSTSavings() != 0 && tr .GetTo().GetDSTSavings() == 0)) { // Generate another DOW rule dtfields = IBM.ICU.Impl.Grego.TimeToFields(tr.GetTime() + tr.GetFrom().GetRawOffset() + tr.GetFrom().GetDSTSavings(), dtfields); weekInMonth = IBM.ICU.Impl.Grego.GetDayOfWeekInMonth( dtfields[0], dtfields[1], dtfields[2]); dtr = new DateTimeRule(dtfields[1], weekInMonth, dtfields[3], dtfields[5], IBM.ICU.Util.DateTimeRule.WALL_TIME); secondRule = new AnnualTimeZoneRule(tr.GetTo() .GetName(), tr.GetTo().GetRawOffset(), tr .GetTo().GetDSTSavings(), dtr, annualRules[0].GetStartYear() - 1, IBM.ICU.Util.AnnualTimeZoneRule.MAX_YEAR); // Check if this rule start after the first rule // after the specified date DateTime d_0 = secondRule.GetNextStart(date, tr.GetFrom() .GetRawOffset(), tr.GetFrom() .GetDSTSavings(), false); if ((d_0.Ticks / 10000) > nextTransitionTime) { // We can use this rule as the second transition // rule annualRules[1] = secondRule; } } } } if (annualRules[1] == null) { // Cannot generate a good pair of AnnualTimeZoneRule annualRules = null; } else { // The initial rule should represent the rule before the // previous transition initialName = annualRules[0].GetName(); initialRaw = annualRules[0].GetRawOffset(); initialDst = annualRules[0].GetDSTSavings(); } } initialRule = new InitialTimeZoneRule(initialName, initialRaw, initialDst); } else { // Try the previous one tr = GetPreviousTransition(date, true); if (tr != null) { initialRule = new InitialTimeZoneRule(tr.GetTo().GetName(), tr .GetTo().GetRawOffset(), tr.GetTo().GetDSTSavings()); } else { // No transitions in the past. Just use the current offsets int[] offsets = new int[2]; GetOffset(date, false, offsets); initialRule = new InitialTimeZoneRule(GetID(), offsets[0], offsets[1]); } } TimeZoneRule[] result = null; if (annualRules == null) { result = new TimeZoneRule[1]; result[0] = initialRule; } else { result = new TimeZoneRule[3]; result[0] = initialRule; result[1] = annualRules[0]; result[2] = annualRules[1]; } return(result); }
/// <summary> /// Gets the array of <c>TimeZoneRule</c> which represents the rule of /// this time zone object since the specified start time. The first element /// in the result array will be the <c>InitialTimeZoneRule</c> instance /// for the initial rule. The rest will be either /// <c>AnnualTimeZoneRule</c> or <c>TimeArrayTimeZoneRule</c> /// instances representing transitions. /// </summary> /// /// <param name="start">The start time (inclusive).</param> /// <returns>The array of <c>TimeZoneRule</c> which represents this time /// zone since the start time.</returns> /// @draft ICU 3.8 /// @provisional This API might change or be removed in a future release. public virtual TimeZoneRule[] GetTimeZoneRules(long start) { TimeZoneRule[] all = GetTimeZoneRules(); TimeZoneTransition tzt = GetPreviousTransition(start, true); if (tzt == null) { // No need to filter out rules only applicable to time before the // start return(all); } BitSet isProcessed = new BitSet(all.Length); IList filteredRules = new LinkedList(); // Create initial rule TimeZoneRule initial = new InitialTimeZoneRule(tzt.GetTo().GetName(), tzt.GetTo().GetRawOffset(), tzt.GetTo().GetDSTSavings()); ILOG.J2CsMapping.Collections.Generics.Collections.Add(filteredRules, initial); isProcessed.Set(0); // Mark rules which does not need to be processed for (int i = 1; i < all.Length; i++) { DateTime d = all[i].GetNextStart(start, initial.GetRawOffset(), initial.GetDSTSavings(), false); if (d == null) { isProcessed.Set(i); } } long time = start; bool bFinalStd = false, bFinalDst = false; while (!bFinalStd || !bFinalDst) { tzt = GetNextTransition(time, false); if (tzt == null) { break; } time = tzt.GetTime(); TimeZoneRule toRule = tzt.GetTo(); int ruleIdx = 1; for (; ruleIdx < all.Length; ruleIdx++) { if (all[ruleIdx].Equals(toRule)) { break; } } if (ruleIdx >= all.Length) { throw new InvalidOperationException("The rule was not found"); } if (isProcessed.Get(ruleIdx)) { continue; } if (toRule is TimeArrayTimeZoneRule) { TimeArrayTimeZoneRule tar = (TimeArrayTimeZoneRule)toRule; // Get the previous raw offset and DST savings before the very // first start time long t = start; while (true) { tzt = GetNextTransition(t, false); if (tzt == null) { break; } if (tzt.GetTo().Equals(tar)) { break; } t = tzt.GetTime(); } if (tzt != null) { // Check if the entire start times to be added DateTime firstStart = tar.GetFirstStart(tzt.GetFrom() .GetRawOffset(), tzt.GetFrom().GetDSTSavings()); if ((firstStart.Ticks / 10000) > start) { // Just add the rule as is ILOG.J2CsMapping.Collections.Generics.Collections.Add(filteredRules, tar); } else { // Collect transitions after the start time long[] times = tar.GetStartTimes(); int timeType = tar.GetTimeType(); int idx; for (idx = 0; idx < times.Length; idx++) { t = times[idx]; if (timeType == IBM.ICU.Util.DateTimeRule.STANDARD_TIME) { t -= tzt.GetFrom().GetRawOffset(); } if (timeType == IBM.ICU.Util.DateTimeRule.WALL_TIME) { t -= tzt.GetFrom().GetDSTSavings(); } if (t > start) { break; } } int asize = times.Length - idx; if (asize > 0) { long[] newtimes = new long[asize]; System.Array.Copy((Array)(times), idx, (Array)(newtimes), 0, asize); TimeArrayTimeZoneRule newtar = new TimeArrayTimeZoneRule( tar.GetName(), tar.GetRawOffset(), tar.GetDSTSavings(), newtimes, tar.GetTimeType()); ILOG.J2CsMapping.Collections.Generics.Collections.Add(filteredRules, newtar); } } } } else if (toRule is AnnualTimeZoneRule) { AnnualTimeZoneRule ar = (AnnualTimeZoneRule)toRule; DateTime firstStart_0 = ar.GetFirstStart( tzt.GetFrom().GetRawOffset(), tzt.GetFrom() .GetDSTSavings()); if ((firstStart_0.Ticks / 10000) == tzt.GetTime()) { // Just add the rule as is ILOG.J2CsMapping.Collections.Generics.Collections.Add(filteredRules, ar); } else { // Calculate the transition year int[] dfields = new int[6]; IBM.ICU.Impl.Grego.TimeToFields(tzt.GetTime(), dfields); // Recreate the rule AnnualTimeZoneRule newar = new AnnualTimeZoneRule( ar.GetName(), ar.GetRawOffset(), ar.GetDSTSavings(), ar.GetRule(), dfields[0], ar.GetEndYear()); ILOG.J2CsMapping.Collections.Generics.Collections.Add(filteredRules, newar); } // Check if this is a final rule if (ar.GetEndYear() == IBM.ICU.Util.AnnualTimeZoneRule.MAX_YEAR) { // After both final standard and dst rule are processed, // exit this while loop. if (ar.GetDSTSavings() == 0) { bFinalStd = true; } else { bFinalDst = true; } } } isProcessed.Set(ruleIdx); } TimeZoneRule[] rules = new TimeZoneRule[filteredRules.Count]; ILOG.J2CsMapping.Collections.Collections.ToArray(filteredRules, rules); return(rules); }
// private stuff /* * Resolve historic transition times and update fields used for offset * calculation. */ private void Complete() { if (upToDate) { // No rules were added since last time. return; } // Make sure either no final rules or a pair of AnnualTimeZoneRules // are available. if (finalRules != null && finalRules[1] == null) { throw new InvalidOperationException("Incomplete final rules"); } // Create a TimezoneTransition and add to the list if (historicRules != null || finalRules != null) { TimeZoneRule curRule = initialRule; long lastTransitionTime = IBM.ICU.Impl.Grego.MIN_MILLIS; // Build the transition array which represents historical time zone // transitions. if (historicRules != null) { BitSet done = new BitSet(historicRules.Count); // for skipping // rules already // processed while (true) { int curStdOffset = curRule.GetRawOffset(); int curDstSavings = curRule.GetDSTSavings(); long nextTransitionTime = IBM.ICU.Impl.Grego.MAX_MILLIS; TimeZoneRule nextRule = null; DateTime d; long tt; for (int i = 0; i < historicRules.Count; i++) { if (done.Get(i)) { continue; } TimeZoneRule r = (TimeZoneRule)historicRules[i]; d = r.GetNextStart(lastTransitionTime, curStdOffset, curDstSavings, false); if (d == null) { // No more transitions from this rule - skip this // rule next time done.Set(i); } else { if (r == curRule || (r.GetName().Equals(curRule.GetName()) && r.GetRawOffset() == curRule .GetRawOffset() && r .GetDSTSavings() == curRule .GetDSTSavings())) { continue; } tt = (d.Ticks / 10000); if (tt < nextTransitionTime) { nextTransitionTime = tt; nextRule = r; } } } if (nextRule == null) { // Check if all historic rules are done bool bDoneAll = true; for (int j = 0; j < historicRules.Count; j++) { if (!done.Get(j)) { bDoneAll = false; break; } } if (bDoneAll) { break; } } if (finalRules != null) { // Check if one of final rules has earlier transition // date for (int i_0 = 0; i_0 < 2 /* finalRules.length */; i_0++) { if ((Object)finalRules[i_0] == (Object)curRule) { continue; } d = finalRules[i_0].GetNextStart(lastTransitionTime, curStdOffset, curDstSavings, false); if (d != null) { tt = (d.Ticks / 10000); if (tt < nextTransitionTime) { nextTransitionTime = tt; nextRule = finalRules[i_0]; } } } } if (nextRule == null) { // Nothing more break; } if (historicTransitions == null) { historicTransitions = new ArrayList(); } ILOG.J2CsMapping.Collections.Generics.Collections.Add(historicTransitions, new TimeZoneTransition( nextTransitionTime, curRule, nextRule)); lastTransitionTime = nextTransitionTime; curRule = nextRule; } } if (finalRules != null) { if (historicTransitions == null) { historicTransitions = new ArrayList(); } // Append the first transition for each DateTime d0 = finalRules[0].GetNextStart(lastTransitionTime, curRule.GetRawOffset(), curRule.GetDSTSavings(), false); DateTime d1 = finalRules[1].GetNextStart(lastTransitionTime, curRule.GetRawOffset(), curRule.GetDSTSavings(), false); if (ILOG.J2CsMapping.Util.DateUtil.After(d1, d0)) { ILOG.J2CsMapping.Collections.Generics.Collections.Add(historicTransitions, new TimeZoneTransition( (d0.Ticks / 10000), curRule, finalRules[0])); d1 = finalRules[1].GetNextStart((d0.Ticks / 10000), finalRules[0].GetRawOffset(), finalRules[0].GetDSTSavings(), false); ILOG.J2CsMapping.Collections.Generics.Collections.Add(historicTransitions, new TimeZoneTransition( (d1.Ticks / 10000), finalRules[0], finalRules[1])); } else { ILOG.J2CsMapping.Collections.Generics.Collections.Add(historicTransitions, new TimeZoneTransition( (d1.Ticks / 10000), curRule, finalRules[1])); d0 = finalRules[0].GetNextStart((d1.Ticks / 10000), finalRules[1].GetRawOffset(), finalRules[1].GetDSTSavings(), false); ILOG.J2CsMapping.Collections.Generics.Collections.Add(historicTransitions, new TimeZoneTransition( (d0.Ticks / 10000), finalRules[1], finalRules[0])); } } } upToDate = true; }
/// <summary> /// /// </summary> /// /// @draft ICU 3.8 /// @provisional This API might change or be removed in a future release. public override TimeZoneTransition GetPreviousTransition(long bs, bool inclusive) { Complete(); if (historicTransitions == null) { return(null); } TimeZoneTransition result = null; TimeZoneTransition tzt = (TimeZoneTransition)historicTransitions[0]; long tt = tzt.GetTime(); if (inclusive && tt == bs) { result = tzt; } else if (tt >= bs) { return(null); } else { int idx = historicTransitions.Count - 1; tzt = (TimeZoneTransition)historicTransitions[idx]; tt = tzt.GetTime(); if (inclusive && tt == bs) { result = tzt; } else if (tt < bs) { if (finalRules != null) { // Find a transion time with finalRules DateTime start0 = finalRules[0].GetPreviousStart(bs, finalRules[1].GetRawOffset(), finalRules[1].GetDSTSavings(), inclusive); DateTime start1 = finalRules[1].GetPreviousStart(bs, finalRules[0].GetRawOffset(), finalRules[0].GetDSTSavings(), inclusive); if (ILOG.J2CsMapping.Util.DateUtil.Before(start1, start0)) { tzt = new TimeZoneTransition((start0.Ticks / 10000), finalRules[1], finalRules[0]); } else { tzt = new TimeZoneTransition((start1.Ticks / 10000), finalRules[0], finalRules[1]); } } result = tzt; } else { // Find a transition within the historic transitions idx--; while (idx >= 0) { tzt = (TimeZoneTransition)historicTransitions[idx]; tt = tzt.GetTime(); if (tt < bs || (inclusive && tt == bs)) { break; } idx--; } result = tzt; } } if (result != null) { // For now, this implementation ignore transitions with only zone // name changes. TimeZoneRule from = result.GetFrom(); TimeZoneRule to = result.GetTo(); if (from.GetRawOffset() == to.GetRawOffset() && from.GetDSTSavings() == to.GetDSTSavings()) { // No offset changes. Try previous one result = GetPreviousTransition(result.GetTime(), false /* * always * exclusive */); } } return(result); }
/// <summary> /// /// </summary> /// /// @draft ICU 3.8 /// @provisional This API might change or be removed in a future release. public override bool HasSameRules(TimeZone other) { if (!(other is RuleBasedTimeZone)) { // We cannot reasonably compare rules in different types return(false); } RuleBasedTimeZone otherRBTZ = (RuleBasedTimeZone)other; // initial rule if (!initialRule.IsEquivalentTo(otherRBTZ.initialRule)) { return(false); } // final rules if (finalRules != null && otherRBTZ.finalRules != null) { for (int i = 0; i < finalRules.Length; i++) { if (finalRules[i] == null && otherRBTZ.finalRules[i] == null) { continue; } if (finalRules[i] != null && otherRBTZ.finalRules[i] != null && finalRules[i] .IsEquivalentTo(otherRBTZ.finalRules[i])) { continue; } return(false); } } else if (finalRules != null || otherRBTZ.finalRules != null) { return(false); } // historic rules if (historicRules != null && otherRBTZ.historicRules != null) { if (historicRules.Count != otherRBTZ.historicRules.Count) { return(false); } IIterator it = new ILOG.J2CsMapping.Collections.IteratorAdapter(historicRules.GetEnumerator()); while (it.HasNext()) { TimeZoneRule rule = (TimeZoneRule)it.Next(); IIterator oit = new ILOG.J2CsMapping.Collections.IteratorAdapter(otherRBTZ.historicRules.GetEnumerator()); bool foundSameRule = false; while (oit.HasNext()) { TimeZoneRule orule = (TimeZoneRule)oit.Next(); if (rule.IsEquivalentTo(orule)) { foundSameRule = true; break; } } if (!foundSameRule) { return(false); } } } else if (historicRules != null || otherRBTZ.historicRules != null) { return(false); } return(true); }