Ezil Kannan
Ezil Kannan

Reputation: 63

Value of UNTIL in RRULE when breaking a repeat event

Consider the following Repeat event in Google Calendar with the RRULE as mentioned below.

BEGIN:VEVENT
DTSTART;TZID=Asia/Calcutta:20170111T020000
DTEND;TZID=Asia/Calcutta:20170111T050000
RRULE:FREQ=DAILY;UNTIL=20170116T203000Z
DTSTAMP:20170110T150957Z
CREATED:20170110T150942Z
DESCRIPTION:
LAST-MODIFIED:20170110T150942Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Repeat event test
TRANSP:OPAQUE
END:VEVENT

If this event is now edited by breaking the recurrence series into two parts(Edit this and future events) on say 14th Jan, the RRULE of this event is changed to the following

RRULE:FREQ=DAILY;UNTIL=20170113T182959Z

Why is the value of UNTIL set to 1 second less than the RECURRENCEID/DTSTART value of the recurrence on 14th January instead of setting it to the DTSTART value of the recurrence on 13th January. Is there a standard that the UNTIL value in RRULE in such cases must be set in this manner (i.e. 1 second less)?

Upvotes: 1

Views: 526

Answers (2)

Hardip
Hardip

Reputation: 360

public String pushAppointmentsToCalender(Activity curActivity, String title, String addInfo, long startDate, boolean needReminder) {
    try {
        String eventUriString = "content://com.android.calendar/events";
        ContentValues eventValues = new ContentValues();
        eventValues.put("calendar_id", 1); // id, We need to choose from
        // our mobile for primary
        //CalendarContract.EXTRA_EVENT_END_TIME
        // its 1
        eventValues.put("title", title);
        eventValues.put("description", addInfo);
        eventValues.put("dtstart", startDate);
        eventValues.put("dtend", startDate);

        String untileDate = "20220515";
        switch (repeatSelection) {
            case "Every Day":
                if (!untileDate.equals("")) {
                    eventValues.put("rrule", "FREQ=DAILY;UNTIL=" + untileDate);
                } else {
                    eventValues.put("rrule", "FREQ=DAILY");
                }
                break;
            case "Every Week":
                if (!untileDate.equals("")) {
                    eventValues.put("rrule", "FREQ=WEEKLY;UNTIL=" + untileDate);
                } else {
                    eventValues.put("rrule", "FREQ=WEEKLY");
                }
                break;
            case "Every Month":
                if (!untileDate.equals("")) {
                    eventValues.put("rrule", FREQ=MONTHLY;UNTIL=" + untileDate);

                } else {
                    eventValues.put("rrule", "FREQ=MONTHLY");
                }
                break;
            case "Custom":
                switch (frequency) {
                    case "1":
                        if (!untileDate.equals("")) {
                            eventValues.put("rrule", "FREQ=DAILY;INTERVAL=" + Integer.parseInt(every) + ";UNTIL=" + untileDate);
                        } else {
                            eventValues.put("rrule", "FREQ=DAILY;INTERVAL=" + Integer.parseInt(every));
                        }
                        break;
                    case "3":
                        if (!untileDate.equals("")) {
                            eventValues.put("rrule", "FREQ=WEEKLY;INTERVAL=" + Integer.parseInt(every) + ";UNTIL=" + untileDate);
                        } else {
                            eventValues.put("rrule", "FREQ=WEEKLY;INTERVAL=" + Integer.parseInt(every));
                        }
                        break;
                    case "2":
                        if (!untileDate.equals("")) {
                            eventValues.put("rrule", "FREQ=MONTHLY;INTERVAL=" + Integer.parseInt(every) + ";UNTIL=" + untileDate);
                        } else {
                            eventValues.put("rrule", "FREQ=MONTHLY;INTERVAL=" + Integer.parseInt(every));
                        }
                        break;
                    case "4":
                        if (!untileDate.equals("")) {
                            eventValues.put("rrule", "FREQ=YEARLY;INTERVAL=" + Integer.parseInt(every) + ";UNTIL=" + untileDate);
                        } else {
                            eventValues.put("rrule", "FREQ=YEARLY;INTERVAL=" + Integer.parseInt(every));
                        }
                        break;
                }
                break;
        }

        eventValues.put("allDay", 0); //If it is bithday alarm or such
        // kind (which should remind me for whole day) 0 for false, 1
        // for true
        eventValues.put("eventStatus", 1); // This information is
        TimeZone timeZone = TimeZone.getDefault();
        eventValues.put(CalendarContract.Events.EVENT_TIMEZONE, timeZone.getID());
        eventValues.put("hasAlarm", 1); // 0 for false, 1 for true

        Uri eventUri = curActivity.getApplicationContext().getContentResolver().insert(Uri.parse(eventUriString), eventValues);
        long eventID = Long.parseLong(eventUri.getLastPathSegment());

        if (needReminder) {
            /**************** Event: Reminder(with alert) Adding reminder to event ******************/
            String reminderUriString = "content://com.android.calendar/reminders";
            ContentValues reminderValues = new ContentValues();
            reminderValues.put("event_id", eventID);
            reminderValues.put("minutes", 10); // Default value of the
            // system. Minutes is a
            // integer
            reminderValues.put("method", 1); // Alert Methods: Default(0),
            // Alert(1), Email(2),
            // SMS(3)
            Uri reminderUri = curActivity.getApplicationContext().getContentResolver().insert(Uri.parse(reminderUriString), reminderValues);
        }
        return "" + eventID;
    } catch (Exception e) {
        e.printStackTrace();
        return "";
    }
}

repeatSelection type =Every Day,Every Week,Every Month,Custom; frequency type =1,2,3,4; when you select custom frequency type 1 = DAILY,2=MONTHLY,3=WEEKLY,4 YEARLY;

Upvotes: 0

Arnaud Quillaud
Arnaud Quillaud

Reputation: 4645

You wont find any standard mentioning this. https://www.rfc-editor.org/rfc/rfc5545#section-3.3.10 mentions how

If the value specified by UNTIL is synchronized with the specified recurrence, this DATE or DATE-TIME becomes the last instance of the recurrence.

but it does not mandate that the value must be synchronized with the recurrence, nor does it mention that it should be 1 second less whatever.

I suspect that this was just a convenience for the developer since the cutoff date is the 14th which he is aready manipulating, whereas the previous instance would have been required to be calculated.

Upvotes: 1

Related Questions