< prev index next >

make/jdk/src/classes/build/tools/tzdb/TzdbZoneRulesProvider.java

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 29,46 **** import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; ! import java.util.*; import java.util.Map.Entry; import java.util.concurrent.ConcurrentSkipListMap; import java.time.*; import java.time.Year; import java.time.chrono.IsoChronology; import java.time.temporal.TemporalAdjusters; ! import build.tools.tzdb.ZoneOffsetTransitionRule.TimeDefinition; import java.time.zone.ZoneRulesException; /** * Compile and build time-zone rules from IANA timezone data * --- 29,56 ---- import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; ! import java.util.ArrayList; ! import java.util.Collections; ! import java.util.List; ! import java.util.Map; import java.util.Map.Entry; + import java.util.NavigableMap; + import java.util.Objects; + import java.util.Set; + import java.util.TreeMap; + import java.util.TreeSet; import java.util.concurrent.ConcurrentSkipListMap; import java.time.*; import java.time.Year; import java.time.chrono.IsoChronology; import java.time.temporal.TemporalAdjusters; ! import java.time.zone.ZoneOffsetTransition; ! import java.time.zone.ZoneOffsetTransitionRule; ! import java.time.zone.ZoneOffsetTransitionRule.TimeDefinition; import java.time.zone.ZoneRulesException; /** * Compile and build time-zone rules from IANA timezone data *
*** 260,271 **** /** The time of the cutover, in second of day */ int secsOfDay = 0; /** Whether this is midnight end of day. */ boolean endOfDay; - /** The time definition of the cutover. */ TimeDefinition timeDefinition = TimeDefinition.WALL; void adjustToForwards(int year) { if (adjustForwards == false && dayOfMonth > 0) { // weekDay<=monthDay case, don't have it in tzdb data for now --- 270,281 ---- /** The time of the cutover, in second of day */ int secsOfDay = 0; /** Whether this is midnight end of day. */ boolean endOfDay; + /** The time of the cutover. */ TimeDefinition timeDefinition = TimeDefinition.WALL; void adjustToForwards(int year) { if (adjustForwards == false && dayOfMonth > 0) { // weekDay<=monthDay case, don't have it in tzdb data for now
*** 331,354 **** secsOfDay = parseSecs(timeStr); if (secsOfDay == 86400) { // time must be midnight when end of day flag is true endOfDay = true; secsOfDay = 0; - } else if (secsOfDay < 0 || secsOfDay > 86400) { - // beyond 0:00-24:00 range. Adjust the cutover date. - int beyondDays = secsOfDay / 86400; - secsOfDay %= 86400; - if (secsOfDay < 0) { - secsOfDay = 86400 + secsOfDay; - beyondDays -= 1; - } - LocalDate date = LocalDate.of(2004, month, dayOfMonth).plusDays(beyondDays); // leap-year - month = date.getMonth(); - dayOfMonth = date.getDayOfMonth(); - if (dayOfWeek != null) { - dayOfWeek = dayOfWeek.plus(beyondDays); - } } timeDefinition = parseTimeDefinition(timeStr.charAt(timeStr.length() - 1)); } } } --- 341,350 ----
*** 499,513 **** /** * Converts this to a transition rule. * * @param standardOffset the active standard offset, not null * @param savingsBeforeSecs the active savings before the transition in seconds - * @param negativeSavings minimum savings in the rule, usually zero, but negative if negative DST is - * in effect. * @return the transition, not null */ ! ZoneOffsetTransitionRule toTransitionRule(ZoneOffset stdOffset, int savingsBefore, int negativeSavings) { // rule shared by different zones, so don't change it Month month = this.month; int dayOfMonth = this.dayOfMonth; DayOfWeek dayOfWeek = this.dayOfWeek; boolean endOfDay = this.endOfDay; --- 495,507 ---- /** * Converts this to a transition rule. * * @param standardOffset the active standard offset, not null * @param savingsBeforeSecs the active savings before the transition in seconds * @return the transition, not null */ ! ZoneOffsetTransitionRule toTransitionRule(ZoneOffset stdOffset, int savingsBefore) { // rule shared by different zones, so don't change it Month month = this.month; int dayOfMonth = this.dayOfMonth; DayOfWeek dayOfWeek = this.dayOfWeek; boolean endOfDay = this.endOfDay;
*** 526,544 **** if (dayOfWeek != null) { dayOfWeek = dayOfWeek.plus(1); } endOfDay = false; } - // build rule return ZoneOffsetTransitionRule.of( //month, dayOfMonth, dayOfWeek, time, endOfDay, timeDefinition, month, dayOfMonth, dayOfWeek, LocalTime.ofSecondOfDay(secsOfDay), endOfDay, timeDefinition, stdOffset, ZoneOffset.ofTotalSeconds(stdOffset.getTotalSeconds() + savingsBefore), ! ZoneOffset.ofTotalSeconds(stdOffset.getTotalSeconds() + savingsAmount - negativeSavings)); } RuleLine parse(String[] tokens) { startYear = parseYear(tokens[2], 0); endYear = parseYear(tokens[3], startYear); --- 520,537 ---- if (dayOfWeek != null) { dayOfWeek = dayOfWeek.plus(1); } endOfDay = false; } // build rule return ZoneOffsetTransitionRule.of( //month, dayOfMonth, dayOfWeek, time, endOfDay, timeDefinition, month, dayOfMonth, dayOfWeek, LocalTime.ofSecondOfDay(secsOfDay), endOfDay, timeDefinition, stdOffset, ZoneOffset.ofTotalSeconds(stdOffset.getTotalSeconds() + savingsBefore), ! ZoneOffset.ofTotalSeconds(stdOffset.getTotalSeconds() + savingsAmount)); } RuleLine parse(String[] tokens) { startYear = parseYear(tokens[2], 0); endYear = parseYear(tokens[3], startYear);
*** 648,663 **** this.rule = rule; this.ldt = rule.toDateTime(year); this.ldtSecs = ldt.toEpochSecond(ZoneOffset.UTC); } ! ZoneOffsetTransition toTransition(ZoneOffset standardOffset, int savingsBeforeSecs, int negativeSavings) { // copy of code in ZoneOffsetTransitionRule to avoid infinite loop ZoneOffset wallOffset = ZoneOffset.ofTotalSeconds( standardOffset.getTotalSeconds() + savingsBeforeSecs); ZoneOffset offsetAfter = ZoneOffset.ofTotalSeconds( ! standardOffset.getTotalSeconds() + rule.savingsAmount - negativeSavings); LocalDateTime dt = rule.timeDefinition .createDateTime(ldt, standardOffset, wallOffset); return ZoneOffsetTransition.of(dt, wallOffset, offsetAfter); } --- 641,656 ---- this.rule = rule; this.ldt = rule.toDateTime(year); this.ldtSecs = ldt.toEpochSecond(ZoneOffset.UTC); } ! ZoneOffsetTransition toTransition(ZoneOffset standardOffset, int savingsBeforeSecs) { // copy of code in ZoneOffsetTransitionRule to avoid infinite loop ZoneOffset wallOffset = ZoneOffset.ofTotalSeconds( standardOffset.getTotalSeconds() + savingsBeforeSecs); ZoneOffset offsetAfter = ZoneOffset.ofTotalSeconds( ! standardOffset.getTotalSeconds() + rule.savingsAmount); LocalDateTime dt = rule.timeDefinition .createDateTime(ldt, standardOffset, wallOffset); return ZoneOffsetTransition.of(dt, wallOffset, offsetAfter); }
*** 671,686 **** /** * Tests if this a real transition with the active savings in seconds * * @param savingsBefore the active savings in seconds - * @param negativeSavings minimum savings in the rule, usually zero, but negative if negative DST is - * in effect. * @return true, if savings changes */ ! boolean isTransition(int savingsBefore, int negativeSavings) { ! return rule.savingsAmount - negativeSavings != savingsBefore; } public int compareTo(TransRule other) { return (ldtSecs < other.ldtSecs)? -1 : ((ldtSecs == other.ldtSecs) ? 0 : 1); } --- 664,677 ---- /** * Tests if this a real transition with the active savings in seconds * * @param savingsBefore the active savings in seconds * @return true, if savings changes */ ! boolean isTransition(int savingsBefore) { ! return rule.savingsAmount != savingsBefore; } public int compareTo(TransRule other) { return (ldtSecs < other.ldtSecs)? -1 : ((ldtSecs == other.ldtSecs) ? 0 : 1); }
*** 704,729 **** ZoneOffset wallOffset = ZoneOffset.ofTotalSeconds(stdOffset.getTotalSeconds() + savings); // start ldt of each zone window LocalDateTime zoneStart = LocalDateTime.MIN; ! // first standard offset ZoneOffset firstStdOffset = stdOffset; // first wall offset ZoneOffset firstWallOffset = wallOffset; for (ZoneLine zone : zones) { - // Adjust stdOffset, if negative DST is observed. It should be either - // fixed amount, or expressed in the named Rules. - int negativeSavings = Math.min(zone.fixedSavingsSecs, findNegativeSavings(zoneStart, zone)); - if (negativeSavings < 0) { - zone.stdOffsetSecs += negativeSavings; - if (zone.fixedSavingsSecs < 0) { - zone.fixedSavingsSecs = 0; - } - } - // check if standard offset changed, update it if yes ZoneOffset stdOffsetPrev = stdOffset; // for effectiveSavings check if (zone.stdOffsetSecs != stdOffset.getTotalSeconds()) { ZoneOffset stdOffsetNew = ZoneOffset.ofTotalSeconds(zone.stdOffsetSecs); standardTransitionList.add( --- 695,710 ---- ZoneOffset wallOffset = ZoneOffset.ofTotalSeconds(stdOffset.getTotalSeconds() + savings); // start ldt of each zone window LocalDateTime zoneStart = LocalDateTime.MIN; ! // first stanard offset ZoneOffset firstStdOffset = stdOffset; // first wall offset ZoneOffset firstWallOffset = wallOffset; for (ZoneLine zone : zones) { // check if standard offset changed, update it if yes ZoneOffset stdOffsetPrev = stdOffset; // for effectiveSavings check if (zone.stdOffsetSecs != stdOffset.getTotalSeconds()) { ZoneOffset stdOffsetNew = ZoneOffset.ofTotalSeconds(zone.stdOffsetSecs); standardTransitionList.add(
*** 808,827 **** Collections.sort(lastRules); } // sort the merged rules Collections.sort(trules); ! effectiveSavings = -negativeSavings; for (TransRule rule : trules) { if (rule.toEpochSecond(stdOffsetPrev, savings) > zoneStart.toEpochSecond(wallOffset)) { // previous savings amount found, which could be the // savings amount at the instant that the window starts // (hence isAfter) break; } ! effectiveSavings = rule.rule.savingsAmount - negativeSavings; } } // check if the start of the window represents a transition ZoneOffset effectiveWallOffset = ZoneOffset.ofTotalSeconds(stdOffset.getTotalSeconds() + effectiveSavings); --- 789,808 ---- Collections.sort(lastRules); } // sort the merged rules Collections.sort(trules); ! effectiveSavings = 0; for (TransRule rule : trules) { if (rule.toEpochSecond(stdOffsetPrev, savings) > zoneStart.toEpochSecond(wallOffset)) { // previous savings amount found, which could be the // savings amount at the instant that the window starts // (hence isAfter) break; } ! effectiveSavings = rule.rule.savingsAmount; } } // check if the start of the window represents a transition ZoneOffset effectiveWallOffset = ZoneOffset.ofTotalSeconds(stdOffset.getTotalSeconds() + effectiveSavings);
*** 834,858 **** savings = effectiveSavings; // apply rules within the window if (trules != null) { long zoneStartEpochSecs = zoneStart.toEpochSecond(wallOffset); for (TransRule trule : trules) { ! if (trule.isTransition(savings, negativeSavings)) { long epochSecs = trule.toEpochSecond(stdOffset, savings); if (epochSecs < zoneStartEpochSecs || epochSecs >= zone.toDateTimeEpochSecond(savings)) { continue; } ! transitionList.add(trule.toTransition(stdOffset, savings, negativeSavings)); ! savings = trule.rule.savingsAmount - negativeSavings; } } } if (lastRules != null) { for (TransRule trule : lastRules) { ! lastTransitionRuleList.add(trule.rule.toTransitionRule(stdOffset, savings, negativeSavings)); ! savings = trule.rule.savingsAmount - negativeSavings; } } // finally we can calculate the true end of the window, passing it to the next window wallOffset = ZoneOffset.ofTotalSeconds(stdOffset.getTotalSeconds() + savings); --- 815,839 ---- savings = effectiveSavings; // apply rules within the window if (trules != null) { long zoneStartEpochSecs = zoneStart.toEpochSecond(wallOffset); for (TransRule trule : trules) { ! if (trule.isTransition(savings)) { long epochSecs = trule.toEpochSecond(stdOffset, savings); if (epochSecs < zoneStartEpochSecs || epochSecs >= zone.toDateTimeEpochSecond(savings)) { continue; } ! transitionList.add(trule.toTransition(stdOffset, savings)); ! savings = trule.rule.savingsAmount; } } } if (lastRules != null) { for (TransRule trule : lastRules) { ! lastTransitionRuleList.add(trule.rule.toTransitionRule(stdOffset, savings)); ! savings = trule.rule.savingsAmount; } } // finally we can calculate the true end of the window, passing it to the next window wallOffset = ZoneOffset.ofTotalSeconds(stdOffset.getTotalSeconds() + savings);
*** 865,904 **** standardTransitionList, transitionList, lastTransitionRuleList); } - /** - * Find the minimum negative savings in named Rules for a Zone. Savings are only - * looked at for the period of the subject Zone. - * - * @param zoneStart start LDT of the zone - * @param zl ZoneLine to look at - */ - private int findNegativeSavings(LocalDateTime zoneStart, ZoneLine zl) { - int negativeSavings = 0; - LocalDateTime zoneEnd = zl.toDateTime(); - - if (zl.savingsRule != null) { - List<RuleLine> rlines = rules.get(zl.savingsRule); - if (rlines == null) { - throw new IllegalArgumentException("<Rule> not found: " + - zl.savingsRule); - } - - negativeSavings = Math.min(0, rlines.stream() - .filter(l -> windowOverlap(l, zoneStart.getYear(), zoneEnd.getYear())) - .map(l -> l.savingsAmount) - .min(Comparator.naturalOrder()) - .orElse(0)); - } - - return negativeSavings; - } - - private boolean windowOverlap(RuleLine ruleLine, int zoneStartYear, int zoneEndYear) { - boolean overlap = zoneStartYear <= ruleLine.startYear && zoneEndYear >= ruleLine.startYear || - zoneStartYear <= ruleLine.endYear && zoneEndYear >= ruleLine.endYear; - - return overlap; - } } --- 846,851 ----
< prev index next >