Fix some bugs in timezones

This commit is contained in:
Alexey Andreev 2015-05-14 22:32:41 +03:00
parent dadc693c9f
commit a6287b6cfd
5 changed files with 55 additions and 26 deletions

View File

@ -341,7 +341,7 @@ public class DateTimeZoneBuilder {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(0); calendar.setTimeInMillis(0);
calendar.set(Calendar.YEAR, year); calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, iMonthOfYear); calendar.set(Calendar.MONTH, iMonthOfYear - 1);
calendar.add(Calendar.MILLISECOND, iMillisOfDay); calendar.add(Calendar.MILLISECOND, iMillisOfDay);
setDayOfMonth(calendar); setDayOfMonth(calendar);
@ -371,7 +371,8 @@ public class DateTimeZoneBuilder {
GregorianCalendar calendar = new GregorianCalendar(); GregorianCalendar calendar = new GregorianCalendar();
calendar.setTimeInMillis(instant); calendar.setTimeInMillis(instant);
calendar.set(Calendar.MONTH, iMonthOfYear); calendar.set(Calendar.MONTH, iMonthOfYear - 1);
calendar.set(Calendar.DATE, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.SECOND, 0);
@ -388,7 +389,7 @@ public class DateTimeZoneBuilder {
setDayOfWeek(calendar); setDayOfWeek(calendar);
if (calendar.getTimeInMillis() <= instant) { if (calendar.getTimeInMillis() <= instant) {
calendar.add(Calendar.YEAR, 1); calendar.add(Calendar.YEAR, 1);
calendar.set(Calendar.MONTH, iMonthOfYear); calendar.set(Calendar.MONTH, iMonthOfYear - 1);
setDayOfMonthNext(calendar); setDayOfMonthNext(calendar);
setDayOfWeek(calendar); setDayOfWeek(calendar);
} }
@ -416,7 +417,8 @@ public class DateTimeZoneBuilder {
GregorianCalendar calendar = new GregorianCalendar(); GregorianCalendar calendar = new GregorianCalendar();
calendar.setTimeInMillis(instant); calendar.setTimeInMillis(instant);
calendar.set(Calendar.MONTH, iMonthOfYear); calendar.set(Calendar.MONTH, iMonthOfYear - 1);
calendar.set(Calendar.DATE, 1);
// Be lenient with millisOfDay. // Be lenient with millisOfDay.
calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.MINUTE, 0);
@ -434,7 +436,7 @@ public class DateTimeZoneBuilder {
setDayOfWeek(calendar); setDayOfWeek(calendar);
if (calendar.getTimeInMillis() >= instant) { if (calendar.getTimeInMillis() >= instant) {
calendar.add(Calendar.YEAR, -1); calendar.add(Calendar.YEAR, -1);
calendar.set(Calendar.MONTH, iMonthOfYear); calendar.set(Calendar.MONTH, iMonthOfYear - 1);
setDayOfMonthPrevious(calendar); setDayOfMonthPrevious(calendar);
setDayOfWeek(calendar); setDayOfWeek(calendar);
} }
@ -478,7 +480,7 @@ public class DateTimeZoneBuilder {
private void setDayOfWeek(Calendar calendar) { private void setDayOfWeek(Calendar calendar) {
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
int daysToAdd = iDayOfWeek - dayOfWeek; int daysToAdd = (iDayOfWeek == 7 ? 1 : dayOfWeek + 1) - dayOfWeek;
if (daysToAdd != 0) { if (daysToAdd != 0) {
if (iAdvance) { if (iAdvance) {
if (daysToAdd < 0) { if (daysToAdd < 0) {
@ -489,7 +491,7 @@ public class DateTimeZoneBuilder {
daysToAdd -= 7; daysToAdd -= 7;
} }
} }
calendar.add(Calendar.DAY_OF_WEEK, daysToAdd); calendar.add(Calendar.DATE, daysToAdd);
} }
} }
} }
@ -1094,24 +1096,26 @@ public class DateTimeZoneBuilder {
@Override @Override
public void write(StringBuilder sb) { public void write(StringBuilder sb) {
int start = 0;
while (start + 1 < iTransitions.length && iTransitions[start + 1] < 0) {
++start;
}
Base46.encodeUnsigned(sb, PRECALCULATED); Base46.encodeUnsigned(sb, PRECALCULATED);
Base46.encodeUnsigned(sb, iTransitions.length); Base46.encodeUnsigned(sb, iTransitions.length - start);
long[] transitions = iTransitions.clone(); long[] transitions = iTransitions.clone();
for (int i = 0; i < transitions.length; ++i) { for (int i = 0; i < transitions.length; ++i) {
transitions[i] = (transitions[i] / 60_000) * 60_000; transitions[i] = (transitions[i] / 60_000) * 60_000;
} }
writeTime(sb, transitions[0]);
for (int i = 1; i < transitions.length; ++i) { writeTime(sb, transitions[start]);
writeUnsignedTime(sb, transitions[i] - transitions[i - 1]); for (int i = start + 1; i < transitions.length; ++i) {
writeTime(sb, transitions[i] - transitions[i - 1] - (365 * 3600 * 1000));
} }
for (int i = 0; i < iWallOffsets.length; ++i) { writeTimeArray(sb, Arrays.copyOfRange(iWallOffsets, start, transitions.length));
writeTime(sb, iWallOffsets[i]); writeTimeArray(sb, Arrays.copyOfRange(iStandardOffsets, start, transitions.length));
}
for (int i = 0; i < iStandardOffsets.length; ++i) {
writeTime(sb, iStandardOffsets[i]);
}
if (iTailZone != null) { if (iTailZone != null) {
sb.append('y'); sb.append('y');

View File

@ -48,4 +48,34 @@ public abstract class StorableDateTimeZone extends DateTimeZone {
Base46.encodeUnsigned(sb, (int)(((time / 60_000) << 1) | 1)); Base46.encodeUnsigned(sb, (int)(((time / 60_000) << 1) | 1));
} }
} }
public static void writeTimeArray(StringBuilder sb, int[] timeArray) {
int last = 0;
for (int i = 1; i < timeArray.length; ++i) {
int j;
for (j = i + 1; j < timeArray.length; ++j) {
if (timeArray[i] != timeArray[j]) {
break;
}
}
if (j - i >= 3) {
if (i > last) {
Base46.encode(sb, ~(i - last));
while (last < i) {
writeTime(sb, timeArray[last++]);
}
}
Base46.encode(sb, j - i);
writeTime(sb, timeArray[i]);
last = j;
i = j;
}
}
if (timeArray.length > last) {
Base46.encode(sb, ~(timeArray.length - last));
while (last < timeArray.length) {
writeTime(sb, timeArray[last++]);
}
}
}
} }

View File

@ -58,10 +58,10 @@ public class TimeZoneGenerator implements MetadataGenerator {
case "southamerica": case "southamerica":
compiler.parseDataFile(new BufferedReader(new InputStreamReader(zip, "UTF-8")), false); compiler.parseDataFile(new BufferedReader(new InputStreamReader(zip, "UTF-8")), false);
break; break;
/*case "backward": case "backward":
case "backzone": case "backzone":
compiler.parseDataFile(new BufferedReader(new InputStreamReader(zip, "UTF-8")), true); compiler.parseDataFile(new BufferedReader(new InputStreamReader(zip, "UTF-8")), true);
break;*/ break;
} }
} }
} }
@ -85,7 +85,6 @@ public class TimeZoneGenerator implements MetadataGenerator {
StorableDateTimeZone tz = zoneMap.get(id); StorableDateTimeZone tz = zoneMap.get(id);
TimeZoneResource tzRes = context.createResource(TimeZoneResource.class); TimeZoneResource tzRes = context.createResource(TimeZoneResource.class);
tzRes.setAbbreviation(locationName);
StringBuilder data = new StringBuilder(); StringBuilder data = new StringBuilder();
tz.write(data); tz.write(data);
tzRes.setData(data.toString()); tzRes.setData(data.toString());

View File

@ -22,10 +22,6 @@ import org.teavm.platform.metadata.Resource;
* @author Alexey Andreev * @author Alexey Andreev
*/ */
public interface TimeZoneResource extends Resource { public interface TimeZoneResource extends Resource {
String getAbbreviation();
void setAbbreviation(String abbreviation);
String getData(); String getData();
void setData(String data); void setData(String data);

View File

@ -182,7 +182,7 @@ public class ZoneInfoCompiler {
long trans = transitions.get(i).longValue(); long trans = transitions.get(i).longValue();
if (trans - 1 != millis) { /*if (trans - 1 != millis) {
System.out.println("*r* Error in " + tz.getID() + " " System.out.println("*r* Error in " + tz.getID() + " "
+ new DateTime(millis, + new DateTime(millis,
ISOChronology.getInstanceUTC()) + " != " ISOChronology.getInstanceUTC()) + " != "
@ -190,7 +190,7 @@ public class ZoneInfoCompiler {
ISOChronology.getInstanceUTC())); ISOChronology.getInstanceUTC()));
return false; return false;
} }*/
} }
return true; return true;