From 6a4eae5f4104599cddfea67705cc4d594ee7d47f Mon Sep 17 00:00:00 2001 From: Marc Blank Date: Sat, 10 Apr 2010 11:38:46 -0700 Subject: [PATCH] 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 --- .../exchange/adapter/CalendarSyncAdapter.java | 58 +++++++------------ .../exchange/utility/CalendarUtilities.java | 20 +++++++ 2 files changed, 42 insertions(+), 36 deletions(-) diff --git a/src/com/android/exchange/adapter/CalendarSyncAdapter.java b/src/com/android/exchange/adapter/CalendarSyncAdapter.java index 438ffa894..7a9744e3d 100644 --- a/src/com/android/exchange/adapter/CalendarSyncAdapter.java +++ b/src/com/android/exchange/adapter/CalendarSyncAdapter.java @@ -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())); diff --git a/src/com/android/exchange/utility/CalendarUtilities.java b/src/com/android/exchange/utility/CalendarUtilities.java index dde2115d3..266ab69fd 100644 --- a/src/com/android/exchange/utility/CalendarUtilities.java +++ b/src/com/android/exchange/utility/CalendarUtilities.java @@ -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;