| /* |
| * Copyright (c) 2000, 2013, 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.io.BufferedReader; |
| import java.io.FileReader; |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.StringTokenizer; |
| |
| /** |
| * ZoneRec hold information of time zone corresponding to each text |
| * line of the "Zone" part. |
| * |
| * @since 1.4 |
| */ |
| class ZoneRec { |
| private int gmtOffset; |
| private String ruleName; |
| private int directSave; |
| private Rule ruleRef; |
| private String format; |
| private boolean hasUntil; |
| private int untilYear; |
| private Month untilMonth; |
| private RuleDay untilDay; |
| private Time untilTime; |
| private long untilInMillis; |
| private String line; |
| |
| /** |
| * @return the "UNTIL" value in milliseconds |
| */ |
| Time getUntilTime() { |
| return untilTime; |
| } |
| |
| /** |
| * @return the GMT offset value in milliseconds |
| */ |
| int getGmtOffset() { |
| return gmtOffset; |
| } |
| |
| /** |
| * @return the rule name to which this zone record refers |
| */ |
| String getRuleName() { |
| return ruleName; |
| } |
| |
| /** |
| * @return the amount of saving time directly defined in the |
| * "RULES/SAVE" field. |
| */ |
| int getDirectSave() { |
| return directSave; |
| } |
| |
| /** |
| * @return true if this zone record has a reference to a rule |
| */ |
| boolean hasRuleReference() { |
| return ruleRef != null; |
| } |
| |
| /** |
| * Returns the "FORMAT" field string of this zone record. This |
| * @return the "FORMAT" field |
| */ |
| String getFormat() { |
| return format; |
| } |
| |
| /** |
| * @return the year in the "UNTIL" field |
| */ |
| int getUntilYear() { |
| return untilYear; |
| } |
| |
| /** |
| * Returns the "UNTIL" field value in milliseconds from Janurary |
| * 1, 1970 0:00 GMT. |
| * @param currentSave the amount of daylight saving in |
| * milliseconds that is used to adjust wall-clock time. |
| * @return the milliseconds value of the "UNTIL" field |
| */ |
| long getUntilTime(int currentSave) { |
| if (untilTime.isWall()) { |
| return untilInMillis - currentSave; |
| } |
| return untilInMillis; |
| } |
| |
| /** |
| * Returns the "UNTIL" time in milliseconds without adjusting GMT |
| * offsets or daylight saving. |
| * @return local "UNTIL" time in milliseconds |
| */ |
| long getLocalUntilTime() { |
| return Time.getLocalTime(untilYear, |
| untilMonth, |
| untilDay, |
| untilTime.getTime()); |
| } |
| |
| /** |
| * Returns the "UNTIL" time in milliseconds with adjusting GMT offsets and daylight saving. |
| * @return the "UNTIL" time after the adjustment |
| */ |
| long getLocalUntilTime(int save, int gmtOffset) { |
| return Time.getLocalTime(untilYear, |
| untilMonth, |
| untilDay, |
| save, |
| gmtOffset, |
| untilTime); |
| } |
| |
| /** |
| * @return the text line of this zone record |
| */ |
| String getLine() { |
| return line; |
| } |
| |
| /** |
| * Sets the specified text line to this zone record |
| */ |
| void setLine(String line) { |
| this.line = line; |
| } |
| |
| /** |
| * @return true if this zone record has the "UNTIL" field |
| */ |
| boolean hasUntil() { |
| return this.hasUntil; |
| } |
| |
| /** |
| * Adjusts the "UNTIL" time to GMT offset if this zone record has |
| * it. <code>untilTime</code> is not adjusted to daylight saving |
| * in this method. |
| */ |
| void adjustTime() { |
| if (!hasUntil()) { |
| return; |
| } |
| if (untilTime.isSTD() || untilTime.isWall()) { |
| // adjust to gmt offset only here. adjust to real |
| // wall-clock time when tracking rules |
| untilInMillis -= gmtOffset; |
| } |
| } |
| |
| /** |
| * @return the reference to the Rule object |
| */ |
| Rule getRuleRef() { |
| return ruleRef; |
| } |
| |
| /** |
| * Resolves the reference to a Rule and adjusts its "UNTIL" time |
| * to GMT offset. |
| */ |
| void resolve(Zoneinfo zi) { |
| if (ruleName != null && (!"-".equals(ruleName))) { |
| ruleRef = zi.getRule(ruleName); |
| } |
| adjustTime(); |
| } |
| |
| /** |
| * Parses a Zone text line that is described by a StringTokenizer. |
| * @param tokens represents tokens of a Zone text line |
| * @return the zone record produced by parsing the text |
| */ |
| static ZoneRec parse(StringTokenizer tokens) { |
| ZoneRec rec = new ZoneRec(); |
| try { |
| rec.gmtOffset = (int) Time.parse(tokens.nextToken()).getTime(); |
| String token = tokens.nextToken(); |
| char c = token.charAt(0); |
| if (c >= '0' && c <= '9') { |
| rec.directSave = (int) Time.parse(token).getTime(); |
| } else { |
| rec.ruleName = token; |
| } |
| rec.format = tokens.nextToken(); |
| if (tokens.hasMoreTokens()) { |
| rec.hasUntil = true; |
| rec.untilYear = Integer.parseInt(tokens.nextToken()); |
| if (tokens.hasMoreTokens()) { |
| rec.untilMonth = Month.parse(tokens.nextToken()); |
| } else { |
| rec.untilMonth = Month.JANUARY; |
| } |
| if (tokens.hasMoreTokens()) { |
| rec.untilDay = RuleDay.parse(tokens.nextToken()); |
| } else { |
| rec.untilDay = new RuleDay(1); |
| } |
| if (tokens.hasMoreTokens()) { |
| rec.untilTime = Time.parse(tokens.nextToken()); |
| } else { |
| rec.untilTime = Time.parse("0:00"); |
| } |
| rec.untilInMillis = rec.getLocalUntilTime(); |
| } |
| } catch (Exception e) { |
| // TODO: error reporting |
| e.printStackTrace(); |
| } |
| return rec; |
| } |
| |
| private static void panic(String msg) { |
| Main.panic(msg); |
| } |
| } |