35a94b7697
Reviewed-by: jlu, coffeys
230 lines
6.9 KiB
Java
230 lines
6.9 KiB
Java
/*
|
|
* Copyright (c) 2000, 2024, 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.
|
|
*
|
|
* 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.StringTokenizer;
|
|
|
|
/**
|
|
* RuleRec class represents one record of the Rule set.
|
|
*
|
|
* @since 1.4
|
|
*/
|
|
class RuleRec {
|
|
private int fromYear;
|
|
private int toYear;
|
|
private String type;
|
|
private Month inMonth;
|
|
private RuleDay onDay;
|
|
private Time atTime;
|
|
private int save;
|
|
private String letters;
|
|
private String line;
|
|
private boolean isLastRule;
|
|
|
|
int getFromYear() {
|
|
return fromYear;
|
|
}
|
|
|
|
int getToYear() {
|
|
return toYear;
|
|
}
|
|
|
|
Month getMonth() {
|
|
return inMonth;
|
|
}
|
|
|
|
int getMonthNum() {
|
|
return inMonth.value();
|
|
}
|
|
|
|
RuleDay getDay() {
|
|
return onDay;
|
|
}
|
|
|
|
Time getTime() {
|
|
return atTime;
|
|
}
|
|
|
|
int getSave() {
|
|
return save;
|
|
}
|
|
|
|
String getLine() {
|
|
return line;
|
|
}
|
|
|
|
/**
|
|
* Sets the line from the text file.
|
|
* @param line the text of the line
|
|
*/
|
|
void setLine(String line) {
|
|
this.line = line;
|
|
}
|
|
|
|
/**
|
|
* @return true if the rule type is "odd".
|
|
*/
|
|
boolean isOdd() {
|
|
return "odd".equals(type);
|
|
}
|
|
|
|
/**
|
|
* @return true if the rule type is "even".
|
|
*/
|
|
boolean isEven() {
|
|
return "even".equals(type);
|
|
}
|
|
|
|
/**
|
|
* Determines if this rule record is the last DST schedule rule.
|
|
*
|
|
* @return true if this rule record has "max" as TO (year).
|
|
*/
|
|
boolean isLastRule() {
|
|
return isLastRule;
|
|
}
|
|
|
|
/**
|
|
* Determines if the unadjusted until time of the specified ZoneRec
|
|
* is the same as the transition time of this rule in the same
|
|
* year as the ZoneRec until year.
|
|
*
|
|
* @param zrec ZoneRec to compare to
|
|
* @param save the amount of daylight saving in milliseconds
|
|
* @param gmtOffset the GMT offset value in milliseconds
|
|
* @return true if the unadjusted until time is the same as rule's
|
|
* transition time.
|
|
*/
|
|
boolean isSameTransition(ZoneRec zrec, int save, int gmtOffset) {
|
|
long until, transition;
|
|
|
|
if (zrec.getUntilTime().getType() != atTime.getType()) {
|
|
until = zrec.getLocalUntilTime(save, gmtOffset);
|
|
transition = Time.getLocalTime(zrec.getUntilYear(),
|
|
getMonth(),
|
|
getDay(),
|
|
save,
|
|
gmtOffset,
|
|
atTime);
|
|
} else {
|
|
until = zrec.getLocalUntilTime();
|
|
transition = Time.getLocalTime(zrec.getUntilYear(),
|
|
getMonth(),
|
|
getDay(),
|
|
atTime.getTime());
|
|
}
|
|
|
|
return until == transition;
|
|
}
|
|
|
|
/**
|
|
* Parses a Rule line and returns a RuleRec object.
|
|
*
|
|
* @param tokens a StringTokenizer object that should contain a
|
|
* token for the "FROM" field and the rest.
|
|
* @return a RuleRec object.
|
|
*/
|
|
static RuleRec parse(StringTokenizer tokens) {
|
|
RuleRec rec = new RuleRec();
|
|
try {
|
|
// FROM
|
|
String token = tokens.nextToken();
|
|
try {
|
|
rec.fromYear = Integer.parseInt(token);
|
|
} catch (NumberFormatException e) {
|
|
// it's not integer
|
|
if ("min".equals(token) || "minimum".equals(token)) {
|
|
rec.fromYear = Zoneinfo.getMinYear();
|
|
} else if ("max".equals(token) || "maximum".equals(token)) {
|
|
rec.fromYear = Zoneinfo.getMaxYear();
|
|
} else {
|
|
Main.panic("invalid year value: "+token);
|
|
}
|
|
}
|
|
|
|
// TO
|
|
token = tokens.nextToken();
|
|
rec.isLastRule = false;
|
|
try {
|
|
rec.toYear = Integer.parseInt(token);
|
|
} catch (NumberFormatException e) {
|
|
// it's not integer
|
|
int len = token.length();
|
|
if (token.regionMatches(true, 0, "minimum", 0, len)) {
|
|
rec.fromYear = Zoneinfo.getMinYear();
|
|
} else if (token.regionMatches(true, 0, "maximum", 0, len)) {
|
|
rec.toYear = Integer.MAX_VALUE;
|
|
rec.isLastRule = true;
|
|
} else if (token.regionMatches(true, 0, "only", 0, len)) {
|
|
rec.toYear = rec.fromYear;
|
|
} else {
|
|
Main.panic("invalid year value: "+token);
|
|
}
|
|
}
|
|
|
|
// TYPE
|
|
rec.type = tokens.nextToken();
|
|
|
|
// IN
|
|
rec.inMonth = Month.parse(tokens.nextToken());
|
|
|
|
// ON
|
|
rec.onDay = RuleDay.parse(tokens.nextToken());
|
|
|
|
// AT
|
|
rec.atTime = Time.parse(tokens.nextToken());
|
|
|
|
// SAVE
|
|
rec.save = (int) Time.parse(tokens.nextToken()).getTime();
|
|
|
|
// LETTER/S
|
|
rec.letters = tokens.nextToken();
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
return rec;
|
|
}
|
|
|
|
/**
|
|
* Calculates the transition time of the given year under this rule.
|
|
* @param year the year value
|
|
* @param gmtOffset the GMT offset value in milliseconds
|
|
* @param save the amount of daylight save time
|
|
* @return the transition time in milliseconds of the given year in UTC.
|
|
*/
|
|
long getTransitionTime(int year, int gmtOffset, int save) {
|
|
long time = Time.getLocalTime(year, getMonth(),
|
|
getDay(), atTime.getTime());
|
|
if (atTime.isSTD()) {
|
|
time -= gmtOffset;
|
|
} else if (atTime.isWall()) {
|
|
time -= gmtOffset + save;
|
|
}
|
|
return time;
|
|
}
|
|
|
|
private static int getInt(StringTokenizer tokens) {
|
|
String token = tokens.nextToken();
|
|
return Integer.parseInt(token);
|
|
}
|
|
}
|