Fix upload of multi-day all day events

* We were assuming a single day for all-day events
* Use the actual end date
* Make sure we send date/time back to server in local TZ
* Also fixes #2500863

Bug: 2578776
Change-Id: I58767a574248935b9840ce93e634a24e54abe62f
This commit is contained in:
Marc Blank 2010-04-10 11:38:46 -07:00
parent 80bd83fd85
commit 6a4eae5f41
2 changed files with 42 additions and 36 deletions

View File

@ -1187,46 +1187,32 @@ public class CalendarSyncAdapter extends AbstractSyncAdapter {
s.data(Tags.CALENDAR_ALL_DAY_EVENT, ade.toString());
}
// DTSTART is always supplied
long startTime = entityValues.getAsLong(Events.DTSTART);
if (allDay) {
// Calendar uses GMT for all day events
GregorianCalendar gmtCal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
gmtCal.setTimeInMillis(startTime);
// This calendar must be in the event's time zone
GregorianCalendar allDayCal = new GregorianCalendar(eventTimeZone);
// Set a new calendar with correct y/m/d, but h/m/s set to zero
allDayCal.set(gmtCal.get(GregorianCalendar.YEAR), gmtCal.get(GregorianCalendar.MONTH),
gmtCal.get(GregorianCalendar.DATE), 0, 0, 0);
// Use this as the start time
s.data(Tags.CALENDAR_START_TIME,
CalendarUtilities.millisToEasDateTime(allDayCal.getTimeInMillis()));
// Use a day later as the end time
allDayCal.add(GregorianCalendar.DATE, 1);
s.data(Tags.CALENDAR_END_TIME,
CalendarUtilities.millisToEasDateTime(allDayCal.getTimeInMillis()));
} else {
s.data(Tags.CALENDAR_START_TIME, CalendarUtilities.millisToEasDateTime(startTime));
// If we've got DTEND, we use it
if (entityValues.containsKey(Events.DTEND)) {
s.data(Tags.CALENDAR_END_TIME, CalendarUtilities.millisToEasDateTime(
entityValues.getAsLong(Events.DTEND)));
} else {
// Convert duration into millis and add it to DTSTART for DTEND
// We'll use 1 hour as a default (if there's no duration specified or if the parse
// of the duration fails)
long durationMillis = HOURS;
if (entityValues.containsKey(Events.DURATION)) {
Duration duration = new Duration();
try {
duration.parse(entityValues.getAsString(Events.DURATION));
} catch (ParseException e) {
// Can't do much about this; use the default (1 hour)
}
// Determine endTime; it's either provided as DTEND or we calculate using DURATION
// If no DURATION is provided, we default to one hour
long endTime;
if (entityValues.containsKey(Events.DTEND)) {
endTime = entityValues.getAsLong(Events.DTEND);
} else {
long durationMillis = HOURS;
if (entityValues.containsKey(Events.DURATION)) {
Duration duration = new Duration();
try {
duration.parse(entityValues.getAsString(Events.DURATION));
} catch (ParseException e) {
// Can't do much about this; use the default (1 hour)
}
s.data(Tags.CALENDAR_END_TIME,
CalendarUtilities.millisToEasDateTime(startTime + durationMillis));
}
endTime = startTime + durationMillis;
}
if (allDay) {
TimeZone tz = TimeZone.getDefault();
startTime = CalendarUtilities.getAllDayCalendar(startTime, tz).getTimeInMillis();
endTime = CalendarUtilities.getAllDayCalendar(endTime, tz).getTimeInMillis();
}
s.data(Tags.CALENDAR_START_TIME, CalendarUtilities.millisToEasDateTime(startTime));
s.data(Tags.CALENDAR_END_TIME, CalendarUtilities.millisToEasDateTime(endTime));
s.data(Tags.CALENDAR_DTSTAMP,
CalendarUtilities.millisToEasDateTime(System.currentTimeMillis()));

View File

@ -881,6 +881,26 @@ public class CalendarUtilities {
return sb.toString();
}
/**
* Create a GregorianCalendar representing the year, month, and day for the given time in
* milliseconds and the local time zone. Hours, minutes, and seconds will be set to zero
* @param time the time in millis
* @param timeZone the time zone to be used
* @return a GregorianCalendar with the data required for an all-day event
*/
static public GregorianCalendar getAllDayCalendar(long time, TimeZone timeZone) {
// Calendar gives us times in GMT
GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
calendar.setTimeInMillis(time);
// But we must send back to EAS in the event's time zone
GregorianCalendar allDayCalendar = new GregorianCalendar(timeZone);
// Set this calendar with correct year, month, and day, but zero hour, minute, and seconds
allDayCalendar.set(calendar.get(GregorianCalendar.YEAR),
calendar.get(GregorianCalendar.MONTH),
calendar.get(GregorianCalendar.DATE), 0, 0, 0);
return allDayCalendar;
}
static void addByDay(StringBuilder rrule, int dow, int wom) {
rrule.append(";BYDAY=");
boolean addComma = false;