8007392: JSR 310: DateTime API Updates
8007520: Update date/time classes in j.util and j.sql packages
8007572: Replace existing jdk timezone data at <java.home>/lib/zi with JSR310's tzdb
Summary: Integration of JSR310 Date/Time API for M7
Reviewed-by: darcy, alanb, naoto
Contributed-by: scolebourne@joda.org, roger.riggs@oracle.com, masayoshi.okutsu@oracle.com, patrick.zhang@oracle.com
/*
* 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.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);
}
}