make/jdk/src/classes/build/tools/tzdb/TzdbZoneRulesProvider.java
author naoto
Fri, 26 Jul 2019 08:56:28 -0700
changeset 57544 99d2dd7b84a8
parent 51789 0535b5a54b83
permissions -rw-r--r--
8212970: TZ database in "vanguard" format support Reviewed-by: rriggs, joehw, erikj, scolebourne
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
     1
/*
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
     2
 * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
     4
 *
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    10
 *
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    15
 * accompanied this code).
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    16
 *
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    20
 *
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    23
 * questions.
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    24
 */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    25
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    26
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    27
package build.tools.tzdb;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    28
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    29
import java.io.IOException;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    30
import java.nio.charset.StandardCharsets;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    31
import java.nio.file.Files;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    32
import java.nio.file.Path;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    33
import java.nio.file.Paths;
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
    34
import java.util.*;
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    35
import java.util.Map.Entry;
51789
0535b5a54b83 8209880: tzdb.dat is not reproducibly built
naoto
parents: 47216
diff changeset
    36
import java.util.concurrent.ConcurrentSkipListMap;
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    37
import java.time.*;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    38
import java.time.Year;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    39
import java.time.chrono.IsoChronology;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    40
import java.time.temporal.TemporalAdjusters;
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
    41
import build.tools.tzdb.ZoneOffsetTransitionRule.TimeDefinition;
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    42
import java.time.zone.ZoneRulesException;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    43
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    44
/**
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    45
 * Compile and build time-zone rules from IANA timezone data
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    46
 *
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    47
 * @author Xueming Shen
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    48
 * @author Stephen Colebourne
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    49
 * @author Michael Nascimento Santos
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    50
 *
35302
e4d2275861c3 8136494: Update "@since 1.9" to "@since 9" to match java.version.specification
iris
parents: 28094
diff changeset
    51
 * @since   9
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    52
 */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    53
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    54
class TzdbZoneRulesProvider {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    55
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    56
    /**
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    57
     * Creates an instance.
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    58
     *
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    59
     * @throws ZoneRulesException if unable to load
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    60
     */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    61
    public TzdbZoneRulesProvider(List<Path> files) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    62
        try {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    63
             load(files);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    64
        } catch (Exception ex) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    65
            throw new ZoneRulesException("Unable to load TZDB time-zone rules", ex);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    66
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    67
    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    68
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    69
    public Set<String> getZoneIds() {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    70
        return new TreeSet(regionIds);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    71
    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    72
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    73
    public Map<String, String> getAliasMap() {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    74
        return links;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    75
    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    76
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    77
    public ZoneRules getZoneRules(String zoneId) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    78
        Object obj = zones.get(zoneId);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    79
        if (obj == null) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    80
            String zoneId0 = zoneId;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    81
            if (links.containsKey(zoneId)) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    82
                zoneId = links.get(zoneId);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    83
                obj = zones.get(zoneId);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    84
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    85
            if (obj == null) {
27726
34021e900889 8064914: tzdb.dat compilation failure when using tzdata2014j
aefimov
parents: 25158
diff changeset
    86
                // Timezone link can be located in 'backward' file and it
34021e900889 8064914: tzdb.dat compilation failure when using tzdata2014j
aefimov
parents: 25158
diff changeset
    87
                // can refer to another link, so we need to check for
34021e900889 8064914: tzdb.dat compilation failure when using tzdata2014j
aefimov
parents: 25158
diff changeset
    88
                // link one more time, before throwing an exception
34021e900889 8064914: tzdb.dat compilation failure when using tzdata2014j
aefimov
parents: 25158
diff changeset
    89
                String zoneIdBack = zoneId;
34021e900889 8064914: tzdb.dat compilation failure when using tzdata2014j
aefimov
parents: 25158
diff changeset
    90
                if (links.containsKey(zoneId)) {
34021e900889 8064914: tzdb.dat compilation failure when using tzdata2014j
aefimov
parents: 25158
diff changeset
    91
                    zoneId = links.get(zoneId);
34021e900889 8064914: tzdb.dat compilation failure when using tzdata2014j
aefimov
parents: 25158
diff changeset
    92
                    obj = zones.get(zoneId);
34021e900889 8064914: tzdb.dat compilation failure when using tzdata2014j
aefimov
parents: 25158
diff changeset
    93
                }
34021e900889 8064914: tzdb.dat compilation failure when using tzdata2014j
aefimov
parents: 25158
diff changeset
    94
                if (obj == null) {
34021e900889 8064914: tzdb.dat compilation failure when using tzdata2014j
aefimov
parents: 25158
diff changeset
    95
                    throw new ZoneRulesException("Unknown time-zone ID: " + zoneIdBack);
34021e900889 8064914: tzdb.dat compilation failure when using tzdata2014j
aefimov
parents: 25158
diff changeset
    96
                }
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    97
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    98
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
    99
        if (obj instanceof ZoneRules) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   100
            return (ZoneRules)obj;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   101
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   102
        try {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   103
            ZoneRules zrules = buildRules(zoneId, (List<ZoneLine>)obj);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   104
            zones.put(zoneId, zrules);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   105
            return zrules;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   106
        } catch (Exception ex) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   107
            throw new ZoneRulesException(
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   108
                "Invalid binary time-zone data: TZDB:" + zoneId, ex);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   109
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   110
    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   111
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   112
    //////////////////////////////////////////////////////////////////////
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   113
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   114
    /**
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   115
     * All the regions that are available.
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   116
     */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   117
    private List<String> regionIds = new ArrayList<>(600);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   118
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   119
    /**
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   120
     * Zone region to rules mapping
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   121
     */
51789
0535b5a54b83 8209880: tzdb.dat is not reproducibly built
naoto
parents: 47216
diff changeset
   122
    private final Map<String, Object> zones = new ConcurrentSkipListMap<>();
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   123
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   124
    /**
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   125
     * compatibility list
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   126
     */
51789
0535b5a54b83 8209880: tzdb.dat is not reproducibly built
naoto
parents: 47216
diff changeset
   127
    private static Set<String> excludedZones;
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   128
    static {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   129
        // (1) exclude EST, HST and MST. They are supported
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   130
        //     via the short-id mapping
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   131
        // (2) remove UTC and GMT
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   132
        // (3) remove ROC, which is not supported in j.u.tz
51789
0535b5a54b83 8209880: tzdb.dat is not reproducibly built
naoto
parents: 47216
diff changeset
   133
        excludedZones = new TreeSet<>();
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   134
        excludedZones.add("EST");
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   135
        excludedZones.add("HST");
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   136
        excludedZones.add("MST");
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   137
        excludedZones.add("GMT+0");
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   138
        excludedZones.add("GMT-0");
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   139
        excludedZones.add("ROC");
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   140
    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   141
51789
0535b5a54b83 8209880: tzdb.dat is not reproducibly built
naoto
parents: 47216
diff changeset
   142
    private Map<String, String> links = new TreeMap<>();
0535b5a54b83 8209880: tzdb.dat is not reproducibly built
naoto
parents: 47216
diff changeset
   143
    private Map<String, List<RuleLine>> rules = new TreeMap<>();
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   144
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   145
    private void load(List<Path> files) throws IOException {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   146
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   147
        for (Path file : files) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   148
            List<ZoneLine> openZone = null;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   149
            try {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   150
                for (String line : Files.readAllLines(file, StandardCharsets.ISO_8859_1)) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   151
                    if (line.length() == 0 || line.charAt(0) == '#') {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   152
                        continue;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   153
                    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   154
                    //StringIterator itr = new StringIterator(line);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   155
                    String[] tokens = split(line);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   156
                    if (openZone != null &&               // continuing zone line
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   157
                        Character.isWhitespace(line.charAt(0)) &&
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   158
                        tokens.length > 0) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   159
                        ZoneLine zLine = new ZoneLine();
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   160
                        openZone.add(zLine);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   161
                        if (zLine.parse(tokens, 0)) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   162
                            openZone = null;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   163
                        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   164
                        continue;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   165
                    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   166
                    if (line.startsWith("Zone")) {        // parse Zone line
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   167
                        String name = tokens[1];
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   168
                        if (excludedZones.contains(name)){
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   169
                            continue;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   170
                        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   171
                        if (zones.containsKey(name)) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   172
                            throw new IllegalArgumentException(
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   173
                                "Duplicated zone name in file: " + name +
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   174
                                ", line: [" + line + "]");
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   175
                        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   176
                        openZone = new ArrayList<>(10);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   177
                        zones.put(name, openZone);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   178
                        regionIds.add(name);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   179
                        ZoneLine zLine = new ZoneLine();
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   180
                        openZone.add(zLine);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   181
                        if (zLine.parse(tokens, 2)) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   182
                            openZone = null;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   183
                        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   184
                    } else if (line.startsWith("Rule")) { // parse Rule line
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   185
                        String name = tokens[1];
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   186
                        if (!rules.containsKey(name)) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   187
                            rules.put(name, new ArrayList<RuleLine>(10));
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   188
                        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   189
                        rules.get(name).add(new RuleLine().parse(tokens));
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   190
                    } else if (line.startsWith("Link")) { // parse link line
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   191
                        if (tokens.length >= 3) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   192
                            String realId = tokens[1];
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   193
                            String aliasId = tokens[2];
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   194
                            if (excludedZones.contains(aliasId)){
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   195
                                continue;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   196
                            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   197
                            links.put(aliasId, realId);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   198
                            regionIds.add(aliasId);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   199
                        } else {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   200
                            throw new IllegalArgumentException(
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   201
                                "Invalid Link line in file" +
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   202
                                file + ", line: [" + line + "]");
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   203
                        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   204
                    } else {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   205
                        // skip unknown line
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   206
                    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   207
                }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   208
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   209
            } catch (Exception ex) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   210
                throw new RuntimeException("Failed while processing file [" + file +
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   211
                                           "]", ex);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   212
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   213
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   214
    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   215
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   216
    private String[] split(String str) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   217
        int off = 0;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   218
        int end = str.length();
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   219
        ArrayList<String> list = new ArrayList<>(10);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   220
        while (off < end) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   221
            char c = str.charAt(off);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   222
            if (c == '\t' || c == ' ') {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   223
                off++;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   224
                continue;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   225
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   226
            if (c == '#') {    // comment
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   227
                break;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   228
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   229
            int start = off;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   230
            while (off < end) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   231
                c = str.charAt(off);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   232
                if (c == ' ' || c == '\t') {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   233
                    break;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   234
                }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   235
                off++;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   236
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   237
            if (start != off) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   238
                list.add(str.substring(start, off));
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   239
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   240
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   241
        return list.toArray(new String[list.size()]);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   242
    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   243
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   244
    /**
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   245
     * Class representing a month-day-time in the TZDB file.
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   246
     */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   247
    private static abstract class MonthDayTime {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   248
        /** The month of the cutover. */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   249
        Month month = Month.JANUARY;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   250
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   251
        /** The day-of-month of the cutover. */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   252
        int dayOfMonth = 1;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   253
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   254
        /** Whether to adjust forwards. */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   255
        boolean adjustForwards = true;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   256
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   257
        /** The day-of-week of the cutover. */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   258
        DayOfWeek dayOfWeek;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   259
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   260
        /** The time of the cutover, in second of day */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   261
        int secsOfDay = 0;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   262
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   263
        /** Whether this is midnight end of day. */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   264
        boolean endOfDay;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   265
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   266
        /** The time definition of the cutover. */
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   267
        TimeDefinition timeDefinition = TimeDefinition.WALL;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   268
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   269
        void adjustToForwards(int year) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   270
            if (adjustForwards == false && dayOfMonth > 0) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   271
                // weekDay<=monthDay case, don't have it in tzdb data for now
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   272
                LocalDate adjustedDate = LocalDate.of(year, month, dayOfMonth).minusDays(6);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   273
                dayOfMonth = adjustedDate.getDayOfMonth();
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   274
                month = adjustedDate.getMonth();
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   275
                adjustForwards = true;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   276
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   277
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   278
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   279
        LocalDateTime toDateTime(int year) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   280
            LocalDate date;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   281
            if (dayOfMonth < 0) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   282
                int monthLen = month.length(IsoChronology.INSTANCE.isLeapYear(year));
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   283
                date = LocalDate.of(year, month, monthLen + 1 + dayOfMonth);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   284
                if (dayOfWeek != null) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   285
                    date = date.with(TemporalAdjusters.previousOrSame(dayOfWeek));
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   286
                }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   287
            } else {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   288
                date = LocalDate.of(year, month, dayOfMonth);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   289
                if (dayOfWeek != null) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   290
                    date = date.with(TemporalAdjusters.nextOrSame(dayOfWeek));
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   291
                }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   292
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   293
            if (endOfDay) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   294
                date = date.plusDays(1);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   295
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   296
            return LocalDateTime.of(date, LocalTime.ofSecondOfDay(secsOfDay));
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   297
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   298
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   299
        /**
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   300
         * Parses the MonthDaytime segment of a tzdb line.
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   301
         */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   302
        private void parse(String[] tokens, int off) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   303
            month = parseMonth(tokens[off++]);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   304
            if (off < tokens.length) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   305
                String dayRule = tokens[off++];
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   306
                if (dayRule.startsWith("last")) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   307
                    dayOfMonth = -1;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   308
                    dayOfWeek = parseDayOfWeek(dayRule.substring(4));
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   309
                    adjustForwards = false;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   310
                } else {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   311
                    int index = dayRule.indexOf(">=");
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   312
                    if (index > 0) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   313
                        dayOfWeek = parseDayOfWeek(dayRule.substring(0, index));
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   314
                        dayRule = dayRule.substring(index + 2);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   315
                    } else {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   316
                        index = dayRule.indexOf("<=");
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   317
                        if (index > 0) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   318
                            dayOfWeek = parseDayOfWeek(dayRule.substring(0, index));
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   319
                            adjustForwards = false;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   320
                            dayRule = dayRule.substring(index + 2);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   321
                        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   322
                    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   323
                    dayOfMonth = Integer.parseInt(dayRule);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   324
                    if (dayOfMonth < -28 || dayOfMonth > 31 || dayOfMonth == 0) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   325
                       throw new IllegalArgumentException(
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   326
                          "Day of month indicator must be between -28 and 31 inclusive excluding zero");
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   327
                    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   328
                }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   329
                if (off < tokens.length) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   330
                    String timeStr = tokens[off++];
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   331
                    secsOfDay = parseSecs(timeStr);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   332
                    if (secsOfDay == 86400) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   333
                        // time must be midnight when end of day flag is true
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   334
                        endOfDay = true;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   335
                        secsOfDay = 0;
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   336
                    } else if (secsOfDay < 0 || secsOfDay > 86400) {
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   337
                        // beyond 0:00-24:00 range. Adjust the cutover date.
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   338
                        int beyondDays = secsOfDay / 86400;
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   339
                        secsOfDay %= 86400;
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   340
                        if (secsOfDay < 0) {
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   341
                            secsOfDay = 86400 + secsOfDay;
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   342
                            beyondDays -= 1;
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   343
                        }
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   344
                        LocalDate date = LocalDate.of(2004, month, dayOfMonth).plusDays(beyondDays);  // leap-year
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   345
                        month = date.getMonth();
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   346
                        dayOfMonth = date.getDayOfMonth();
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   347
                        if (dayOfWeek != null) {
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   348
                            dayOfWeek = dayOfWeek.plus(beyondDays);
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   349
                        }
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   350
                    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   351
                    timeDefinition = parseTimeDefinition(timeStr.charAt(timeStr.length() - 1));
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   352
                }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   353
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   354
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   355
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   356
        int parseYear(String year, int defaultYear) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   357
            switch (year.toLowerCase()) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   358
            case "min":  return 1900;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   359
            case "max":  return Year.MAX_VALUE;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   360
            case "only": return defaultYear;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   361
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   362
            return Integer.parseInt(year);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   363
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   364
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   365
        Month parseMonth(String mon) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   366
            switch (mon) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   367
            case "Jan": return Month.JANUARY;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   368
            case "Feb": return Month.FEBRUARY;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   369
            case "Mar": return Month.MARCH;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   370
            case "Apr": return Month.APRIL;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   371
            case "May": return Month.MAY;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   372
            case "Jun": return Month.JUNE;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   373
            case "Jul": return Month.JULY;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   374
            case "Aug": return Month.AUGUST;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   375
            case "Sep": return Month.SEPTEMBER;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   376
            case "Oct": return Month.OCTOBER;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   377
            case "Nov": return Month.NOVEMBER;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   378
            case "Dec": return Month.DECEMBER;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   379
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   380
            throw new IllegalArgumentException("Unknown month: " + mon);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   381
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   382
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   383
        DayOfWeek parseDayOfWeek(String dow) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   384
            switch (dow) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   385
            case "Mon": return DayOfWeek.MONDAY;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   386
            case "Tue": return DayOfWeek.TUESDAY;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   387
            case "Wed": return DayOfWeek.WEDNESDAY;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   388
            case "Thu": return DayOfWeek.THURSDAY;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   389
            case "Fri": return DayOfWeek.FRIDAY;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   390
            case "Sat": return DayOfWeek.SATURDAY;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   391
            case "Sun": return DayOfWeek.SUNDAY;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   392
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   393
            throw new IllegalArgumentException("Unknown day-of-week: " + dow);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   394
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   395
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   396
        String parseOptional(String str) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   397
            return str.equals("-") ? null : str;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   398
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   399
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   400
        static final boolean isDigit(char c) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   401
            return c >= '0' && c <= '9';
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   402
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   403
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   404
        private int parseSecs(String time) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   405
            if (time.equals("-")) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   406
                return 0;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   407
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   408
            // faster hack
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   409
            int secs = 0;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   410
            int sign = 1;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   411
            int off = 0;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   412
            int len = time.length();
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   413
            if (off < len && time.charAt(off) == '-') {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   414
                sign = -1;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   415
                off++;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   416
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   417
            char c0, c1;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   418
            if (off < len && isDigit(c0 = time.charAt(off++))) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   419
                int hour = c0 - '0';
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   420
                if (off < len && isDigit(c1 = time.charAt(off))) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   421
                    hour = hour * 10 + c1 - '0';
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   422
                    off++;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   423
                }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   424
                secs = hour * 60 * 60;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   425
                if (off < len && time.charAt(off++) == ':') {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   426
                    if (off + 1 < len &&
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   427
                        isDigit(c0 = time.charAt(off++)) &&
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   428
                        isDigit(c1 = time.charAt(off++))) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   429
                        // minutes
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   430
                        secs += ((c0 - '0') * 10 + c1 - '0') * 60;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   431
                        if (off < len && time.charAt(off++) == ':') {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   432
                            if (off + 1 < len &&
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   433
                                isDigit(c0 = time.charAt(off++)) &&
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   434
                                isDigit(c1 = time.charAt(off++))) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   435
                                // seconds
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   436
                                secs += ((c0 - '0') * 10 + c1 - '0');
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   437
                            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   438
                        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   439
                    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   440
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   441
                }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   442
                return secs * sign;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   443
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   444
            throw new IllegalArgumentException("[" + time + "]");
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   445
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   446
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   447
        int parseOffset(String str) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   448
            int secs = parseSecs(str);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   449
            if (Math.abs(secs) > 18 * 60 * 60) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   450
                throw new IllegalArgumentException(
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   451
                    "Zone offset not in valid range: -18:00 to +18:00");
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   452
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   453
            return secs;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   454
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   455
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   456
        int parsePeriod(String str) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   457
            return parseSecs(str);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   458
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   459
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   460
        TimeDefinition parseTimeDefinition(char c) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   461
            switch (c) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   462
            case 's':
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   463
            case 'S':
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   464
                // standard time
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   465
                return TimeDefinition.STANDARD;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   466
            case 'u':
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   467
            case 'U':
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   468
            case 'g':
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   469
            case 'G':
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   470
            case 'z':
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   471
            case 'Z':
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   472
                // UTC
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   473
                return TimeDefinition.UTC;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   474
            case 'w':
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   475
            case 'W':
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   476
            default:
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   477
                // wall time
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   478
                return TimeDefinition.WALL;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   479
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   480
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   481
    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   482
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   483
    /**
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   484
     * Class representing a rule line in the TZDB file.
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   485
     */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   486
    private static class RuleLine extends MonthDayTime {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   487
        /** The start year. */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   488
        int startYear;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   489
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   490
        /** The end year. */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   491
        int endYear;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   492
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   493
        /** The amount of savings, in seconds. */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   494
        int savingsAmount;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   495
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   496
        /** The text name of the zone. */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   497
        String text;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   498
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   499
        /**
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   500
         * Converts this to a transition rule.
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   501
         *
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   502
         * @param standardOffset  the active standard offset, not null
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   503
         * @param savingsBeforeSecs  the active savings before the transition in seconds
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   504
         * @param negativeSavings minimum savings in the rule, usually zero, but negative if negative DST is
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   505
         *                   in effect.
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   506
         * @return the transition, not null
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   507
        */
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   508
        ZoneOffsetTransitionRule toTransitionRule(ZoneOffset stdOffset, int savingsBefore, int negativeSavings) {
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   509
            // rule shared by different zones, so don't change it
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   510
            Month month = this.month;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   511
            int dayOfMonth = this.dayOfMonth;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   512
            DayOfWeek dayOfWeek = this.dayOfWeek;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   513
            boolean endOfDay = this.endOfDay;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   514
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   515
            // optimize stored format
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   516
            if (dayOfMonth < 0) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   517
                if (month != Month.FEBRUARY) {    // not Month.FEBRUARY
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   518
                    dayOfMonth = month.maxLength() - 6;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   519
                }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   520
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   521
            if (endOfDay && dayOfMonth > 0 &&
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   522
                (dayOfMonth == 28 && month == Month.FEBRUARY) == false) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   523
                LocalDate date = LocalDate.of(2004, month, dayOfMonth).plusDays(1);  // leap-year
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   524
                month = date.getMonth();
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   525
                dayOfMonth = date.getDayOfMonth();
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   526
                if (dayOfWeek != null) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   527
                    dayOfWeek = dayOfWeek.plus(1);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   528
                }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   529
                endOfDay = false;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   530
            }
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   531
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   532
            // build rule
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   533
            return ZoneOffsetTransitionRule.of(
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   534
                    //month, dayOfMonth, dayOfWeek, time, endOfDay, timeDefinition,
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   535
                    month, dayOfMonth, dayOfWeek,
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   536
                    LocalTime.ofSecondOfDay(secsOfDay), endOfDay, timeDefinition,
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   537
                    stdOffset,
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   538
                    ZoneOffset.ofTotalSeconds(stdOffset.getTotalSeconds() + savingsBefore),
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   539
                    ZoneOffset.ofTotalSeconds(stdOffset.getTotalSeconds() + savingsAmount - negativeSavings));
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   540
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   541
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   542
        RuleLine parse(String[] tokens) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   543
            startYear = parseYear(tokens[2], 0);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   544
            endYear = parseYear(tokens[3], startYear);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   545
            if (startYear > endYear) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   546
                throw new IllegalArgumentException(
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   547
                    "Invalid <Rule> line/Year order invalid:" + startYear + " > " + endYear);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   548
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   549
            //parseOptional(s.next());  // type is unused
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   550
            super.parse(tokens, 5);     // monthdaytime parsing
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   551
            savingsAmount = parsePeriod(tokens[8]);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   552
            //rule.text = parseOptional(s.next());
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   553
            return this;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   554
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   555
    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   556
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   557
    /**
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   558
     * Class representing a linked set of zone lines in the TZDB file.
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   559
     */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   560
    private static class ZoneLine extends MonthDayTime {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   561
        /** The standard offset. */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   562
        int stdOffsetSecs;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   563
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   564
        /** The fixed savings amount. */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   565
        int fixedSavingsSecs = 0;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   566
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   567
        /** The savings rule. */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   568
        String savingsRule;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   569
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   570
        /** The text name of the zone. */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   571
        String text;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   572
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   573
        /** The cutover year */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   574
        int year = Year.MAX_VALUE;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   575
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   576
        /** The cutover date time */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   577
        LocalDateTime ldt;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   578
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   579
        /** The cutover date/time in epoch seconds/UTC */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   580
        long ldtSecs = Long.MIN_VALUE;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   581
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   582
        LocalDateTime toDateTime() {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   583
            if (ldt == null) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   584
                ldt = toDateTime(year);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   585
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   586
            return ldt;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   587
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   588
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   589
        /**
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   590
         * Creates the date-time epoch second in the wall offset for the local
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   591
         * date-time at the end of the window.
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   592
         *
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   593
         * @param savingsSecs  the amount of savings in use in seconds
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   594
         * @return the created date-time epoch second in the wall offset, not null
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   595
         */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   596
        long toDateTimeEpochSecond(int savingsSecs) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   597
            if (ldtSecs == Long.MIN_VALUE) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   598
                ldtSecs = toDateTime().toEpochSecond(ZoneOffset.UTC);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   599
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   600
            switch(timeDefinition) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   601
            case UTC:      return ldtSecs;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   602
            case STANDARD: return ldtSecs - stdOffsetSecs;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   603
            default:       return ldtSecs - (stdOffsetSecs + savingsSecs); // WALL
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   604
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   605
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   606
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   607
        boolean parse(String[] tokens, int off) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   608
            stdOffsetSecs = parseOffset(tokens[off++]);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   609
            savingsRule = parseOptional(tokens[off++]);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   610
            if (savingsRule != null && savingsRule.length() > 0 &&
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   611
                (savingsRule.charAt(0) == '-' || isDigit(savingsRule.charAt(0)))) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   612
                try {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   613
                    fixedSavingsSecs = parsePeriod(savingsRule);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   614
                    savingsRule = null;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   615
                } catch (Exception ex) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   616
                    fixedSavingsSecs = 0;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   617
                }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   618
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   619
            text = tokens[off++];
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   620
            if (off < tokens.length) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   621
                year = Integer.parseInt(tokens[off++]);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   622
                if (off < tokens.length) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   623
                    super.parse(tokens, off);  // MonthDayTime
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   624
                }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   625
                return false;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   626
            } else {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   627
                return true;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   628
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   629
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   630
    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   631
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   632
    /**
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   633
     * Class representing a rule line in the TZDB file for a particular year.
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   634
     */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   635
    private static class TransRule implements Comparable<TransRule>
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   636
    {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   637
        private int year;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   638
        private RuleLine rule;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   639
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   640
        /** The trans date/time */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   641
        private LocalDateTime ldt;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   642
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   643
        /** The trans date/time in epoch seconds (assume UTC) */
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   644
        long ldtSecs;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   645
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   646
        TransRule(int year, RuleLine rule) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   647
            this.year = year;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   648
            this.rule = rule;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   649
            this.ldt = rule.toDateTime(year);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   650
            this.ldtSecs = ldt.toEpochSecond(ZoneOffset.UTC);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   651
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   652
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   653
        ZoneOffsetTransition toTransition(ZoneOffset standardOffset, int savingsBeforeSecs, int negativeSavings) {
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   654
            // copy of code in ZoneOffsetTransitionRule to avoid infinite loop
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   655
            ZoneOffset wallOffset = ZoneOffset.ofTotalSeconds(
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   656
                standardOffset.getTotalSeconds() + savingsBeforeSecs);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   657
            ZoneOffset offsetAfter = ZoneOffset.ofTotalSeconds(
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   658
                standardOffset.getTotalSeconds() + rule.savingsAmount - negativeSavings);
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   659
            LocalDateTime dt = rule.timeDefinition
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   660
                                   .createDateTime(ldt, standardOffset, wallOffset);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   661
            return ZoneOffsetTransition.of(dt, wallOffset, offsetAfter);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   662
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   663
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   664
        long toEpochSecond(ZoneOffset stdOffset, int savingsBeforeSecs) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   665
            switch(rule.timeDefinition) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   666
            case UTC:      return ldtSecs;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   667
            case STANDARD: return ldtSecs - stdOffset.getTotalSeconds();
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   668
            default:       return ldtSecs - (stdOffset.getTotalSeconds() + savingsBeforeSecs); // WALL
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   669
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   670
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   671
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   672
        /**
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   673
         * Tests if this a real transition with the active savings in seconds
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   674
         *
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   675
         * @param savingsBefore the active savings in seconds
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   676
         * @param negativeSavings minimum savings in the rule, usually zero, but negative if negative DST is
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   677
         *                   in effect.
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   678
         * @return true, if savings changes
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   679
         */
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   680
        boolean isTransition(int savingsBefore, int negativeSavings) {
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   681
            return rule.savingsAmount - negativeSavings != savingsBefore;
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   682
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   683
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   684
        public int compareTo(TransRule other) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   685
            return (ldtSecs < other.ldtSecs)? -1 : ((ldtSecs == other.ldtSecs) ? 0 : 1);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   686
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   687
    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   688
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   689
    private ZoneRules buildRules(String zoneId, List<ZoneLine> zones) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   690
        if (zones.isEmpty()) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   691
            throw new IllegalStateException("No available zone window");
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   692
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   693
        final List<ZoneOffsetTransition> standardTransitionList = new ArrayList<>(4);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   694
        final List<ZoneOffsetTransition> transitionList = new ArrayList<>(256);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   695
        final List<ZoneOffsetTransitionRule> lastTransitionRuleList = new ArrayList<>(2);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   696
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   697
        final ZoneLine zone0 = zones.get(0);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   698
        // initialize the standard offset, wallOffset and savings for loop
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   699
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   700
        //ZoneOffset stdOffset = zone0.standardOffset;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   701
        ZoneOffset stdOffset = ZoneOffset.ofTotalSeconds(zone0.stdOffsetSecs);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   702
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   703
        int savings = zone0.fixedSavingsSecs;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   704
        ZoneOffset wallOffset = ZoneOffset.ofTotalSeconds(stdOffset.getTotalSeconds() + savings);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   705
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   706
        // start ldt of each zone window
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   707
        LocalDateTime zoneStart = LocalDateTime.MIN;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   708
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   709
        // first standard offset
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   710
        ZoneOffset firstStdOffset = stdOffset;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   711
        // first wall offset
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   712
        ZoneOffset firstWallOffset = wallOffset;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   713
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   714
        for (ZoneLine zone : zones) {
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   715
            // Adjust stdOffset, if negative DST is observed. It should be either
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   716
            // fixed amount, or expressed in the named Rules.
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   717
            int negativeSavings = Math.min(zone.fixedSavingsSecs, findNegativeSavings(zoneStart, zone));
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   718
            if (negativeSavings < 0) {
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   719
                zone.stdOffsetSecs += negativeSavings;
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   720
                if (zone.fixedSavingsSecs < 0) {
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   721
                    zone.fixedSavingsSecs = 0;
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   722
                }
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   723
            }
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   724
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   725
            // check if standard offset changed, update it if yes
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   726
            ZoneOffset stdOffsetPrev = stdOffset;  // for effectiveSavings check
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   727
            if (zone.stdOffsetSecs != stdOffset.getTotalSeconds()) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   728
                ZoneOffset stdOffsetNew = ZoneOffset.ofTotalSeconds(zone.stdOffsetSecs);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   729
                standardTransitionList.add(
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   730
                    ZoneOffsetTransition.of(
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   731
                        LocalDateTime.ofEpochSecond(zoneStart.toEpochSecond(wallOffset),
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   732
                                                    0,
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   733
                                                    stdOffset),
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   734
                        stdOffset,
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   735
                        stdOffsetNew));
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   736
                stdOffset = stdOffsetNew;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   737
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   738
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   739
            LocalDateTime zoneEnd;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   740
            if (zone.year == Year.MAX_VALUE) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   741
                zoneEnd = LocalDateTime.MAX;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   742
            } else {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   743
                zoneEnd = zone.toDateTime();
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   744
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   745
            if (zoneEnd.compareTo(zoneStart) < 0) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   746
                throw new IllegalStateException("Windows must be in date-time order: " +
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   747
                        zoneEnd + " < " + zoneStart);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   748
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   749
            // calculate effective savings at the start of the window
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   750
            List<TransRule> trules = null;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   751
            List<TransRule> lastRules = null;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   752
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   753
            int effectiveSavings = zone.fixedSavingsSecs;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   754
            if (zone.savingsRule != null) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   755
                List<RuleLine> tzdbRules = rules.get(zone.savingsRule);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   756
                if (tzdbRules == null) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   757
                   throw new IllegalArgumentException("<Rule> not found: " +
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   758
                                                       zone.savingsRule);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   759
                }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   760
                trules = new ArrayList<>(256);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   761
                lastRules = new ArrayList<>(2);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   762
                int lastRulesStartYear = Year.MIN_VALUE;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   763
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   764
                // merge the rules to transitions
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   765
                for (RuleLine rule : tzdbRules) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   766
                    if (rule.startYear > zoneEnd.getYear()) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   767
                        // rules will not be used for this zone entry
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   768
                        continue;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   769
                    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   770
                    rule.adjustToForwards(2004);  // irrelevant, treat as leap year
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   771
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   772
                    int startYear = rule.startYear;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   773
                    int endYear = rule.endYear;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   774
                    if (zoneEnd.equals(LocalDateTime.MAX)) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   775
                        if (endYear == Year.MAX_VALUE) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   776
                            endYear = startYear;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   777
                            lastRules.add(new TransRule(endYear, rule));
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   778
                        }
28094
d0383a8fa398 8051641: Africa/Casablanca transitions is incorrectly calculated starting from 2027
aefimov
parents: 27726
diff changeset
   779
                        lastRulesStartYear = Math.max(startYear, lastRulesStartYear);
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   780
                    } else {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   781
                        if (endYear == Year.MAX_VALUE) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   782
                            //endYear = zoneEnd.getYear();
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   783
                            endYear = zone.year;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   784
                        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   785
                    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   786
                    int year = startYear;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   787
                    while (year <= endYear) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   788
                        trules.add(new TransRule(year, rule));
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   789
                        year++;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   790
                    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   791
                }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   792
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   793
                // last rules, fill the gap years between different last rules
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   794
                if (zoneEnd.equals(LocalDateTime.MAX)) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   795
                    lastRulesStartYear = Math.max(lastRulesStartYear, zoneStart.getYear()) + 1;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   796
                    for (TransRule rule : lastRules) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   797
                        if (rule.year <= lastRulesStartYear) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   798
                            int year = rule.year;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   799
                            while (year <= lastRulesStartYear) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   800
                                trules.add(new TransRule(year, rule.rule));
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   801
                                year++;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   802
                            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   803
                            rule.year = lastRulesStartYear;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   804
                            rule.ldt = rule.rule.toDateTime(year);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   805
                            rule.ldtSecs = rule.ldt.toEpochSecond(ZoneOffset.UTC);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   806
                        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   807
                    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   808
                    Collections.sort(lastRules);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   809
                }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   810
                // sort the merged rules
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   811
                Collections.sort(trules);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   812
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   813
                effectiveSavings = -negativeSavings;
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   814
                for (TransRule rule : trules) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   815
                    if (rule.toEpochSecond(stdOffsetPrev, savings) >
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   816
                        zoneStart.toEpochSecond(wallOffset)) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   817
                        // previous savings amount found, which could be the
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   818
                        // savings amount at the instant that the window starts
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   819
                        // (hence isAfter)
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   820
                        break;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   821
                    }
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   822
                    effectiveSavings = rule.rule.savingsAmount - negativeSavings;
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   823
                }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   824
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   825
            // check if the start of the window represents a transition
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   826
            ZoneOffset effectiveWallOffset =
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   827
                ZoneOffset.ofTotalSeconds(stdOffset.getTotalSeconds() + effectiveSavings);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   828
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   829
            if (!wallOffset.equals(effectiveWallOffset)) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   830
                transitionList.add(ZoneOffsetTransition.of(zoneStart,
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   831
                                                           wallOffset,
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   832
                                                           effectiveWallOffset));
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   833
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   834
            savings = effectiveSavings;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   835
            // apply rules within the window
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   836
            if (trules != null) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   837
                long zoneStartEpochSecs = zoneStart.toEpochSecond(wallOffset);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   838
                for (TransRule trule : trules) {
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   839
                    if (trule.isTransition(savings, negativeSavings)) {
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   840
                        long epochSecs = trule.toEpochSecond(stdOffset, savings);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   841
                        if (epochSecs < zoneStartEpochSecs ||
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   842
                            epochSecs >= zone.toDateTimeEpochSecond(savings)) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   843
                            continue;
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   844
                        }
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   845
                        transitionList.add(trule.toTransition(stdOffset, savings, negativeSavings));
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   846
                        savings = trule.rule.savingsAmount - negativeSavings;
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   847
                    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   848
                }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   849
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   850
            if (lastRules != null) {
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   851
                for (TransRule trule : lastRules) {
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   852
                    lastTransitionRuleList.add(trule.rule.toTransitionRule(stdOffset, savings, negativeSavings));
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   853
                    savings = trule.rule.savingsAmount - negativeSavings;
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   854
                }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   855
            }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   856
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   857
            // finally we can calculate the true end of the window, passing it to the next window
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   858
            wallOffset = ZoneOffset.ofTotalSeconds(stdOffset.getTotalSeconds() + savings);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   859
            zoneStart = LocalDateTime.ofEpochSecond(zone.toDateTimeEpochSecond(savings),
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   860
                                                    0,
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   861
                                                    wallOffset);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   862
        }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   863
        return new ZoneRules(firstStdOffset,
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   864
                             firstWallOffset,
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   865
                             standardTransitionList,
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   866
                             transitionList,
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   867
                             lastTransitionRuleList);
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   868
    }
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   869
57544
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   870
    /**
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   871
     * Find the minimum negative savings in named Rules for a Zone. Savings are only
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   872
     * looked at for the period of the subject Zone.
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   873
     *
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   874
     * @param zoneStart start LDT of the zone
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   875
     * @param zl ZoneLine to look at
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   876
     */
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   877
    private int findNegativeSavings(LocalDateTime zoneStart, ZoneLine zl) {
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   878
        int negativeSavings = 0;
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   879
        LocalDateTime zoneEnd = zl.toDateTime();
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   880
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   881
        if (zl.savingsRule != null) {
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   882
            List<RuleLine> rlines = rules.get(zl.savingsRule);
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   883
            if (rlines == null) {
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   884
                throw new IllegalArgumentException("<Rule> not found: " +
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   885
                        zl.savingsRule);
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   886
            }
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   887
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   888
            negativeSavings = Math.min(0, rlines.stream()
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   889
                    .filter(l -> windowOverlap(l, zoneStart.getYear(), zoneEnd.getYear()))
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   890
                    .map(l -> l.savingsAmount)
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   891
                    .min(Comparator.naturalOrder())
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   892
                    .orElse(0));
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   893
        }
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   894
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   895
        return negativeSavings;
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   896
    }
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   897
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   898
    private boolean windowOverlap(RuleLine ruleLine, int zoneStartYear, int zoneEndYear) {
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   899
        boolean overlap = zoneStartYear <= ruleLine.startYear && zoneEndYear >= ruleLine.startYear ||
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   900
                          zoneStartYear <= ruleLine.endYear && zoneEndYear >= ruleLine.endYear;
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   901
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   902
        return overlap;
99d2dd7b84a8 8212970: TZ database in "vanguard" format support
naoto
parents: 51789
diff changeset
   903
    }
25158
e76154c2c239 8042369: Remove duplicated java.time classes in build.tools.tzdb
sherman
parents:
diff changeset
   904
}