final List<ZoneOffsetTransition> transitionList = new ArrayList<ZoneOffsetTransition>(256);
final List<ZoneOffsetTransitionRule> lastTransitionRuleList = new ArrayList<ZoneOffsetTransitionRule>(2);
// initialize the standard offset calculation
final TZWindow firstWindow = windowList.get(0);
ZoneOffset loopStandardOffset = firstWindow.standardOffset;
int loopSavings = 0;
if (firstWindow.fixedSavingAmountSecs != null) {
loopSavings = firstWindow.fixedSavingAmountSecs;
}
final ZoneOffset firstWallOffset = deduplicate(ZoneOffset.ofTotalSeconds(loopStandardOffset.getTotalSeconds() + loopSavings));
LocalDateTime loopWindowStart = deduplicate(LocalDateTime.of(Year.MIN_VALUE, 1, 1, 0, 0));
ZoneOffset loopWindowOffset = firstWallOffset;
// build the windows and rules to interesting data
for (TZWindow window : windowList) {
// tidy the state
window.tidy(loopWindowStart.getYear());
// calculate effective savings at the start of the window
Integer effectiveSavings = window.fixedSavingAmountSecs;
if (effectiveSavings == null) {
// apply rules from this window together with the standard offset and
// savings from the last window to find the savings amount applicable
// at start of this window
effectiveSavings = 0;
for (TZRule rule : window.ruleList) {
ZoneOffsetTransition trans = rule.toTransition(loopStandardOffset, loopSavings);
if (trans.toEpochSecond() > loopWindowStart.toEpochSecond(loopWindowOffset)) {
// previous savings amount found, which could be the savings amount at
// the instant that the window starts (hence isAfter)
break;
}
effectiveSavings = rule.savingAmountSecs;
}
}
// check if standard offset changed, and update it
if (loopStandardOffset.equals(window.standardOffset) == false) {
standardTransitionList.add(deduplicate(
new ZoneOffsetTransition(
LocalDateTime.ofEpochSecond(loopWindowStart.toEpochSecond(loopWindowOffset), 0, loopStandardOffset),
loopStandardOffset, window.standardOffset)));
loopStandardOffset = deduplicate(window.standardOffset);
}
// check if the start of the window represents a transition
ZoneOffset effectiveWallOffset = deduplicate(ZoneOffset.ofTotalSeconds(loopStandardOffset.getTotalSeconds() + effectiveSavings));
if (loopWindowOffset.equals(effectiveWallOffset) == false) {
ZoneOffsetTransition trans = deduplicate(
new ZoneOffsetTransition(loopWindowStart, loopWindowOffset, effectiveWallOffset));
transitionList.add(trans);
}