Merge change I44da0c8f into eclair
* changes: Correct the raw offsets in the time zone index for a few zones.
This commit is contained in:
@@ -48,8 +48,11 @@ public class ZoneCompactor {
|
|||||||
private static final int MAXNAME = 40;
|
private static final int MAXNAME = 40;
|
||||||
|
|
||||||
// Concatenate the contents of 'inFile' onto 'out'
|
// Concatenate the contents of 'inFile' onto 'out'
|
||||||
private static void copyFile(File inFile, OutputStream out)
|
// and return the contents as a byte array.
|
||||||
|
private static byte[] copyFile(File inFile, OutputStream out)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
byte[] ret = new byte[0];
|
||||||
|
|
||||||
InputStream in = new FileInputStream(inFile);
|
InputStream in = new FileInputStream(inFile);
|
||||||
byte[] buf = new byte[8192];
|
byte[] buf = new byte[8192];
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -58,9 +61,14 @@ public class ZoneCompactor {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
out.write(buf, 0, nbytes);
|
out.write(buf, 0, nbytes);
|
||||||
|
|
||||||
|
byte[] nret = new byte[ret.length + nbytes];
|
||||||
|
System.arraycopy(ret, 0, nret, 0, ret.length);
|
||||||
|
System.arraycopy(buf, 0, nret, ret.length, nbytes);
|
||||||
|
ret = nret;
|
||||||
}
|
}
|
||||||
out.flush();
|
out.flush();
|
||||||
return;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write a 32-bit integer in network byte order
|
// Write a 32-bit integer in network byte order
|
||||||
@@ -96,12 +104,12 @@ public class ZoneCompactor {
|
|||||||
starts.put(s, new Integer(start));
|
starts.put(s, new Integer(start));
|
||||||
lengths.put(s, new Integer((int)length));
|
lengths.put(s, new Integer((int)length));
|
||||||
|
|
||||||
TimeZone tz = TimeZone.getTimeZone(s);
|
start += length;
|
||||||
|
byte[] data = copyFile(f, zoneInfo);
|
||||||
|
|
||||||
|
TimeZone tz = ZoneInfo.make(s, data);
|
||||||
int gmtOffset = tz.getRawOffset();
|
int gmtOffset = tz.getRawOffset();
|
||||||
offsets.put(s, new Integer(gmtOffset));
|
offsets.put(s, new Integer(gmtOffset));
|
||||||
|
|
||||||
start += length;
|
|
||||||
copyFile(f, zoneInfo);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
272
tools/zoneinfo/ZoneInfo.java
Normal file
272
tools/zoneinfo/ZoneInfo.java
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2007 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copied from ZoneInfo and ZoneInfoDB in dalvik.
|
||||||
|
* {@hide}
|
||||||
|
*/
|
||||||
|
public class ZoneInfo extends TimeZone {
|
||||||
|
|
||||||
|
private static final long MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
|
||||||
|
private static final long MILLISECONDS_PER_400_YEARS =
|
||||||
|
MILLISECONDS_PER_DAY * (400 * 365 + 100 - 3);
|
||||||
|
|
||||||
|
private static final long UNIX_OFFSET = 62167219200000L;
|
||||||
|
|
||||||
|
private static final int[] NORMAL = new int[] {
|
||||||
|
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final int[] LEAP = new int[] {
|
||||||
|
0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335,
|
||||||
|
};
|
||||||
|
|
||||||
|
private static String nullName(byte[] data, int where, int off) {
|
||||||
|
if (off < 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
int end = where + off;
|
||||||
|
while (end < data.length && data[end] != '\0')
|
||||||
|
end++;
|
||||||
|
|
||||||
|
return new String(data, where + off, end - (where + off));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ZoneInfo make(String name, byte[] data) {
|
||||||
|
int ntransition = read4(data, 32);
|
||||||
|
int ngmtoff = read4(data, 36);
|
||||||
|
int base = 44;
|
||||||
|
|
||||||
|
int[] transitions = new int[ntransition];
|
||||||
|
for (int i = 0; i < ntransition; i++)
|
||||||
|
transitions[i] = read4(data, base + 4 * i);
|
||||||
|
base += 4 * ntransition;
|
||||||
|
|
||||||
|
byte[] type = new byte[ntransition];
|
||||||
|
for (int i = 0; i < ntransition; i++)
|
||||||
|
type[i] = data[base + i];
|
||||||
|
base += ntransition;
|
||||||
|
|
||||||
|
int[] gmtoff = new int[ngmtoff];
|
||||||
|
byte[] isdst = new byte[ngmtoff];
|
||||||
|
byte[] abbrev = new byte[ngmtoff];
|
||||||
|
for (int i = 0; i < ngmtoff; i++) {
|
||||||
|
gmtoff[i] = read4(data, base + 6 * i);
|
||||||
|
isdst[i] = data[base + 6 * i + 4];
|
||||||
|
abbrev[i] = data[base + 6 * i + 5];
|
||||||
|
}
|
||||||
|
|
||||||
|
base += 6 * ngmtoff;
|
||||||
|
|
||||||
|
return new ZoneInfo(name, transitions, type, gmtoff, isdst, abbrev, data, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int read4(byte[] data, int off) {
|
||||||
|
return ((data[off ] & 0xFF) << 24) |
|
||||||
|
((data[off + 1] & 0xFF) << 16) |
|
||||||
|
((data[off + 2] & 0xFF) << 8) |
|
||||||
|
((data[off + 3] & 0xFF) << 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*package*/ ZoneInfo(String name, int[] transitions, byte[] type,
|
||||||
|
int[] gmtoff, byte[] isdst, byte[] abbrev,
|
||||||
|
byte[] data, int abbrevoff) {
|
||||||
|
mTransitions = transitions;
|
||||||
|
mTypes = type;
|
||||||
|
mGmtOffs = gmtoff;
|
||||||
|
mIsDsts = isdst;
|
||||||
|
mUseDst = false;
|
||||||
|
setID(name);
|
||||||
|
|
||||||
|
// Find the latest GMT and non-GMT offsets for their abbreviations
|
||||||
|
|
||||||
|
int lastdst;
|
||||||
|
for (lastdst = mTransitions.length - 1; lastdst >= 0; lastdst--) {
|
||||||
|
if (mIsDsts[mTypes[lastdst] & 0xFF] != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int laststd;
|
||||||
|
for (laststd = mTransitions.length - 1; laststd >= 0; laststd--) {
|
||||||
|
if (mIsDsts[mTypes[laststd] & 0xFF] == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastdst >= 0) {
|
||||||
|
mDaylightName = nullName(data, abbrevoff,
|
||||||
|
abbrev[mTypes[lastdst] & 0xFF]);
|
||||||
|
}
|
||||||
|
if (laststd >= 0) {
|
||||||
|
mStandardName = nullName(data, abbrevoff,
|
||||||
|
abbrev[mTypes[laststd] & 0xFF]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the latest non-DST offset if any as the raw offset
|
||||||
|
|
||||||
|
if (laststd < 0) {
|
||||||
|
laststd = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (laststd >= mTypes.length) {
|
||||||
|
mRawOffset = mGmtOffs[0];
|
||||||
|
} else {
|
||||||
|
mRawOffset = mGmtOffs[mTypes[laststd] & 0xFF];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subtract the raw offset from all offsets so it can be changed
|
||||||
|
// and affect them too.
|
||||||
|
// Find whether there exist any observances of DST.
|
||||||
|
|
||||||
|
for (int i = 0; i < mGmtOffs.length; i++) {
|
||||||
|
mGmtOffs[i] -= mRawOffset;
|
||||||
|
|
||||||
|
if (mIsDsts[i] != 0) {
|
||||||
|
mUseDst = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mRawOffset *= 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOffset(@SuppressWarnings("unused") int era,
|
||||||
|
int year, int month, int day,
|
||||||
|
@SuppressWarnings("unused") int dayOfWeek,
|
||||||
|
int millis) {
|
||||||
|
// XXX This assumes Gregorian always; Calendar switches from
|
||||||
|
// Julian to Gregorian in 1582. What calendar system are the
|
||||||
|
// arguments supposed to come from?
|
||||||
|
|
||||||
|
long calc = (year / 400) * MILLISECONDS_PER_400_YEARS;
|
||||||
|
year %= 400;
|
||||||
|
|
||||||
|
calc += year * (365 * MILLISECONDS_PER_DAY);
|
||||||
|
calc += ((year + 3) / 4) * MILLISECONDS_PER_DAY;
|
||||||
|
|
||||||
|
if (year > 0)
|
||||||
|
calc -= ((year - 1) / 100) * MILLISECONDS_PER_DAY;
|
||||||
|
|
||||||
|
boolean isLeap = (year == 0 || (year % 4 == 0 && year % 100 != 0));
|
||||||
|
int[] mlen = isLeap ? LEAP : NORMAL;
|
||||||
|
|
||||||
|
calc += mlen[month] * MILLISECONDS_PER_DAY;
|
||||||
|
calc += (day - 1) * MILLISECONDS_PER_DAY;
|
||||||
|
calc += millis;
|
||||||
|
|
||||||
|
calc -= mRawOffset;
|
||||||
|
calc -= UNIX_OFFSET;
|
||||||
|
|
||||||
|
return getOffset(calc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOffset(long when) {
|
||||||
|
int unix = (int) (when / 1000);
|
||||||
|
int trans = Arrays.binarySearch(mTransitions, unix);
|
||||||
|
|
||||||
|
if (trans == ~0) {
|
||||||
|
return mGmtOffs[0] * 1000 + mRawOffset;
|
||||||
|
}
|
||||||
|
if (trans < 0) {
|
||||||
|
trans = ~trans - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mGmtOffs[mTypes[trans] & 0xFF] * 1000 + mRawOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRawOffset() {
|
||||||
|
return mRawOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRawOffset(int off) {
|
||||||
|
mRawOffset = off;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean inDaylightTime(Date when) {
|
||||||
|
int unix = (int) (when.getTime() / 1000);
|
||||||
|
int trans = Arrays.binarySearch(mTransitions, unix);
|
||||||
|
|
||||||
|
if (trans == ~0) {
|
||||||
|
return mIsDsts[0] != 0;
|
||||||
|
}
|
||||||
|
if (trans < 0) {
|
||||||
|
trans = ~trans - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mIsDsts[mTypes[trans] & 0xFF] != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean useDaylightTime() {
|
||||||
|
return mUseDst;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int mRawOffset;
|
||||||
|
private int[] mTransitions;
|
||||||
|
private int[] mGmtOffs;
|
||||||
|
private byte[] mTypes;
|
||||||
|
private byte[] mIsDsts;
|
||||||
|
private boolean mUseDst;
|
||||||
|
private String mDaylightName;
|
||||||
|
private String mStandardName;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof ZoneInfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ZoneInfo other = (ZoneInfo) obj;
|
||||||
|
return mUseDst == other.mUseDst
|
||||||
|
&& (mDaylightName == null ? other.mDaylightName == null :
|
||||||
|
mDaylightName.equals(other.mDaylightName))
|
||||||
|
&& (mStandardName == null ? other.mStandardName == null :
|
||||||
|
mStandardName.equals(other.mStandardName))
|
||||||
|
&& mRawOffset == other.mRawOffset
|
||||||
|
// Arrays.equals returns true if both arrays are null
|
||||||
|
&& Arrays.equals(mGmtOffs, other.mGmtOffs)
|
||||||
|
&& Arrays.equals(mIsDsts, other.mIsDsts)
|
||||||
|
&& Arrays.equals(mTypes, other.mTypes)
|
||||||
|
&& Arrays.equals(mTransitions, other.mTransitions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((mDaylightName == null) ? 0 :
|
||||||
|
mDaylightName.hashCode());
|
||||||
|
result = prime * result + Arrays.hashCode(mGmtOffs);
|
||||||
|
result = prime * result + Arrays.hashCode(mIsDsts);
|
||||||
|
result = prime * result + mRawOffset;
|
||||||
|
result = prime * result + ((mStandardName == null) ? 0 :
|
||||||
|
mStandardName.hashCode());
|
||||||
|
result = prime * result + Arrays.hashCode(mTransitions);
|
||||||
|
result = prime * result + Arrays.hashCode(mTypes);
|
||||||
|
result = prime * result + (mUseDst ? 1231 : 1237);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,7 +20,7 @@ do
|
|||||||
zic -d data $i
|
zic -d data $i
|
||||||
done
|
done
|
||||||
|
|
||||||
javac -target 1.5 ZoneCompactor.java
|
javac -target 1.5 ZoneCompactor.java ZoneInfo.java
|
||||||
|
|
||||||
(
|
(
|
||||||
cat $version/* | grep '^Link' | awk '{print $1, $2, $3}'
|
cat $version/* | grep '^Link' | awk '{print $1, $2, $3}'
|
||||||
|
|||||||
Reference in New Issue
Block a user