jdk/src/share/classes/sun/util/calendar/ZoneInfoFile.java
author sherman
Fri, 12 Apr 2013 07:57:35 -0700
changeset 16852 60207b2b4b42
parent 15665 2223468cd706
child 17464 268d3ce75045
permissions -rw-r--r--
8011172: JSR 310 DateTime API Updates II Summary: Integration of JSR310 Date/Time API update Reviewed-by: alanb, naoto, dholmes Contributed-by: scolebourne@joda.org, roger.riggs@oracle.com, masayoshi.okutsu@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
     2
 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4194
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4194
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4194
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4194
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 4194
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.util.calendar;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    28
import java.io.ByteArrayInputStream;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    29
import java.io.DataInput;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    30
import java.io.DataInputStream;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    31
import java.io.File;
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
    32
import java.io.FileInputStream;
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    33
import java.io.IOException;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    34
import java.io.StreamCorruptedException;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    35
import java.security.AccessController;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    36
import java.security.PrivilegedAction;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    37
import java.time.LocalDateTime;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    38
import java.time.ZoneOffset;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    39
import java.util.ArrayList;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    40
import java.util.Arrays;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    41
import java.util.Calendar;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    42
import java.util.Collections;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    43
import java.util.HashMap;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    44
import java.util.List;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    45
import java.util.Locale;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    46
import java.util.Map;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    47
import java.util.Map.Entry;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    48
import java.util.Objects;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    49
import java.util.Set;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    50
import java.util.SimpleTimeZone;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    51
import java.util.concurrent.ConcurrentHashMap;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    52
import java.util.zip.CRC32;
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
    53
import sun.security.action.GetPropertyAction;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
/**
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    56
 * Loads TZDB time-zone rules for j.u.TimeZone
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * <p>
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    58
 * @since 1.8
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 */
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    60
public final class ZoneInfoFile {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    62
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    63
     * Gets all available IDs supported in the Java run-time.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    64
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    65
     * @return a set of time zone IDs.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    66
     */
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
    67
    public static String[] getZoneIds() {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
    68
        String[] ids = Arrays.copyOf(regions, regions.length + oldMappings.length);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
    69
        int i = regions.length;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
    70
        for (int j = 0; j < oldMappings.length; j++) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
    71
            ids[i++] = oldMappings[j][0];
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
    72
        }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
    73
        return ids;
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    74
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    /**
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    77
     * Gets all available IDs that have the same value as the
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    78
     * specified raw GMT offset.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    79
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    80
     * @param rawOffset  the GMT offset in milliseconds. This
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    81
     *                   value should not include any daylight saving time.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    82
     * @return an array of time zone IDs.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
     */
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    84
    public static String[] getZoneIds(int rawOffset) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    85
        List<String> ids = new ArrayList<>();
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
    86
        for (String id : getZoneIds()) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
    87
            ZoneInfo zi = getZoneInfo(id);
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    88
            if (zi.getRawOffset() == rawOffset) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    89
                ids.add(id);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    90
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    91
        }
15665
2223468cd706 8008161: Regression: j.u.TimeZone.getAvailableIDs(rawOffset) returns non-sorted list
sherman
parents: 15658
diff changeset
    92
        // It appears the "zi" implementation returns the
2223468cd706 8008161: Regression: j.u.TimeZone.getAvailableIDs(rawOffset) returns non-sorted list
sherman
parents: 15658
diff changeset
    93
        // sorted list, though the specification does not
2223468cd706 8008161: Regression: j.u.TimeZone.getAvailableIDs(rawOffset) returns non-sorted list
sherman
parents: 15658
diff changeset
    94
        // specify it. Keep the same behavior for better
2223468cd706 8008161: Regression: j.u.TimeZone.getAvailableIDs(rawOffset) returns non-sorted list
sherman
parents: 15658
diff changeset
    95
        // compatibility.
2223468cd706 8008161: Regression: j.u.TimeZone.getAvailableIDs(rawOffset) returns non-sorted list
sherman
parents: 15658
diff changeset
    96
        String[] list = ids.toArray(new String[ids.size()]);
2223468cd706 8008161: Regression: j.u.TimeZone.getAvailableIDs(rawOffset) returns non-sorted list
sherman
parents: 15658
diff changeset
    97
        Arrays.sort(list);
2223468cd706 8008161: Regression: j.u.TimeZone.getAvailableIDs(rawOffset) returns non-sorted list
sherman
parents: 15658
diff changeset
    98
        return list;
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
    99
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   101
    public static ZoneInfo getZoneInfo(String zoneId) {
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   102
        if (zoneId == null) {
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   103
            return null;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   104
        }
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   105
        ZoneInfo zi = getZoneInfo0(zoneId);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   106
        if (zi != null) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   107
            zi = (ZoneInfo)zi.clone();
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   108
            zi.setID(zoneId);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   109
        }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   110
        return zi;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   111
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   113
    private static ZoneInfo getZoneInfo0(String zoneId) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   114
        try {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   115
            ZoneInfo zi = zones.get(zoneId);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   116
            if (zi != null) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   117
                return zi;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   118
            }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   119
            String zid = zoneId;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   120
            if (aliases.containsKey(zoneId)) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   121
                zid = aliases.get(zoneId);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   122
            }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   123
            int index = Arrays.binarySearch(regions, zid);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   124
            if (index < 0) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   125
                return null;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   126
            }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   127
            byte[] bytes = ruleArray[indices[index]];
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   128
            DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes));
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   129
            zi = getZoneInfo(dis, zid);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   130
            zones.put(zoneId, zi);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   131
            return zi;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   132
        } catch (Exception ex) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   133
            throw new RuntimeException("Invalid binary time-zone data: TZDB:" +
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   134
                zoneId + ", version: " + versionId, ex);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   135
        }
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   136
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    /**
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   139
     * Returns a Map from alias time zone IDs to their standard
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   140
     * time zone IDs.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   141
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   142
     * @return an unmodified alias mapping
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     */
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   144
    public static Map<String, String> getAliasMap() {
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   145
        return Collections.unmodifiableMap(aliases);
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   146
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    /**
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   149
     * Gets the version of this tz data.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   150
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   151
     * @return the tzdb version
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
     */
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   153
    public static String getVersion() {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   154
        return versionId;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
     * Gets a ZoneInfo with the given GMT offset. The object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
     * has its ID in the format of GMT{+|-}hh:mm.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
     *
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   161
     * @param originalId  the given custom id (before normalized such as "GMT+9")
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   162
     * @param gmtOffset   GMT offset <em>in milliseconds</em>
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
     * @return a ZoneInfo constructed with the given GMT offset
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    public static ZoneInfo getCustomTimeZone(String originalId, int gmtOffset) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        String id = toCustomID(gmtOffset);
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   167
        return new ZoneInfo(id, gmtOffset);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
    public static String toCustomID(int gmtOffset) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        char sign;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        int offset = gmtOffset / 60000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        if (offset >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
            sign = '+';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
            sign = '-';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
            offset = -offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        int hh = offset / 60;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        int mm = offset % 60;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        char[] buf = new char[] { 'G', 'M', 'T', sign, '0', '0', ':', '0', '0' };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        if (hh >= 10) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
            buf[4] += hh / 10;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        buf[5] += hh % 10;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        if (mm != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
            buf[7] += mm / 10;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            buf[8] += mm % 10;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
        return new String(buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   194
    ///////////////////////////////////////////////////////////
11130
c7093e306a34 7117487: Warnings Cleanup: some i18n classes in java.util and sun.util
okutsu
parents: 9025
diff changeset
   195
    private ZoneInfoFile() {
c7093e306a34 7117487: Warnings Cleanup: some i18n classes in java.util and sun.util
okutsu
parents: 9025
diff changeset
   196
    }
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   197
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   198
    private static String versionId;
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   199
    private final static Map<String, ZoneInfo> zones = new ConcurrentHashMap<>();
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   200
    private static Map<String, String> aliases = new HashMap<>();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   201
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   202
    private static byte[][] ruleArray;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   203
    private static String[] regions;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   204
    private static int[] indices;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   205
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   206
    // Flag for supporting JDK backward compatible IDs, such as "EST".
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   207
    private static final boolean USE_OLDMAPPING;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   208
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   209
    private static String[][] oldMappings = new String[][] {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   210
        { "ACT", "Australia/Darwin" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   211
        { "AET", "Australia/Sydney" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   212
        { "AGT", "America/Argentina/Buenos_Aires" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   213
        { "ART", "Africa/Cairo" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   214
        { "AST", "America/Anchorage" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   215
        { "BET", "America/Sao_Paulo" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   216
        { "BST", "Asia/Dhaka" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   217
        { "CAT", "Africa/Harare" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   218
        { "CNT", "America/St_Johns" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   219
        { "CST", "America/Chicago" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   220
        { "CTT", "Asia/Shanghai" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   221
        { "EAT", "Africa/Addis_Ababa" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   222
        { "ECT", "Europe/Paris" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   223
        { "IET", "America/Indiana/Indianapolis" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   224
        { "IST", "Asia/Kolkata" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   225
        { "JST", "Asia/Tokyo" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   226
        { "MIT", "Pacific/Apia" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   227
        { "NET", "Asia/Yerevan" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   228
        { "NST", "Pacific/Auckland" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   229
        { "PLT", "Asia/Karachi" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   230
        { "PNT", "America/Phoenix" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   231
        { "PRT", "America/Puerto_Rico" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   232
        { "PST", "America/Los_Angeles" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   233
        { "SST", "Pacific/Guadalcanal" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   234
        { "VST", "Asia/Ho_Chi_Minh" },
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   235
    };
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   236
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   237
    static {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   238
        String oldmapping = AccessController.doPrivileged(
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   239
            new GetPropertyAction("sun.timezone.ids.oldmapping", "false")).toLowerCase(Locale.ROOT);
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   240
        USE_OLDMAPPING = (oldmapping.equals("yes") || oldmapping.equals("true"));
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   241
        AccessController.doPrivileged(new PrivilegedAction<Object>() {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   242
            public Object run() {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   243
                try {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   244
                    String libDir = System.getProperty("java.home") + File.separator + "lib";
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   245
                    try (DataInputStream dis = new DataInputStream(
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   246
                             new FileInputStream(new File(libDir, "tzdb.dat")))) {
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   247
                        load(dis);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   248
                    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   249
                } catch (Exception x) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   250
                    throw new Error(x);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   251
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   252
                return null;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   253
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   254
        });
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   255
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   256
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   257
    private static void addOldMapping() {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   258
        for (String[] alias : oldMappings) {
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   259
            aliases.put(alias[0], alias[1]);
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   260
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   261
        if (USE_OLDMAPPING) {
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   262
            aliases.put("EST", "America/New_York");
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   263
            aliases.put("MST", "America/Denver");
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   264
            aliases.put("HST", "Pacific/Honolulu");
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   265
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   266
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   267
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   268
    /**
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   269
     * Loads the rules from a DateInputStream
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   270
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   271
     * @param dis  the DateInputStream to load, not null
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   272
     * @throws Exception if an error occurs
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   273
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   274
    private static void load(DataInputStream dis) throws ClassNotFoundException, IOException {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   275
        if (dis.readByte() != 1) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   276
            throw new StreamCorruptedException("File format not recognised");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   277
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   278
        // group
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   279
        String groupId = dis.readUTF();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   280
        if ("TZDB".equals(groupId) == false) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   281
            throw new StreamCorruptedException("File format not recognised");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   282
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   283
        // versions, only keep the last one
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   284
        int versionCount = dis.readShort();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   285
        for (int i = 0; i < versionCount; i++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   286
            versionId = dis.readUTF();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   287
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   288
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   289
        // regions
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   290
        int regionCount = dis.readShort();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   291
        String[] regionArray = new String[regionCount];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   292
        for (int i = 0; i < regionCount; i++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   293
            regionArray[i] = dis.readUTF();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   294
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   295
        // rules
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   296
        int ruleCount = dis.readShort();
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   297
        ruleArray = new byte[ruleCount][];
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   298
        for (int i = 0; i < ruleCount; i++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   299
            byte[] bytes = new byte[dis.readShort()];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   300
            dis.readFully(bytes);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   301
            ruleArray[i] = bytes;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   302
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   303
        // link version-region-rules, only keep the last version, if more than one
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   304
        for (int i = 0; i < versionCount; i++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   305
            regionCount = dis.readShort();
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   306
            regions = new String[regionCount];
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   307
            indices = new int[regionCount];
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   308
            for (int j = 0; j < regionCount; j++) {
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   309
                regions[j] = regionArray[dis.readShort()];
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   310
                indices[j] = dis.readShort();
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   311
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   312
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   313
        // remove the following ids from the map, they
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   314
        // are exclued from the "old" ZoneInfo
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   315
        zones.remove("ROC");
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   316
        for (int i = 0; i < versionCount; i++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   317
            int aliasCount = dis.readShort();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   318
            aliases.clear();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   319
            for (int j = 0; j < aliasCount; j++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   320
                String alias = regionArray[dis.readShort()];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   321
                String region = regionArray[dis.readShort()];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   322
                aliases.put(alias, region);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   323
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   324
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   325
        // old us time-zone names
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   326
        addOldMapping();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   327
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   328
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   329
    /////////////////////////Ser/////////////////////////////////
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   330
    public static ZoneInfo getZoneInfo(DataInput in, String zoneId) throws Exception {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   331
        byte type = in.readByte();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   332
        // TBD: assert ZRULES:
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   333
        int stdSize = in.readInt();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   334
        long[] stdTrans = new long[stdSize];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   335
        for (int i = 0; i < stdSize; i++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   336
            stdTrans[i] = readEpochSec(in);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   337
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   338
        int [] stdOffsets = new int[stdSize + 1];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   339
        for (int i = 0; i < stdOffsets.length; i++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   340
            stdOffsets[i] = readOffset(in);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   341
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   342
        int savSize = in.readInt();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   343
        long[] savTrans = new long[savSize];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   344
        for (int i = 0; i < savSize; i++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   345
            savTrans[i] = readEpochSec(in);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   346
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   347
        int[] savOffsets = new int[savSize + 1];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   348
        for (int i = 0; i < savOffsets.length; i++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   349
            savOffsets[i] = readOffset(in);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   350
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   351
        int ruleSize = in.readByte();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   352
        ZoneOffsetTransitionRule[] rules = new ZoneOffsetTransitionRule[ruleSize];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   353
        for (int i = 0; i < ruleSize; i++) {
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   354
            rules[i] = new ZoneOffsetTransitionRule(in);
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   355
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   356
        return getZoneInfo(zoneId, stdTrans, stdOffsets, savTrans, savOffsets, rules);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   357
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   358
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   359
    public static int readOffset(DataInput in) throws IOException {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   360
        int offsetByte = in.readByte();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   361
        return offsetByte == 127 ? in.readInt() : offsetByte * 900;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   362
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   363
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   364
    static long readEpochSec(DataInput in) throws IOException {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   365
        int hiByte = in.readByte() & 255;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   366
        if (hiByte == 255) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   367
            return in.readLong();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   368
        } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   369
            int midByte = in.readByte() & 255;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   370
            int loByte = in.readByte() & 255;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   371
            long tot = ((hiByte << 16) + (midByte << 8) + loByte);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   372
            return (tot * 900) - 4575744000L;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   373
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   374
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   375
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   376
    /////////////////////////ZoneRules --> ZoneInfo/////////////////////////////////
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   377
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   378
    // ZoneInfo starts with UTC1900
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   379
    private static final long UTC1900 = -2208988800L;
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   380
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   381
    // ZoneInfo ends with   UTC2037
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   382
    // LocalDateTime.of(2038, 1, 1, 0, 0, 0).toEpochSecond(ZoneOffset.UTC) - 1;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   383
    private static final long UTC2037 = 2145916799L;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   384
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   385
    // ZoneInfo has an ending entry for 2037, this need to be offset by
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   386
    // a "rawOffset"
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   387
    // LocalDateTime.of(2037, 1, 1, 0, 0, 0).toEpochSecond(ZoneOffset.UTC));
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   388
    private static final long LDT2037 = 2114380800L;
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   389
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   390
    /* Get a ZoneInfo instance.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   391
     *
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   392
     * @param standardTransitions  the standard transitions, not null
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   393
     * @param standardOffsets  the standard offsets, not null
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   394
     * @param savingsInstantTransitions  the standard transitions, not null
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   395
     * @param wallOffsets  the wall offsets, not null
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   396
     * @param lastRules  the recurring last rules, size 15 or less, not null
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   397
     */
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   398
    private static ZoneInfo getZoneInfo(String zoneId,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   399
                                        long[] standardTransitions,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   400
                                        int[] standardOffsets,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   401
                                        long[] savingsInstantTransitions,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   402
                                        int[] wallOffsets,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   403
                                        ZoneOffsetTransitionRule[] lastRules) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   404
        int rawOffset = 0;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   405
        int dstSavings = 0;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   406
        int checksum = 0;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   407
        int[] params = null;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   408
        boolean willGMTOffsetChange = false;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   409
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   410
        // rawOffset, pick the last one
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   411
        if (standardTransitions.length > 0)
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   412
            rawOffset = standardOffsets[standardOffsets.length - 1] * 1000;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   413
        else
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   414
            rawOffset = standardOffsets[0] * 1000;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   415
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   416
        // transitions, offsets;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   417
        long[] transitions = null;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   418
        int[]  offsets = null;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   419
        int    nOffsets = 0;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   420
        int    nTrans = 0;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   421
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   422
        if (savingsInstantTransitions.length != 0) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   423
            transitions = new long[250];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   424
            offsets = new int[100];    // TBD: ZoneInfo actually can't handle
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   425
                                       // offsets.length > 16 (4-bit index limit)
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   426
            // last year in trans table
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   427
            // It should not matter to use before or after offset for year
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   428
            int lastyear = getYear(savingsInstantTransitions[savingsInstantTransitions.length - 1],
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   429
                                   wallOffsets[savingsInstantTransitions.length - 1]);
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   430
            int i = 0, k = 1;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   431
            while (i < savingsInstantTransitions.length &&
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   432
                   savingsInstantTransitions[i] < UTC1900) {
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   433
                i++;     // skip any date before UTC1900
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   434
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   435
            if (i < savingsInstantTransitions.length) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   436
                // javazic writes the last GMT offset into index 0!
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   437
                if (i < savingsInstantTransitions.length) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   438
                    offsets[0] = standardOffsets[standardOffsets.length - 1] * 1000;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   439
                    nOffsets = 1;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   440
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   441
                // ZoneInfo has a beginning entry for 1900.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   442
                // Only add it if this is not the only one in table
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   443
                nOffsets = addTrans(transitions, nTrans++,
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   444
                                    offsets, nOffsets,
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   445
                                    UTC1900,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   446
                                    wallOffsets[i],
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   447
                                    getStandardOffset(standardTransitions, standardOffsets, UTC1900));
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   448
            }
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   449
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   450
            for (; i < savingsInstantTransitions.length; i++) {
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   451
                long trans = savingsInstantTransitions[i];
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   452
                if (trans > UTC2037) {
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   453
                    // no trans beyond LASTYEAR
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   454
                    lastyear = LASTYEAR;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   455
                    break;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   456
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   457
                while (k < standardTransitions.length) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   458
                    // some standard offset transitions don't exist in
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   459
                    // savingInstantTrans, if the offset "change" doesn't
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   460
                    // really change the "effectiveWallOffset". For example
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   461
                    // the 1999/2000 pair in Zone Arg/Buenos_Aires, in which
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   462
                    // the daylightsaving "happened" but it actually does
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   463
                    // not result in the timezone switch. ZoneInfo however
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   464
                    // needs them in its transitions table
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   465
                    long trans_s = standardTransitions[k];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   466
                    if (trans_s >= UTC1900) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   467
                        if (trans_s > trans)
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   468
                            break;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   469
                        if (trans_s < trans) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   470
                            if (nOffsets + 2 >= offsets.length) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   471
                                offsets = Arrays.copyOf(offsets, offsets.length + 100);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   472
                            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   473
                            if (nTrans + 1 >= transitions.length) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   474
                                transitions = Arrays.copyOf(transitions, transitions.length + 100);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   475
                            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   476
                            nOffsets = addTrans(transitions, nTrans++, offsets, nOffsets,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   477
                                                trans_s,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   478
                                                wallOffsets[i],
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   479
                                                standardOffsets[k+1]);
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   480
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   481
                        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   482
                    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   483
                    k++;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   484
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   485
                if (nOffsets + 2 >= offsets.length) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   486
                    offsets = Arrays.copyOf(offsets, offsets.length + 100);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   487
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   488
                if (nTrans + 1 >= transitions.length) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   489
                    transitions = Arrays.copyOf(transitions, transitions.length + 100);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   490
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   491
                nOffsets = addTrans(transitions, nTrans++, offsets, nOffsets,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   492
                                    trans,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   493
                                    wallOffsets[i + 1],
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   494
                                    getStandardOffset(standardTransitions, standardOffsets, trans));
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   495
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   496
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   497
            // append any leftover standard trans
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   498
            while (k < standardTransitions.length) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   499
                long trans = standardTransitions[k];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   500
                if (trans >= UTC1900) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   501
                    int offset = wallOffsets[i];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   502
                    int offsetIndex = indexOf(offsets, 0, nOffsets, offset);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   503
                    if (offsetIndex == nOffsets)
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   504
                        nOffsets++;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   505
                    transitions[nTrans++] = ((trans * 1000) << TRANSITION_NSHIFT) |
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   506
                                            (offsetIndex & OFFSET_MASK);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   507
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   508
                k++;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   509
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   510
            if (lastRules.length > 1) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   511
                // fill the gap between the last trans until LASTYEAR
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   512
                while (lastyear++ < LASTYEAR) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   513
                    for (ZoneOffsetTransitionRule zotr : lastRules) {
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   514
                        long trans = zotr.getTransitionEpochSecond(lastyear);
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   515
                        if (nOffsets + 2 >= offsets.length) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   516
                            offsets = Arrays.copyOf(offsets, offsets.length + 100);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   517
                        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   518
                        if (nTrans + 1 >= transitions.length) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   519
                            transitions = Arrays.copyOf(transitions, transitions.length + 100);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   520
                        }
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   521
                        nOffsets = addTrans(transitions, nTrans++,
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   522
                                            offsets, nOffsets,
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   523
                                            trans,
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   524
                                            zotr.offsetAfter,
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   525
                                            zotr.standardOffset);
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   526
                    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   527
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   528
                ZoneOffsetTransitionRule startRule =  lastRules[lastRules.length - 2];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   529
                ZoneOffsetTransitionRule endRule =  lastRules[lastRules.length - 1];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   530
                params = new int[10];
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   531
                if (startRule.offsetAfter - startRule.offsetBefore < 0 &&
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   532
                    endRule.offsetAfter - endRule.offsetBefore > 0) {
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   533
                    ZoneOffsetTransitionRule tmp;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   534
                    tmp = startRule;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   535
                    startRule = endRule;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   536
                    endRule = tmp;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   537
                }
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   538
                params[0] = startRule.month - 1;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   539
                int dom = startRule.dom;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   540
                int dow = startRule.dow;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   541
                if (dow == -1) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   542
                    params[1] = dom;
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   543
                    params[2] = 0;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   544
                } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   545
                    // ZoneRulesBuilder adjusts < 0 case (-1, for last, don't have
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   546
                    // "<=" case yet) to positive value if not February (it appears
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   547
                    // we don't have February cutoff in tzdata table yet)
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   548
                    // Ideally, if JSR310 can just pass in the nagative and
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   549
                    // we can then pass in the dom = -1, dow > 0 into ZoneInfo
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   550
                    //
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   551
                    // hacking, assume the >=24 is the result of ZRB optimization for
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   552
                    // "last", it works for now.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   553
                    if (dom < 0 || dom >= 24) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   554
                        params[1] = -1;
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   555
                        params[2] = toCalendarDOW[dow];
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   556
                    } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   557
                        params[1] = dom;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   558
                        // To specify a day of week on or after an exact day of month,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   559
                        // set the month to an exact month value, day-of-month to the
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   560
                        // day on or after which the rule is applied, and day-of-week
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   561
                        // to a negative Calendar.DAY_OF_WEEK DAY_OF_WEEK field value.
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   562
                        params[2] = -toCalendarDOW[dow];
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   563
                    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   564
                }
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   565
                params[3] = startRule.secondOfDay * 1000;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   566
                params[4] = toSTZTime[startRule.timeDefinition];
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   567
                params[5] = endRule.month - 1;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   568
                dom = endRule.dom;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   569
                dow = endRule.dow;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   570
                if (dow == -1) {
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   571
                    params[6] = dom;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   572
                    params[7] = 0;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   573
                } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   574
                    // hacking: see comment above
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   575
                    if (dom < 0 || dom >= 24) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   576
                        params[6] = -1;
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   577
                        params[7] = toCalendarDOW[dow];
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   578
                    } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   579
                        params[6] = dom;
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   580
                        params[7] = -toCalendarDOW[dow];
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   581
                    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   582
                }
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   583
                params[8] = endRule.secondOfDay * 1000;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   584
                params[9] = toSTZTime[endRule.timeDefinition];
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   585
                dstSavings = (startRule.offsetAfter - startRule.offsetBefore) * 1000;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   586
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   587
                // Note: known mismatching -> Asia/Amman
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   588
                // ZoneInfo :      startDayOfWeek=5     <= Thursday
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   589
                //                 startTime=86400000   <= 24 hours
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   590
                // This:           startDayOfWeek=6
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   591
                //                 startTime=0
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   592
                // Below is the workaround, it probably slows down everyone a little
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   593
                if (params[2] == 6 && params[3] == 0 && zoneId.equals("Asia/Amman")) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   594
                    params[2] = 5;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   595
                    params[3] = 86400000;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   596
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   597
            } else if (nTrans > 0) {  // only do this if there is something in table already
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   598
                if (lastyear < LASTYEAR) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   599
                    // ZoneInfo has an ending entry for 2037
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   600
                    //long trans = OffsetDateTime.of(LASTYEAR, 1, 1, 0, 0, 0, 0,
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   601
                    //                               ZoneOffset.ofTotalSeconds(rawOffset/1000))
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   602
                    //                           .toEpochSecond();
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   603
                    long trans = LDT2037 - rawOffset/1000;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   604
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   605
                    int offsetIndex = indexOf(offsets, 0, nOffsets, rawOffset/1000);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   606
                    if (offsetIndex == nOffsets)
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   607
                        nOffsets++;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   608
                    transitions[nTrans++] = (trans * 1000) << TRANSITION_NSHIFT |
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   609
                                       (offsetIndex & OFFSET_MASK);
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   610
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   611
                } else if (savingsInstantTransitions.length > 2) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   612
                    // Workaround: create the params based on the last pair for
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   613
                    // zones like Israel and Iran which have trans defined
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   614
                    // up until 2037, but no "transition rule" defined
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   615
                    //
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   616
                    // Note: Known mismatching for Israel, Asia/Jerusalem/Tel Aviv
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   617
                    // ZoneInfo:        startMode=3
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   618
                    //                  startMonth=2
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   619
                    //                  startDay=26
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   620
                    //                  startDayOfWeek=6
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   621
                    //
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   622
                    // This:            startMode=1
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   623
                    //                  startMonth=2
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   624
                    //                  startDay=27
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   625
                    //                  startDayOfWeek=0
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   626
                    // these two are actually the same for 2037, the SimpleTimeZone
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   627
                    // for the last "known" year
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   628
                    int m = savingsInstantTransitions.length;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   629
                    long startTrans = savingsInstantTransitions[m - 2];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   630
                    int startOffset = wallOffsets[m - 2 + 1];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   631
                    int startStd = getStandardOffset(standardTransitions, standardOffsets, startTrans);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   632
                    long endTrans =  savingsInstantTransitions[m - 1];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   633
                    int endOffset = wallOffsets[m - 1 + 1];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   634
                    int endStd = getStandardOffset(standardTransitions, standardOffsets, endTrans);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   635
                    if (startOffset > startStd && endOffset == endStd) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   636
                        // last - 1 trans
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   637
                        m = savingsInstantTransitions.length - 2;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   638
                        ZoneOffset before = ZoneOffset.ofTotalSeconds(wallOffsets[m]);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   639
                        ZoneOffset after = ZoneOffset.ofTotalSeconds(wallOffsets[m + 1]);
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   640
                        LocalDateTime ldt = LocalDateTime.ofEpochSecond(savingsInstantTransitions[m], 0, before);
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   641
                        LocalDateTime startLDT;
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   642
                        if (after.getTotalSeconds() > before.getTotalSeconds()) {  // isGap()
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   643
                            startLDT = ldt;
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   644
                        } else {
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   645
                            startLDT = ldt.plusSeconds(wallOffsets[m + 1] - wallOffsets[m]);
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   646
                        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   647
                        // last trans
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   648
                        m = savingsInstantTransitions.length - 1;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   649
                        before = ZoneOffset.ofTotalSeconds(wallOffsets[m]);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   650
                        after = ZoneOffset.ofTotalSeconds(wallOffsets[m + 1]);
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   651
                        ldt = LocalDateTime.ofEpochSecond(savingsInstantTransitions[m], 0, before);
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   652
                        LocalDateTime endLDT;
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   653
                        if (after.getTotalSeconds() > before.getTotalSeconds()) {  // isGap()
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   654
                            endLDT = ldt.plusSeconds(wallOffsets[m + 1] - wallOffsets[m]);
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   655
                        } else {
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   656
                            endLDT = ldt;
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   657
                        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   658
                        params = new int[10];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   659
                        params[0] = startLDT.getMonthValue() - 1;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   660
                        params[1] = startLDT.getDayOfMonth();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   661
                        params[2] = 0;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   662
                        params[3] = startLDT.toLocalTime().toSecondOfDay() * 1000;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   663
                        params[4] = SimpleTimeZone.WALL_TIME;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   664
                        params[5] = endLDT.getMonthValue() - 1;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   665
                        params[6] = endLDT.getDayOfMonth();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   666
                        params[7] = 0;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   667
                        params[8] = endLDT.toLocalTime().toSecondOfDay() * 1000;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   668
                        params[9] = SimpleTimeZone.WALL_TIME;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   669
                        dstSavings = (startOffset - startStd) * 1000;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   670
                    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   671
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   672
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   673
            if (transitions != null && transitions.length != nTrans) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   674
                if (nTrans == 0) {
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   675
                    transitions = null;
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   676
                } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   677
                    transitions = Arrays.copyOf(transitions, nTrans);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   678
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   679
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   680
            if (offsets != null && offsets.length != nOffsets) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   681
                if (nOffsets == 0) {
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   682
                    offsets = null;
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   683
                } else {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   684
                    offsets = Arrays.copyOf(offsets, nOffsets);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   685
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   686
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   687
            if (transitions != null) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   688
                Checksum sum = new Checksum();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   689
                for (i = 0; i < transitions.length; i++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   690
                    long val = transitions[i];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   691
                    int dst = (int)((val >>> DST_NSHIFT) & 0xfL);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   692
                    int saving = (dst == 0) ? 0 : offsets[dst];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   693
                    int index = (int)(val & OFFSET_MASK);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   694
                    int offset = offsets[index];
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   695
                    long second = (val >> TRANSITION_NSHIFT);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   696
                    // javazic uses "index of the offset in offsets",
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   697
                    // instead of the real offset value itself to
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   698
                    // calculate the checksum. Have to keep doing
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   699
                    // the same thing, checksum is part of the
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   700
                    // ZoneInfo serialization form.
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   701
                    sum.update(second + index);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   702
                    sum.update(index);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   703
                    sum.update(dst == 0 ? -1 : dst);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   704
                }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   705
                checksum = (int)sum.getValue();
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   706
            }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   707
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   708
        return new ZoneInfo(zoneId, rawOffset, dstSavings, checksum, transitions,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   709
                            offsets, params, willGMTOffsetChange);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   710
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   711
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   712
    private static int getStandardOffset(long[] standardTransitions,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   713
                                         int[] standardOffsets,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   714
                                         long epochSec) {
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   715
        // The size of stdOffsets is [0..9], with most are
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   716
        // [1..4] entries , simple loop search is faster
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   717
        //
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   718
        // int index  = Arrays.binarySearch(standardTransitions, epochSec);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   719
        // if (index < 0) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   720
        //    // switch negative insert position to start of matched range
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   721
        //    index = -index - 2;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   722
        // }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   723
        // return standardOffsets[index + 1];
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   724
        int index = 0;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   725
        for (; index < standardTransitions.length; index++) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   726
            if (epochSec < standardTransitions[index]) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   727
                break;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   728
            }
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   729
        }
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   730
        return standardOffsets[index];
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   731
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   732
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   733
    static final int SECONDS_PER_DAY = 86400;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   734
    static final int DAYS_PER_CYCLE = 146097;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   735
    static final long DAYS_0000_TO_1970 = (DAYS_PER_CYCLE * 5L) - (30L * 365L + 7L);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   736
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   737
    private static int getYear(long epochSecond, int offset) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   738
        long second = epochSecond + offset;  // overflow caught later
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   739
        long epochDay = Math.floorDiv(second, SECONDS_PER_DAY);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   740
        long zeroDay = epochDay + DAYS_0000_TO_1970;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   741
        // find the march-based year
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   742
        zeroDay -= 60;  // adjust to 0000-03-01 so leap day is at end of four year cycle
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   743
        long adjust = 0;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   744
        if (zeroDay < 0) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   745
            // adjust negative years to positive for calculation
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   746
            long adjustCycles = (zeroDay + 1) / DAYS_PER_CYCLE - 1;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   747
            adjust = adjustCycles * 400;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   748
            zeroDay += -adjustCycles * DAYS_PER_CYCLE;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   749
        }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   750
        long yearEst = (400 * zeroDay + 591) / DAYS_PER_CYCLE;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   751
        long doyEst = zeroDay - (365 * yearEst + yearEst / 4 - yearEst / 100 + yearEst / 400);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   752
        if (doyEst < 0) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   753
            // fix estimate
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   754
            yearEst--;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   755
            doyEst = zeroDay - (365 * yearEst + yearEst / 4 - yearEst / 100 + yearEst / 400);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   756
        }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   757
        yearEst += adjust;  // reset any negative year
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   758
        int marchDoy0 = (int) doyEst;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   759
        // convert march-based values back to january-based
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   760
        int marchMonth0 = (marchDoy0 * 5 + 2) / 153;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   761
        int month = (marchMonth0 + 2) % 12 + 1;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   762
        int dom = marchDoy0 - (marchMonth0 * 306 + 5) / 10 + 1;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   763
        yearEst += marchMonth0 / 10;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   764
        return (int)yearEst;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   765
    }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   766
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   767
    private static final int toCalendarDOW[] = new int[] {
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   768
        -1,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   769
        Calendar.MONDAY,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   770
        Calendar.TUESDAY,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   771
        Calendar.WEDNESDAY,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   772
        Calendar.THURSDAY,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   773
        Calendar.FRIDAY,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   774
        Calendar.SATURDAY,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   775
        Calendar.SUNDAY
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   776
    };
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   777
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   778
    private static final int toSTZTime[] = new int[] {
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   779
        SimpleTimeZone.UTC_TIME,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   780
        SimpleTimeZone.WALL_TIME,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   781
        SimpleTimeZone.STANDARD_TIME,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   782
    };
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   783
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   784
    private static final long OFFSET_MASK = 0x0fL;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   785
    private static final long DST_MASK = 0xf0L;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   786
    private static final int  DST_NSHIFT = 4;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   787
    private static final int  TRANSITION_NSHIFT = 12;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   788
    private static final int  LASTYEAR = 2037;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   789
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   790
    // from: 0 for offset lookup, 1 for dstsvings lookup
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   791
    private static int indexOf(int[] offsets, int from, int nOffsets, int offset) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   792
        offset *= 1000;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   793
        for (; from < nOffsets; from++) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   794
            if (offsets[from] == offset)
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   795
                return from;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   796
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   797
        offsets[from] = offset;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   798
        return from;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   799
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   800
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   801
    // return updated nOffsets
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   802
    private static int addTrans(long transitions[], int nTrans,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   803
                                int offsets[], int nOffsets,
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   804
                                long trans, int offset, int stdOffset) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   805
        int offsetIndex = indexOf(offsets, 0, nOffsets, offset);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   806
        if (offsetIndex == nOffsets)
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   807
            nOffsets++;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   808
        int dstIndex = 0;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   809
        if (offset != stdOffset) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   810
            dstIndex = indexOf(offsets, 1, nOffsets, offset - stdOffset);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   811
            if (dstIndex == nOffsets)
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   812
                nOffsets++;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   813
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   814
        transitions[nTrans] = ((trans * 1000) << TRANSITION_NSHIFT) |
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   815
                              ((dstIndex << DST_NSHIFT) & DST_MASK) |
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   816
                              (offsetIndex & OFFSET_MASK);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   817
        return nOffsets;
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   818
    }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   819
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   820
    // ZoneInfo checksum, copy/pasted from javazic
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   821
    private static class Checksum extends CRC32 {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   822
        public void update(int val) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   823
            byte[] b = new byte[4];
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   824
            b[0] = (byte)(val >>> 24);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   825
            b[1] = (byte)(val >>> 16);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   826
            b[2] = (byte)(val >>> 8);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   827
            b[3] = (byte)(val);
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   828
            update(b);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   829
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   830
        void update(long val) {
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   831
            byte[] b = new byte[8];
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   832
            b[0] = (byte)(val >>> 56);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   833
            b[1] = (byte)(val >>> 48);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   834
            b[2] = (byte)(val >>> 40);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   835
            b[3] = (byte)(val >>> 32);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   836
            b[4] = (byte)(val >>> 24);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   837
            b[5] = (byte)(val >>> 16);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   838
            b[6] = (byte)(val >>> 8);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   839
            b[7] = (byte)(val);
15658
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   840
            update(b);
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   841
        }
55b829ca2334 8007392: JSR 310: DateTime API Updates
sherman
parents: 11986
diff changeset
   842
    }
16852
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   843
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   844
    // A simple/raw version of j.t.ZoneOffsetTransitionRule
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   845
    private static class ZoneOffsetTransitionRule {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   846
        private final int month;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   847
        private final byte dom;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   848
        private final int dow;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   849
        private final int secondOfDay;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   850
        private final boolean timeEndOfDay;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   851
        private final int timeDefinition;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   852
        private final int standardOffset;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   853
        private final int offsetBefore;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   854
        private final int offsetAfter;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   855
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   856
        ZoneOffsetTransitionRule(DataInput in) throws IOException {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   857
            int data = in.readInt();
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   858
            int dowByte = (data & (7 << 19)) >>> 19;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   859
            int timeByte = (data & (31 << 14)) >>> 14;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   860
            int stdByte = (data & (255 << 4)) >>> 4;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   861
            int beforeByte = (data & (3 << 2)) >>> 2;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   862
            int afterByte = (data & 3);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   863
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   864
            this.month = data >>> 28;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   865
            this.dom = (byte)(((data & (63 << 22)) >>> 22) - 32);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   866
            this.dow = dowByte == 0 ? -1 : dowByte;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   867
            this.secondOfDay = timeByte == 31 ? in.readInt() : timeByte * 3600;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   868
            this.timeEndOfDay = timeByte == 24;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   869
            this.timeDefinition = (data & (3 << 12)) >>> 12;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   870
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   871
            this.standardOffset = stdByte == 255 ? in.readInt() : (stdByte - 128) * 900;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   872
            this.offsetBefore = beforeByte == 3 ? in.readInt() : standardOffset + beforeByte * 1800;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   873
            this.offsetAfter = afterByte == 3 ? in.readInt() : standardOffset + afterByte * 1800;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   874
        }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   875
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   876
        long getTransitionEpochSecond(int year) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   877
            long epochDay = 0;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   878
            if (dom < 0) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   879
                epochDay = toEpochDay(year, month, lengthOfMonth(year, month) + 1 + dom);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   880
                if (dow != -1) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   881
                    epochDay = previousOrSame(epochDay, dow);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   882
                }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   883
            } else {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   884
                epochDay = toEpochDay(year, month, dom);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   885
                if (dow != -1) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   886
                    epochDay = nextOrSame(epochDay, dow);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   887
                }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   888
            }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   889
            if (timeEndOfDay) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   890
                epochDay += 1;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   891
            }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   892
            int difference = 0;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   893
            switch (timeDefinition) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   894
                case 0:    // UTC
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   895
                    difference = 0;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   896
                    break;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   897
                case 1:    // WALL
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   898
                    difference = -offsetBefore;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   899
                    break;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   900
                case 2:    //STANDARD
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   901
                    difference = -standardOffset;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   902
                    break;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   903
            }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   904
            return epochDay * 86400 + secondOfDay + difference;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   905
        }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   906
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   907
        static final boolean isLeapYear(int year) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   908
            return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   909
        }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   910
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   911
        static final int lengthOfMonth(int year, int month) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   912
            switch (month) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   913
                case 2:        //FEBRUARY:
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   914
                    return isLeapYear(year)? 29 : 28;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   915
                case 4:        //APRIL:
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   916
                case 6:        //JUNE:
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   917
                case 9:        //SEPTEMBER:
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   918
                case 11:       //NOVEMBER:
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   919
                    return 30;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   920
                default:
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   921
                    return 31;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   922
            }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   923
        }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   924
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   925
        static final long toEpochDay(int year, int month, int day) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   926
            long y = year;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   927
            long m = month;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   928
            long total = 0;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   929
            total += 365 * y;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   930
            if (y >= 0) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   931
                total += (y + 3) / 4 - (y + 99) / 100 + (y + 399) / 400;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   932
            } else {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   933
                total -= y / -4 - y / -100 + y / -400;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   934
            }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   935
            total += ((367 * m - 362) / 12);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   936
            total += day - 1;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   937
            if (m > 2) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   938
                total--;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   939
                if (!isLeapYear(year)) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   940
                    total--;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   941
                }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   942
            }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   943
            return total - DAYS_0000_TO_1970;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   944
        }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   945
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   946
        static final long previousOrSame(long epochDay, int dayOfWeek) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   947
            return adjust(epochDay, dayOfWeek, 1);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   948
        }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   949
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   950
        static final long nextOrSame(long epochDay, int dayOfWeek) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   951
           return adjust(epochDay, dayOfWeek, 0);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   952
        }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   953
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   954
        static final long adjust(long epochDay, int dow, int relative) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   955
            int calDow = (int)Math.floorMod(epochDay + 3, 7L) + 1;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   956
            if (relative < 2 && calDow == dow) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   957
                return epochDay;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   958
            }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   959
            if ((relative & 1) == 0) {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   960
                int daysDiff = calDow - dow;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   961
                return epochDay + (daysDiff >= 0 ? 7 - daysDiff : -daysDiff);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   962
            } else {
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   963
                int daysDiff = dow - calDow;
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   964
                return epochDay - (daysDiff >= 0 ? 7 - daysDiff : -daysDiff);
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   965
            }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   966
        }
60207b2b4b42 8011172: JSR 310 DateTime API Updates II
sherman
parents: 15665
diff changeset
   967
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
}