Path: blob/master/test/jdk/sun/util/calendar/zi/Timezone.java
41153 views
/*1* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.util.ArrayList;24import java.util.List;2526/**27* Timezone represents all information of a single point of time to28* generate its time zone database.29*30* @since 1.431*/32class Timezone {33/**34* zone name of this time zone35*/36private String name;3738/**39* transition time values in UTC (millisecond)40*/41private List<Long> transitions;4243/**44* All offset values in millisecond45* @see sun.util.calendar.ZoneInfo46*/47private List<Integer> offsets;4849/**50* Indices of GMT offset values (both raw and raw+saving)51* at transitions52*/53private List<Integer> gmtOffsets;5455/**56* Indices of regular or "direct" saving time values57* at transitions58*/59private List<Integer> dstOffsets;6061/**62* Zone records of this time zone63*/64private List<ZoneRec> usedZoneRecs;6566/**67* Rule records referred to by this time zone68*/69private List<RuleRec> usedRuleRecs;7071/**72* Type of DST rules in this time zone73*/74private int dstType;75static final int UNDEF_DST = 0; // DST type not set yet76static final int NO_DST = 1; // never observed DST77static final int LAST_DST = 2; // last rule ends in DST (all year round DST-only)78static final int X_DST = 3; // used to observe DST79static final int DST = 4; // observing DST regularly8081/**82* Raw GMT offset of this time zone in the last rule83*/84private int rawOffset;8586/**87* The CRC32 value of the transitions data88*/89private int crc32;9091/**92* The last ZoneRec93*/94private ZoneRec lastZoneRec;9596/**97* The last DST rules. lastRules[0] is the DST start98* rule. lastRules[1] is the DST end rules.99*/100private List<RuleRec> lastRules;101102/**103* The amount of DST saving value (millisecond) in the last DST104* rule.105*/106private int lastSaving;107108/**109* true if the raw offset will change in the future time.110*/111private boolean willRawOffsetChange = false;112113114/**115* Constracts a Timezone object with the given zone name.116* @param name the zone name117*/118Timezone(String name) {119this.name = name;120}121122/**123* @return the number of transitions124*/125int getNTransitions() {126if (transitions == null) {127return 0;128}129return transitions.size();130}131132/**133* @return the zone name134*/135String getName() {136return name;137}138139/**140* Returns the list of all rule records that have been referred to141* by this time zone.142* @return the rule records list143*/144List<RuleRec> getRules() {145return usedRuleRecs;146}147148/**149* Returns the list of all zone records that have been referred to150* by this time zone.151* @return the zone records list152*/153List<ZoneRec> getZones() {154return usedZoneRecs;155}156157/**158* @return the transition table (list)159*/160List<Long> getTransitions() {161return transitions;162}163164/**165* @return the offsets list166*/167List<Integer> getOffsets() {168return offsets;169}170171/**172* @return the DST saving offsets list173*/174List<Integer> getDstOffsets() {175return dstOffsets;176}177178/**179* @return the GMT offsets list180*/181List<Integer> getGmtOffsets() {182return gmtOffsets;183}184185/**186* @return the checksum (crc32) value of the trasition table187*/188int getCRC32() {189return crc32;190}191192/**193* @return true if the GMT offset of this time zone would change194* after the time zone database has been generated, false, otherwise.195*/196boolean willGMTOffsetChange() {197return willRawOffsetChange;198}199200/**201* @return the last known GMT offset value in milliseconds202*/203int getRawOffset() {204return rawOffset;205}206207/**208* Sets time zone's GMT offset to <code>offset</code>.209* @param offset the GMT offset value in milliseconds210*/211void setRawOffset(int offset) {212rawOffset = offset;213}214215/**216* Sets time zone's GMT offset value to <code>offset</code>. If217* <code>startTime</code> is future time, then the {@link218* #willRawOffsetChange} value is set to true.219* @param offset the GMT offset value in milliseconds220* @param startTime the UTC time at which the GMT offset is in effective221*/222void setRawOffset(int offset, long startTime) {223// if this rawOffset is for the future time, let the run-time224// look for the current GMT offset.225if (startTime > Time.getCurrentTime()) {226willRawOffsetChange = true;227}228setRawOffset(offset);229}230231/**232* Adds the specified transition information to the end of the transition table.233* @param time the UTC time at which this transition happens234* @param offset the total amount of the offset from GMT in milliseconds235* @param dstOffset the amount of time in milliseconds saved at this transition236*/237void addTransition(long time, int offset, int dstOffset) {238if (transitions == null) {239transitions = new ArrayList<Long>();240offsets = new ArrayList<Integer>();241dstOffsets = new ArrayList<Integer>();242}243transitions.add(time);244offsets.add(offset);245dstOffsets.add(dstOffset);246}247248/**249* Sets the type of historical daylight saving time250* observation. For example, China used to observed daylight251* saving time, but it no longer does. Then, X_DST is set to the252* China time zone.253* @param type the type of daylight saving time254*/255void setDSTType(int type) {256dstType = type;257}258259/**260* @return the type of historical daylight saving time261* observation.262*/263int getDSTType() {264return dstType;265}266267/**268* Adds the specified zone record to the zone records list.269* @param rec the zone record270*/271void addUsedRec(ZoneRec rec) {272if (usedZoneRecs == null) {273usedZoneRecs = new ArrayList<ZoneRec>();274}275usedZoneRecs.add(rec);276}277278/**279* Adds the specified rule record to the rule records list.280* @param rec the rule record281*/282void addUsedRec(RuleRec rec) {283if (usedRuleRecs == null) {284usedRuleRecs = new ArrayList<RuleRec>();285}286// if the last used rec is the same as the given rec, avoid287// putting the same rule.288int n = usedRuleRecs.size();289for (int i = 0; i < n; i++) {290if (usedRuleRecs.get(i).equals(rec)) {291return;292}293}294usedRuleRecs.add(rec);295}296297/**298* Sets the last zone record for this time zone.299* @param the last zone record300*/301void setLastZoneRec(ZoneRec zrec) {302lastZoneRec = zrec;303}304305/**306* @return the last zone record for this time zone.307*/308ZoneRec getLastZoneRec() {309return lastZoneRec;310}311312/**313* Sets the last rule records for this time zone. Those are used314* for generating SimpleTimeZone parameters.315* @param rules the last rule records316*/317void setLastRules(List<RuleRec> rules) {318int n = rules.size();319if (n > 0) {320lastRules = rules;321RuleRec rec = rules.get(0);322int offset = rec.getSave();323if (offset > 0) {324setLastDSTSaving(offset);325} else {326System.err.println("\t No DST starting rule in the last rules.");327}328}329}330331/**332* @return the last rule records for this time zone.333*/334List<RuleRec> getLastRules() {335return lastRules;336}337338/**339* Sets the last daylight saving amount.340* @param the daylight saving amount341*/342void setLastDSTSaving(int offset) {343lastSaving = offset;344}345346/**347* @return the last daylight saving amount.348*/349int getLastDSTSaving() {350return lastSaving;351}352353/**354* Calculates the CRC32 value from the transition table and sets355* the value to <code>crc32</code>.356*/357void checksum() {358if (transitions == null) {359crc32 = 0;360return;361}362Checksum sum = new Checksum();363for (int i = 0; i < transitions.size(); i++) {364int offset = offsets.get(i);365// adjust back to make the transition in local time366sum.update(transitions.get(i) + offset);367sum.update(offset);368sum.update(dstOffsets.get(i));369}370crc32 = (int)sum.getValue();371}372373/**374* Removes unnecessary transitions for Java time zone support.375*/376void optimize() {377// if there is only one offset, delete all transitions. This378// could happen if only time zone abbreviations changed.379if (gmtOffsets.size() == 1) {380transitions = null;381usedRuleRecs = null;382setDSTType(NO_DST);383return;384}385for (int i = 0; i < (transitions.size() - 2); i++) { // don't remove the last one386if (transitions.get(i) == transitions.get(i+1)) {387transitions.remove(i);388offsets.remove(i);389dstOffsets.remove(i);390i--;391}392}393394for (int i = 0; i < (transitions.size() - 2); i++) { // don't remove the last one395if (offsets.get(i) == offsets.get(i+1)396&& dstOffsets.get(i) == dstOffsets.get(i+1)) {397transitions.remove(i+1);398offsets.remove(i+1);399dstOffsets.remove(i+1);400i--;401}402}403}404405/**406* Stores the specified offset value from GMT in the GMT offsets407* table and returns its index. The offset value includes the base408* GMT offset and any additional daylight saving if applicable. If409* the same value as the specified offset is already in the table,410* its index is returned.411* @param offset the offset value in milliseconds412* @return the index to the offset value in the GMT offsets table.413*/414int getOffsetIndex(int offset) {415return getOffsetIndex(offset, 0);416}417418/**419* Stores the specified daylight saving value in the GMT offsets420* table and returns its index. If the same value as the specified421* offset is already in the table, its index is returned. If 0 is422* specified, it's not stored in the table and -1 is returned.423* @param offset the offset value in milliseconds424* @return the index to the specified offset value in the GMT425* offsets table, or -1 if 0 is specified.426*/427int getDstOffsetIndex(int offset) {428if (offset == 0) {429return -1;430}431return getOffsetIndex(offset, 1);432}433434private int getOffsetIndex(int offset, int index) {435if (gmtOffsets == null) {436gmtOffsets = new ArrayList<Integer>();437}438for (int i = index; i < gmtOffsets.size(); i++) {439if (offset == gmtOffsets.get(i)) {440return i;441}442}443if (gmtOffsets.size() < index) {444gmtOffsets.add(0);445}446gmtOffsets.add(offset);447return gmtOffsets.size() - 1;448}449}450451452