/** *ConstractsaZoneinfo.
*/
Zoneinfo() {
zones = new HashMap<String,Zone>();
rules = new HashMap<String,Rule>();
aliases = new HashMap<String,String>();
}
/** *ParsesthespecifiedtimezonedatafileandcreatesaZoneinfo *thathasallRules,ZonesandLinks(aliases)information. *@paramfnamethetimezonedatafilename *@returnaZoneinfoobject
*/ static Zoneinfo parse(String fname) {
BufferedReader in = null; try {
FileReader fr = new FileReader(fname);
in = new BufferedReader(fr);
} catch (FileNotFoundException e) {
panic("can't open file: "+fname);
}
Zoneinfo zi = new Zoneinfo(); boolean continued = false;
Zone zone = null;
String l;
lineNum = 0;
try { while ((line = in.readLine()) != null) {
lineNum++; // skip blank and comment lines if (line.length() == 0 || line.charAt(0) == '#') { continue;
}
// trim trailing comments int rindex = line.lastIndexOf('#'); if (rindex != -1) { // take the data part of the line
l = line.substring(0, rindex);
} else {
l = line;
}
StringTokenizer tokens = new StringTokenizer(l); if (!tokens.hasMoreTokens()) { continue;
}
String token = tokens.nextToken();
if (continued || "Zone".equals(token)) { if (zone == null) { if (!tokens.hasMoreTokens()) {
panic("syntax error: zone no more token");
}
token = tokens.nextToken(); // if the zone name is in "GMT+hh" or "GMT-hh" // format, ignore it due to spec conflict. if (token.startsWith("GMT+") || token.startsWith("GMT-")) { continue;
}
zone = new Zone(token);
} else { // no way to push the current token back...
tokens = new StringTokenizer(l);
}
ZoneRec zrec = ZoneRec.parse(tokens);
zrec.setLine(line);
zone.add(zrec); if ((continued = zrec.hasUntil()) == false) { if (Zone.isTargetZone(zone.getName())) { // zone.resolve(zi);
zi.add(zone);
}
zone = null;
}
} elseif ("Rule".equals(token)) { if (!tokens.hasMoreTokens()) {
panic("syntax error: rule no more token");
}
token = tokens.nextToken();
Rule rule = zi.getRule(token); if (rule == null) {
rule = new Rule(token);
zi.add(rule);
}
RuleRec rrec = RuleRec.parse(tokens);
rrec.setLine(line);
rule.add(rrec);
} elseif ("Link".equals(token)) { // Link <newname> <oldname> try {
String name1 = tokens.nextToken();
String name2 = tokens.nextToken();
// if the zone name is in "GMT+hh" or "GMT-hh" // format, ignore it due to spec conflict with // custom time zones. Also, ignore "ROC" for // PC-ness. if (name2.startsWith("GMT+") || name2.startsWith("GMT-")
|| "ROC".equals(name2)) { continue;
}
zi.putAlias(name2, name1);
} catch (Exception e) {
panic("syntax error: no more token for Link");
}
}
}
in.close();
} catch (IOException ex) {
panic("IO error: " + ex.getMessage());
}
return zi;
}
/** *InterpretsazoneandconstructsaTimezoneobjectthat *containsenoughinformationonGMToffsetsandDSTschedulesto *generateazoneinfodatabase. * *@paramzoneNamethezonenameforwhichaTimezoneobjectis *constructed. * *@returnaTimezoneobjectthatcontainsallGMToffsetsandDST *rulesinformation.
*/
Timezone phase2(String zoneName) {
Timezone tz = new Timezone(zoneName);
Zone zone = getZone(zoneName);
zone.resolve(this);
// TODO: merge phase2's for the regular and SimpleTimeZone ones. if (isYearForTimeZoneDataSpecified) {
ZoneRec zrec = zone.get(zone.size()-1);
tz.setLastZoneRec(zrec);
tz.setRawOffset(zrec.getGmtOffset()); if (zrec.hasRuleReference()) { /* *Thispartassumesthatthespecifiedyeariscoveredby *therulesreferredtobythelastzonerecord.
*/
List<RuleRec> rrecs = zrec.getRuleRef().getRules(startYear);
if (rrecs.size() == 2) { // make sure that one is a start rule and the other is // an end rule.
RuleRec r0 = rrecs.get(0);
RuleRec r1 = rrecs.get(1); if (r0.getSave() == 0 && r1.getSave() > 0) {
rrecs.set(0, r1);
rrecs.set(1, r0);
} elseif (!(r0.getSave() > 0 && r1.getSave() == 0)) {
rrecs = null;
Main.error(zoneName + ": rules for " + startYear + " not found.");
}
} else {
rrecs = null;
} if (rrecs != null) {
tz.setLastRules(rrecs);
}
} return tz;
}
int gmtOffset; int year = minYear; int fromYear = year; long fromTime = Time.getLocalTime(startYear,
Month.JANUARY, 1, 0);
// take the index 0 for the GMT offset of the last zone record
ZoneRec zrec = zone.get(zone.size()-1);
tz.getOffsetIndex(zrec.getGmtOffset());
int lastGmtOffsetValue = -1;
ZoneRec prevzrec = null; int currentSave = 0; boolean usedZone; for (int zindex = 0; zindex < zone.size(); zindex++) {
zrec = zone.get(zindex);
usedZone = false;
gmtOffset = zrec.getGmtOffset(); int stdOffset = zrec.getDirectSave();
if (gmtOffset != lastGmtOffsetValue) {
tz.setRawOffset(gmtOffset, fromTime);
lastGmtOffsetValue = gmtOffset;
} // If this is the last zone record, take the last rule info. if (!zrec.hasUntil()) { if (zrec.hasRuleReference()) {
tz.setLastRules(zrec.getRuleRef().getLastRules());
} elseif (stdOffset != 0) { // in case the last rule is all year round DST-only // (Asia/Amman once announced this rule.)
tz.setLastDSTSaving(stdOffset);
}
} if (!zrec.hasRuleReference()) { if (!zrec.hasUntil() || zrec.getUntilTime(stdOffset) >= fromTime) {
tz.addTransition(fromTime,
tz.getOffsetIndex(gmtOffset+stdOffset),
tz.getDstOffsetIndex(stdOffset));
usedZone = true;
}
currentSave = stdOffset; // optimization in case the last rule is fixed. if (!zrec.hasUntil()) { if (tz.getNTransitions() > 0) { if (stdOffset == 0) {
tz.setDSTType(Timezone.X_DST);
} else {
tz.setDSTType(Timezone.LAST_DST);
} long time = Time.getLocalTime(maxYear,
Month.JANUARY, 1, 0);
time -= zrec.getGmtOffset();
tz.addTransition(time,
tz.getOffsetIndex(gmtOffset+stdOffset),
tz.getDstOffsetIndex(stdOffset));
tz.addUsedRec(zrec);
} else {
tz.setDSTType(Timezone.NO_DST);
} break;
}
} else {
Rule rule = zrec.getRuleRef(); boolean fromTimeUsed = false;
currentSave = 0;
year_loop: for (year = getMinYear(); year <= endYear; year++) { if (zrec.hasUntil() && year > zrec.getUntilYear()) { break;
}
List<RuleRec> rules = rule.getRules(year); if (rules.size() > 0) { for (int i = 0; i < rules.size(); i++) {
RuleRec rrec = rules.get(i); long transition = rrec.getTransitionTime(year,
gmtOffset,
currentSave); if (zrec.hasUntil()) { if (transition >= zrec.getUntilTime(currentSave)) { // If the GMT offset changed from the previous one, // record fromTime as a transition. if (!fromTimeUsed && prevzrec != null
&& gmtOffset != prevzrec.getGmtOffset()) {
tz.addTransition(fromTime,
tz.getOffsetIndex(gmtOffset+currentSave),
tz.getDstOffsetIndex(currentSave));
fromTimeUsed = true; // for consistency
} break year_loop;
}
}
if (fromTimeUsed == false) { if (fromTime <= transition) {
fromTimeUsed = true;
if (fromTime != minTime) { int prevsave;
// See if until time in the previous // ZoneRec is the same thing as the // local time in the next rule. // (examples are Asia/Ashkhabad in 1991, // Europe/Riga in 1989)
if (i > 0) {
prevsave = rules.get(i-1).getSave();
} else {
List<RuleRec> prevrules = rule.getRules(year-1);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.