DO NOT MERGE: Fix serious DST issue with non-DST time zones
* When finding a match for an EAS time zone without DST, we were checking the offset, but NOT the DST status; therefore, we could match the wrong time zone (depending on the order of items in the TZ database) * All users with events set up in non-DST timezones would have their events show up at the wrong time after a DST transition * The fix is to first check against the default time zone, and use that if it's a match; otherwise, to use the first time zone that matches both offset and DST availability Bug: 4337360 Change-Id: Ia26590972c1b0eab4640a3082881a28ee0a81622
This commit is contained in:
parent
b79e9fed67
commit
c55e2c8847
@ -30,14 +30,15 @@ import com.android.exchange.EasSyncService;
|
||||
import com.android.exchange.SyncManager;
|
||||
import com.android.exchange.adapter.Serializer;
|
||||
import com.android.exchange.adapter.Tags;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.Entity;
|
||||
import android.content.EntityIterator;
|
||||
import android.content.Entity.NamedContentValues;
|
||||
import android.content.EntityIterator;
|
||||
import android.content.res.Resources;
|
||||
import android.net.Uri;
|
||||
import android.os.RemoteException;
|
||||
@ -698,7 +699,7 @@ public class CalendarUtilities {
|
||||
TimeZone timeZone = sTimeZoneCache.get(timeZoneString);
|
||||
if (timeZone != null) {
|
||||
if (Eas.USER_LOG) {
|
||||
SyncManager.log(TAG, " Using cached TimeZone " + timeZone.getDisplayName());
|
||||
SyncManager.log(TAG, " Using cached TimeZone " + timeZone.getID());
|
||||
}
|
||||
} else {
|
||||
timeZone = tziStringToTimeZoneImpl(timeZoneString);
|
||||
@ -739,14 +740,31 @@ public class CalendarUtilities {
|
||||
TimeZoneDate dstEnd =
|
||||
getTimeZoneDateFromSystemTime(timeZoneBytes, MSFT_TIME_ZONE_STANDARD_DATE_OFFSET);
|
||||
if (dstEnd == null) {
|
||||
// In this case, there is no daylight savings time, so the only interesting data
|
||||
// is the offset, and we know that all of the zoneId's match; we'll take the first
|
||||
timeZone = TimeZone.getTimeZone(zoneIds[0]);
|
||||
if (Eas.USER_LOG) {
|
||||
SyncManager.log(TAG, "TimeZone without DST found by offset: " +
|
||||
timeZone.getDisplayName());
|
||||
// If the default time zone is a match
|
||||
TimeZone defaultTimeZone = TimeZone.getDefault();
|
||||
if (!defaultTimeZone.useDaylightTime() &&
|
||||
ArrayUtils.contains(zoneIds, defaultTimeZone.getID())) {
|
||||
if (Eas.USER_LOG) {
|
||||
SyncManager.log(TAG, "TimeZone without DST found to be default: " +
|
||||
defaultTimeZone.getID());
|
||||
}
|
||||
return defaultTimeZone;
|
||||
}
|
||||
return timeZone;
|
||||
// In this case, there is no daylight savings time, so the only interesting data
|
||||
// for possible matches is the offset and DST availability; we'll take the first
|
||||
// match for those
|
||||
for (String zoneId: zoneIds) {
|
||||
timeZone = TimeZone.getTimeZone(zoneId);
|
||||
if (!timeZone.useDaylightTime()) {
|
||||
if (Eas.USER_LOG) {
|
||||
SyncManager.log(TAG, "TimeZone without DST found by offset: " +
|
||||
timeZone.getID());
|
||||
}
|
||||
return timeZone;
|
||||
}
|
||||
}
|
||||
// None found, return null
|
||||
return null;
|
||||
} else {
|
||||
TimeZoneDate dstStart = getTimeZoneDateFromSystemTime(timeZoneBytes,
|
||||
MSFT_TIME_ZONE_DAYLIGHT_DATE_OFFSET);
|
||||
@ -791,7 +809,7 @@ public class CalendarUtilities {
|
||||
timeZone = TimeZone.getTimeZone(zoneIds[0]);
|
||||
if (Eas.USER_LOG) {
|
||||
SyncManager.log(TAG, "No TimeZone with correct DST settings; using first: " +
|
||||
timeZone.getDisplayName());
|
||||
timeZone.getID());
|
||||
}
|
||||
return timeZone;
|
||||
}
|
||||
|
@ -91,6 +91,12 @@ public class CalendarUtilitiesTests extends AndroidTestCase {
|
||||
"AAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAACgARwBNAFQAKwAwADAAOgAwADAAKQAgAFQAaQBtAGUAIABaAG8A" +
|
||||
"bgBlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAFAAEAAAAAAAAAxP///w==";
|
||||
|
||||
// This time zone has no DST, but earlier, buggy code retrieved a TZ WITH DST
|
||||
private static final String ARIZONA_TIME =
|
||||
"pAEAAFUAUwAgAE0AbwB1AG4AdABhAGkAbgAgAFMAdABhAG4AZABhAHIAZAAgAFQAaQBtAGUAAAAAAAAAAAAA" +
|
||||
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFUAUwAgAE0AbwB1AG4AdABhAGkAbgAgAEQAYQB5AGwAaQBnAGgA" +
|
||||
"dAAgAFQAaQBtAGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==";
|
||||
|
||||
private static final String ORGANIZER = "organizer@server.com";
|
||||
private static final String ATTENDEE = "attendee@server.com";
|
||||
|
||||
@ -125,6 +131,9 @@ public class CalendarUtilitiesTests extends AndroidTestCase {
|
||||
tz = CalendarUtilities.tziStringToTimeZone(GMT_UNKNOWN_DAYLIGHT_TIME);
|
||||
int bias = tz.getOffset(System.currentTimeMillis());
|
||||
assertEquals(0, bias);
|
||||
// Make sure non-DST TZ's work properly
|
||||
tz = CalendarUtilities.tziStringToTimeZone(ARIZONA_TIME);
|
||||
assertEquals("America/Phoenix", tz.getID());
|
||||
}
|
||||
|
||||
public void testGenerateEasDayOfWeek() {
|
||||
|
Loading…
Reference in New Issue
Block a user