--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/util/calendar/zi/Timezone.java Tue Feb 12 09:25:43 2013 -0800
@@ -0,0 +1,452 @@
+/*
+ * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Timezone represents all information of a single point of time to
+ * generate its time zone database.
+ *
+ * @since 1.4
+ */
+class Timezone {
+ /**
+ * zone name of this time zone
+ */
+ private String name;
+
+ /**
+ * transition time values in UTC (millisecond)
+ */
+ private List<Long> transitions;
+
+ /**
+ * All offset values in millisecond
+ * @see sun.util.calendar.ZoneInfo
+ */
+ private List<Integer> offsets;
+
+ /**
+ * Indices of GMT offset values (both raw and raw+saving)
+ * at transitions
+ */
+ private List<Integer> gmtOffsets;
+
+ /**
+ * Indices of regular or "direct" saving time values
+ * at transitions
+ */
+ private List<Integer> dstOffsets;
+
+ /**
+ * Zone records of this time zone
+ */
+ private List<ZoneRec> usedZoneRecs;
+
+ /**
+ * Rule records referred to by this time zone
+ */
+ private List<RuleRec> usedRuleRecs;
+
+ /**
+ * Type of DST rules in this time zone
+ */
+ private int dstType;
+ static final int UNDEF_DST = 0; // DST type not set yet
+ static final int NO_DST = 1; // never observed DST
+ static final int LAST_DST = 2; // last rule ends in DST (all year round DST-only)
+ static final int X_DST = 3; // used to observe DST
+ static final int DST = 4; // observing DST regularly
+
+ /**
+ * Raw GMT offset of this time zone in the last rule
+ */
+ private int rawOffset;
+
+ /**
+ * The CRC32 value of the transitions data
+ */
+ private int crc32;
+
+ /**
+ * The last ZoneRec
+ */
+ private ZoneRec lastZoneRec;
+
+ /**
+ * The last DST rules. lastRules[0] is the DST start
+ * rule. lastRules[1] is the DST end rules.
+ */
+ private List<RuleRec> lastRules;
+
+ /**
+ * The amount of DST saving value (millisecond) in the last DST
+ * rule.
+ */
+ private int lastSaving;
+
+ /**
+ * true if the raw offset will change in the future time.
+ */
+ private boolean willRawOffsetChange = false;
+
+
+ /**
+ * Constracts a Timezone object with the given zone name.
+ * @param name the zone name
+ */
+ Timezone(String name) {
+ this.name = name;
+ }
+
+ /**
+ * @return the number of transitions
+ */
+ int getNTransitions() {
+ if (transitions == null) {
+ return 0;
+ }
+ return transitions.size();
+ }
+
+ /**
+ * @return the zone name
+ */
+ String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the list of all rule records that have been referred to
+ * by this time zone.
+ * @return the rule records list
+ */
+ List<RuleRec> getRules() {
+ return usedRuleRecs;
+ }
+
+ /**
+ * Returns the list of all zone records that have been referred to
+ * by this time zone.
+ * @return the zone records list
+ */
+ List<ZoneRec> getZones() {
+ return usedZoneRecs;
+ }
+
+ /**
+ * @return the transition table (list)
+ */
+ List<Long> getTransitions() {
+ return transitions;
+ }
+
+ /**
+ * @return the offsets list
+ */
+ List<Integer> getOffsets() {
+ return offsets;
+ }
+
+ /**
+ * @return the DST saving offsets list
+ */
+ List<Integer> getDstOffsets() {
+ return dstOffsets;
+ }
+
+ /**
+ * @return the GMT offsets list
+ */
+ List<Integer> getGmtOffsets() {
+ return gmtOffsets;
+ }
+
+ /**
+ * @return the checksum (crc32) value of the trasition table
+ */
+ int getCRC32() {
+ return crc32;
+ }
+
+ /**
+ * @return true if the GMT offset of this time zone would change
+ * after the time zone database has been generated, false, otherwise.
+ */
+ boolean willGMTOffsetChange() {
+ return willRawOffsetChange;
+ }
+
+ /**
+ * @return the last known GMT offset value in milliseconds
+ */
+ int getRawOffset() {
+ return rawOffset;
+ }
+
+ /**
+ * Sets time zone's GMT offset to <code>offset</code>.
+ * @param offset the GMT offset value in milliseconds
+ */
+ void setRawOffset(int offset) {
+ rawOffset = offset;
+ }
+
+ /**
+ * Sets time zone's GMT offset value to <code>offset</code>. If
+ * <code>startTime</code> is future time, then the {@link
+ * #willRawOffsetChange} value is set to true.
+ * @param offset the GMT offset value in milliseconds
+ * @param startTime the UTC time at which the GMT offset is in effective
+ */
+ void setRawOffset(int offset, long startTime) {
+ // if this rawOffset is for the future time, let the run-time
+ // look for the current GMT offset.
+ if (startTime > Time.getCurrentTime()) {
+ willRawOffsetChange = true;
+ }
+ setRawOffset(offset);
+ }
+
+ /**
+ * Adds the specified transition information to the end of the transition table.
+ * @param time the UTC time at which this transition happens
+ * @param offset the total amount of the offset from GMT in milliseconds
+ * @param dstOffset the amount of time in milliseconds saved at this transition
+ */
+ void addTransition(long time, int offset, int dstOffset) {
+ if (transitions == null) {
+ transitions = new ArrayList<Long>();
+ offsets = new ArrayList<Integer>();
+ dstOffsets = new ArrayList<Integer>();
+ }
+ transitions.add(time);
+ offsets.add(offset);
+ dstOffsets.add(dstOffset);
+ }
+
+ /**
+ * Sets the type of historical daylight saving time
+ * observation. For example, China used to observed daylight
+ * saving time, but it no longer does. Then, X_DST is set to the
+ * China time zone.
+ * @param type the type of daylight saving time
+ */
+ void setDSTType(int type) {
+ dstType = type;
+ }
+
+ /**
+ * @return the type of historical daylight saving time
+ * observation.
+ */
+ int getDSTType() {
+ return dstType;
+ }
+
+ /**
+ * Adds the specified zone record to the zone records list.
+ * @param rec the zone record
+ */
+ void addUsedRec(ZoneRec rec) {
+ if (usedZoneRecs == null) {
+ usedZoneRecs = new ArrayList<ZoneRec>();
+ }
+ usedZoneRecs.add(rec);
+ }
+
+ /**
+ * Adds the specified rule record to the rule records list.
+ * @param rec the rule record
+ */
+ void addUsedRec(RuleRec rec) {
+ if (usedRuleRecs == null) {
+ usedRuleRecs = new ArrayList<RuleRec>();
+ }
+ // if the last used rec is the same as the given rec, avoid
+ // putting the same rule.
+ int n = usedRuleRecs.size();
+ for (int i = 0; i < n; i++) {
+ if (usedRuleRecs.get(i).equals(rec)) {
+ return;
+ }
+ }
+ usedRuleRecs.add(rec);
+ }
+
+ /**
+ * Sets the last zone record for this time zone.
+ * @param the last zone record
+ */
+ void setLastZoneRec(ZoneRec zrec) {
+ lastZoneRec = zrec;
+ }
+
+ /**
+ * @return the last zone record for this time zone.
+ */
+ ZoneRec getLastZoneRec() {
+ return lastZoneRec;
+ }
+
+ /**
+ * Sets the last rule records for this time zone. Those are used
+ * for generating SimpleTimeZone parameters.
+ * @param rules the last rule records
+ */
+ void setLastRules(List<RuleRec> rules) {
+ int n = rules.size();
+ if (n > 0) {
+ lastRules = rules;
+ RuleRec rec = rules.get(0);
+ int offset = rec.getSave();
+ if (offset > 0) {
+ setLastDSTSaving(offset);
+ } else {
+ System.err.println("\t No DST starting rule in the last rules.");
+ }
+ }
+ }
+
+ /**
+ * @return the last rule records for this time zone.
+ */
+ List<RuleRec> getLastRules() {
+ return lastRules;
+ }
+
+ /**
+ * Sets the last daylight saving amount.
+ * @param the daylight saving amount
+ */
+ void setLastDSTSaving(int offset) {
+ lastSaving = offset;
+ }
+
+ /**
+ * @return the last daylight saving amount.
+ */
+ int getLastDSTSaving() {
+ return lastSaving;
+ }
+
+ /**
+ * Calculates the CRC32 value from the transition table and sets
+ * the value to <code>crc32</code>.
+ */
+ void checksum() {
+ if (transitions == null) {
+ crc32 = 0;
+ return;
+ }
+ Checksum sum = new Checksum();
+ for (int i = 0; i < transitions.size(); i++) {
+ int offset = offsets.get(i);
+ // adjust back to make the transition in local time
+ sum.update(transitions.get(i) + offset);
+ sum.update(offset);
+ sum.update(dstOffsets.get(i));
+ }
+ crc32 = (int)sum.getValue();
+ }
+
+ /**
+ * Removes unnecessary transitions for Java time zone support.
+ */
+ void optimize() {
+ // if there is only one offset, delete all transitions. This
+ // could happen if only time zone abbreviations changed.
+ if (gmtOffsets.size() == 1) {
+ transitions = null;
+ usedRuleRecs = null;
+ setDSTType(NO_DST);
+ return;
+ }
+ for (int i = 0; i < (transitions.size() - 2); i++) { // don't remove the last one
+ if (transitions.get(i) == transitions.get(i+1)) {
+ transitions.remove(i);
+ offsets.remove(i);
+ dstOffsets.remove(i);
+ i--;
+ }
+ }
+
+ for (int i = 0; i < (transitions.size() - 2); i++) { // don't remove the last one
+ if (offsets.get(i) == offsets.get(i+1)
+ && dstOffsets.get(i) == dstOffsets.get(i+1)) {
+ transitions.remove(i+1);
+ offsets.remove(i+1);
+ dstOffsets.remove(i+1);
+ i--;
+ }
+ }
+ }
+
+ /**
+ * Stores the specified offset value from GMT in the GMT offsets
+ * table and returns its index. The offset value includes the base
+ * GMT offset and any additional daylight saving if applicable. If
+ * the same value as the specified offset is already in the table,
+ * its index is returned.
+ * @param offset the offset value in milliseconds
+ * @return the index to the offset value in the GMT offsets table.
+ */
+ int getOffsetIndex(int offset) {
+ return getOffsetIndex(offset, 0);
+ }
+
+ /**
+ * Stores the specified daylight saving value in the GMT offsets
+ * table and returns its index. If the same value as the specified
+ * offset is already in the table, its index is returned. If 0 is
+ * specified, it's not stored in the table and -1 is returned.
+ * @param offset the offset value in milliseconds
+ * @return the index to the specified offset value in the GMT
+ * offsets table, or -1 if 0 is specified.
+ */
+ int getDstOffsetIndex(int offset) {
+ if (offset == 0) {
+ return -1;
+ }
+ return getOffsetIndex(offset, 1);
+ }
+
+ private int getOffsetIndex(int offset, int index) {
+ if (gmtOffsets == null) {
+ gmtOffsets = new ArrayList<Integer>();
+ }
+ for (int i = index; i < gmtOffsets.size(); i++) {
+ if (offset == gmtOffsets.get(i)) {
+ return i;
+ }
+ }
+ if (gmtOffsets.size() < index) {
+ gmtOffsets.add(0);
+ }
+ gmtOffsets.add(offset);
+ return gmtOffsets.size() - 1;
+ }
+}