privatestaticfinallong OFFSET_MASK = 0x0fL; privatestaticfinallong DST_MASK = 0xf0L; privatestaticfinalint DST_NSHIFT = 4; // this bit field is reserved for abbreviation support privatestaticfinallong ABBR_MASK = 0xf00L; privatestaticfinalint TRANSITION_NSHIFT = 12;
// Flag for supporting JDK backward compatible IDs, such as "EST". staticfinalboolean USE_OLDMAPPING; static {
String oldmapping = System.getProperty("sun.timezone.ids.oldmapping", "false").toLowerCase(Locale.ROOT);
USE_OLDMAPPING = (oldmapping.equals("yes") || oldmapping.equals("true"));
}
// IDs having conflicting data between Olson and JDK 1.1 staticfinal String[] conflictingIDs = { "EST", "MST", "HST"
};
privateint getOffsets(long date, int[] offsets, int type) { // if dst is never observed, there is no transition. if (transitions == null) { int offset = getLastRawOffset(); if (offsets != null) {
offsets[0] = offset;
offsets[1] = 0;
} return offset;
}
date -= rawOffsetDiff; int index = getTransitionIndex(date, type);
// prior to the transition table, returns the raw offset. // FIXME: should support LMT. if (index < 0) { int offset = getLastRawOffset(); if (offsets != null) {
offsets[0] = offset;
offsets[1] = 0;
} return offset;
}
if (index < transitions.length) { long val = transitions[index]; int offset = this.offsets[(int)(val & OFFSET_MASK)] + rawOffsetDiff; if (offsets != null) { int dst = (int)((val >>> DST_NSHIFT) & 0xfL); int save = (dst == 0) ? 0 : this.offsets[dst];
offsets[0] = offset - save;
offsets[1] = save;
} return offset;
}
// beyond the transitions, delegate to SimpleTimeZone if there // is a rule; otherwise, return rawOffset.
SimpleTimeZone tz = getLastRule(); if (tz != null) { int rawoffset = tz.getRawOffset(); long msec = date; if (type != UTC_TIME) {
msec -= rawOffset;
} int dstoffset = tz.getOffset(msec) - rawOffset;
// Check if it's in a standard-to-daylight transition. if (dstoffset > 0 && tz.getOffset(msec - dstoffset) == rawoffset) {
dstoffset = 0;
}
privateint getTransitionIndex(long date, int type) { int low = 0; int high = transitions.length - 1;
while (low <= high) { int mid = (low + high) / 2; long val = transitions[mid]; long midVal = val >> TRANSITION_NSHIFT; // sign extended if (type != UTC_TIME) {
midVal += offsets[(int)(val & OFFSET_MASK)]; // wall time
} if (type == STANDARD_TIME) { int dstIndex = (int)((val >>> DST_NSHIFT) & 0xfL); if (dstIndex != 0) {
midVal -= offsets[dstIndex]; // make it standard time
}
}
if (transitions == null) { return getLastRawOffset();
}
long dateInMillis = gcal.getTime(date) + milliseconds;
dateInMillis -= (long) rawOffset; // make it UTC return getOffsets(dateInMillis, null, UTC_TIME);
}
@Override publicboolean observesDaylightTime() { if (simpleTimeZoneParams != null) { returntrue;
} if (transitions == null) { returnfalse;
}
// Look up the transition table to see if it's in DST right // now or if there's any standard-to-daylight transition at // any future. long utc = System.currentTimeMillis() - rawOffsetDiff; int index = getTransitionIndex(utc, UTC_TIME);
// before transitions in the transition table if (index < 0) { returnfalse;
}
// the time is in the table range. for (int i = index; i < transitions.length; i++) { if ((transitions[i] & DST_MASK) != 0) { returntrue;
}
} // No further DST is observed. returnfalse;
}
// /** // * @return the last year in the transition table or -1 if this // * time zone doesn't observe any daylight saving time. // */ // public int getMaxTransitionYear() { // if (transitions == null) { // return -1; // } // long val = transitions[transitions.length - 1]; // int offset = this.offsets[(int)(val & OFFSET_MASK)] + rawOffsetDiff; // val = (val >> TRANSITION_NSHIFT) + offset; // CalendarDate lastDate = Gregorian.getCalendarDate(val); // return lastDate.getYear(); // }
loop: for (int index = 0; index < rawOffsets.length; index++) { if (rawOffsets[index] == rawOffset) { byte[] indices = ZoneInfoFile.getRawOffsetIndices(); for (int i = 0; i < indices.length; i++) { if (indices[i] == index) {
matched.add(IDs.get(i++)); while (i < indices.length && indices[i] == index) {
matched.add(IDs.get(i++));
} break loop;
}
}
}
}
// We need to add any zones from the excluded zone list that // currently have the same GMT offset as the specified // rawOffset. The zones returned by this method may not be // correct as of return to the caller if any GMT offset // transition is happening during this GMT offset checking...
List<String> excluded = ZoneInfoFile.getExcludedZones(); if (excluded != null) { for (String id : excluded) {
TimeZone zi = getTimeZone(id); if (zi != null && zi.getRawOffset() == rawOffset) {
matched.add(id);
}
}
}
result = new String[matched.size()];
matched.toArray(result); return result;
}
/** *ReturnsaMapfromaliastimezoneIDstotheirstandard *timezoneIDs. * *@returntheMapthatholdsthemappingsfromaliastimezoneIDs *totheirstandardtimezoneIDs,ornullif *<code>ZoneInfoOldMappings</code>fileisnotavailable.
*/ publicsynchronizedstatic Map<String, String> getAliasTable() {
Map<String, String> aliases = getCachedAliasTable(); if (aliases == null) {
aliases = ZoneInfoFile.getZoneAliases(); if (aliases != null) { if (!USE_OLDMAPPING) { // Remove the conflicting IDs from the alias table. for (String key : conflictingIDs) {
aliases.remove(key);
}
}
aliasTable = new SoftReference<Map<String, String>>(aliases);
}
} return aliases;
}
privatevoid readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject(); // We don't know how this object from 1.4.x or earlier has // been mutated. So it should always be marked as `dirty'.
dirty = true;
}
privateboolean equalsTransOffsets(ZoneInfoOld other) { if (transitions == null) { return (other.transitions == null &&
Arrays.equals(offsets, other.offsets));
} if (other.transitions == null ||
transitions.length != other.transitions.length) { returnfalse;
} // if offsets and other.offsets have different order // the last 4-bit in trans are different. for (int i = 0; i < transitions.length; i++) { long val = transitions[i]; int dst = (int)((val >>> DST_NSHIFT) & 0xfL); int save = (dst == 0) ? 0 : offsets[dst] / 1000; int off = offsets[(int)(val & OFFSET_MASK)]/1000; long second = (val >> TRANSITION_NSHIFT)/1000;
val = other.transitions[i]; int dstO = (int)((val >>> DST_NSHIFT) & 0xfL); int saveO = (dstO == 0) ? 0 : other.offsets[dstO] / 1000; int offO = other.offsets[(int)(val & OFFSET_MASK)]/1000; long secondO = (val >> TRANSITION_NSHIFT)/1000; if ((dst == 0) != (dstO == 0) || save != saveO || off != offO || second != secondO) returnfalse;
} returntrue;
}
privateint transToString(long val, int off_old, int[] offsets, StringBuilder sb) { int dst = (int)((val >>> DST_NSHIFT) & 0xfL); int save = (dst == 0) ? 0 : offsets[dst] / 1000; int off = offsets[(int)(val & OFFSET_MASK)]/1000; long second = (val >> TRANSITION_NSHIFT)/1000;
ZoneOffset offset_old = ZoneOffset.ofTotalSeconds(off_old);
ZoneOffset offset = ZoneOffset.ofTotalSeconds(off);
sb.append(" " + LocalDateTime.ofEpochSecond(second, 0, offset_old));
sb.append(" [utc=" + second + " raw=" + Long.toHexString(val >> TRANSITION_NSHIFT) + ", offset=" + off + "/" + offset + ", saving=" + save + "]"); return off;
}
public String diffsTo(ZoneInfoOld other) {
int rawOffset0 = other.rawOffset; int checksum0 = other.checksum; int dstSavings0 = other.dstSavings; long[] transitions0 = other.transitions; int[] offsets0 = other.offsets; int[] simpleTimeZoneParams0 = other.simpleTimeZoneParams; boolean willGMTOffsetChange0 = other.willGMTOffsetChange;
//return getClass().getName() +
StringBuilder sb = new StringBuilder();
sb.append("******************************\n" +
getID() + " : " + other.getID()); // ROC is excluded by ZoneInfoOld if ("ROC".equals(getID())) { return sb.toString();
} if (rawOffset != rawOffset0 ||
dstSavings != dstSavings0 ||
checksum != checksum0 ||
willGMTOffsetChange != willGMTOffsetChange0 ||
(simpleTimeZoneParams != null ) != (simpleTimeZoneParams0 != null) ||
(transitions != null && transitions0 != null &&
transitions.length != transitions0.length))
{
sb.append("\n offset=" + getLastRawOffset() + ",dstSavings=" + dstSavings + ",useDaylight=" + useDaylightTime() + ",transitions=" + ((transitions != null) ? transitions.length : 0) + ",offsets=" + ((offsets != null) ? offsets.length : 0) + ",checksum=" + checksum + ",gmtChanged=" + willGMTOffsetChange)
.append("\n[NG]offset=" + rawOffset0 + ",dstSavings=" + dstSavings0 + ",useDaylight=" + (simpleTimeZoneParams != null) + ",transitions=" + ((transitions0 != null) ? transitions0.length : 0) + ",offsets=" + ((offsets0 != null) ? offsets0.length : 0) + ",checksum=" + checksum0 + ",gmtChanged=" + willGMTOffsetChange0 + "");
} // offsets if (!Arrays.equals(offsets, offsets0)) {
sb.append("\n offset.len=" + ((offsets != null)? offsets.length : "null") + " " + ((offsets0 != null)? offsets0.length : "null")); if (offsets != null && offsets0.length != 0) { int len = Math.min(offsets.length, offsets0.length); int i = 0; for (i = 0; i < len; i++) {
sb.append("\n " +
ZoneOffset.ofTotalSeconds(offsets[i]/1000) + " " +
ZoneOffset.ofTotalSeconds(offsets0[i]/1000));
} for (; i < offsets0.length; i++) {
sb.append("\n " + ZoneOffset.ofTotalSeconds(offsets0[i]/1000));
}
}
} // trans int offset = 0; int offset0 = 0; if (!equalsTransOffsets(other)) {
sb.append("\n -------------"); if ((transitions == null) != (transitions0 == null)) {
sb.append("\n (NG) Different trans(null) :" +
transitions + ", " + transitions0); if (transitions != null) { for (int i = 0; i < transitions.length; i++) {
sb.append("\n (NG)");
offset = transToString(transitions[i], offset, offsets, sb);
}
}
} else { if (transitions.length != transitions0.length) {
sb.append("\n (NG) Different trans size :" +
transitions.length + ", " + transitions0.length);
} int length = Math.min(transitions.length, transitions0.length); for (int i = 0; i < length; i++) { // sb.append("\n[" + i + "] "); // offset = transToString(transitions[i], offset, offsets, sb); long val = transitions[i]; int dst = (int)((val >>> DST_NSHIFT) & 0xfL); int save = (dst == 0) ? 0 : offsets[dst] / 1000; int off = offsets[(int)(val & OFFSET_MASK)]/1000; long second = (val >> TRANSITION_NSHIFT)/1000;
sb.append("\n ");
offset = transToString(transitions[i], offset, offsets, sb); if (transitions0 == null || i >= transitions0.length) {
sb.append("\n ");
offset = transToString(transitions[i], offset, offsets, sb);
sb.append("\n (NG) trans0 is null or < trans.length");
} else { long val0 = transitions0[i]; int dst0 = (int)((val0 >>> DST_NSHIFT) & 0xfL); int save0 = (dst0 == 0) ? 0 : offsets0[dst0] / 1000; int off0 = offsets0[(int)(val0 & OFFSET_MASK)]/1000; long second0 = (val0 >> TRANSITION_NSHIFT)/1000; if (save != save0 || off != off0 || second != second0) {
sb.append("\n (NG)");
} else {
sb.append("\n (OK)");
}
offset0 = transToString(transitions0[i], offset0, offsets0, sb);
sb.append("\n -----");
}
}
}
}
SimpleTimeZone stz = getLastRuleInstance(); if (stz != null) {
SimpleTimeZone stz0 = other.getLastRule(); if (!stz.hasSameRules(stz0)) {
sb.append("\n -------------")
.append("\n SimpleTimeZone (NG)")
.append("\n stz=" + stz)
.append("\n stz0=" + stz0);
}
}
sb.append("\n -------------"); return sb.toString();
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.23 Sekunden
(vorverarbeitet am 2026-10-11)
¤
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.