4
votes

I am trying to get the events in my calendar over a date range (single or recurring events alike). Now I will not necessarily know the exact datetime for the next instance of a recurring event as . For recurring events I want the date of the next occurrence rather than the date of the first instance as I am getting with the request below. How do I do this?

https://www.googleapis.com/calendar/v3/calendars/{calendarid}/events?fields=items(id,summary,start)&key={APIkey}&timeMax={enddate}&timeMin={startdate}

3

3 Answers

10
votes

Add in the URL parameter singleEvents=True. This will expand all recurring events into their individual items. There isn't any way to specifically get just the second event in a series if you don't already know when it is, but using that parameter will let you parse out all instances and get the one you want.

Source: https://developers.google.com/google-apps/calendar/v3/reference/events/list

0
votes
long now = System.currentTimeMillis();

Uri.Builder eventsUriBuilder = CalendarContract.Instances.CONTENT_URI.buildUpon();
ContentUris.appendId(eventsUriBuilder, Long.MIN_VALUE);
ContentUris.appendId(eventsUriBuilder, Long.MAX_VALUE);
String[] projection = new String[]{CalendarContract.Instances.CALENDAR_ID, CalendarContract.Instances.TITLE,
        CalendarContract.Instances.DESCRIPTION, CalendarContract.Instances.BEGIN,
        CalendarContract.Instances.END, CalendarContract.Instances.EVENT_LOCATION,
        CalendarContract.Instances.EVENT_ID};

Uri eventsUri = eventsUriBuilder.build();
Cursor instance_cursor = getActivity().getContentResolver().query(
        eventsUri, projection, CalendarContract.Instances.BEGIN + " >= " + now + " and " + CalendarContract.Instances.BEGIN
                + " <= " + (now + 2592000000L) + " and " + CalendarContract.Instances.VISIBLE + " = 1",
        null, CalendarContract.Instances.DTSTART + " ASC");
0
votes

There is now direct way of doing that but you can hack together a method to accomplish that.

The idea is that you can specify time boundaries and limit the number of records and that's enough to do the job.

So setting the timeMin to now (or right after your reference event end date), timeMax to a big enough number, like a year from timeMin and maxResults = 1 will get the next instance if it exists.

Here is how this can be done in nodejs:

    let startDate = startTime ? new Date(startTime) : new Date()
    let endDate = endTime ? new Date(endTime) : new Date(startDate.getTime() + 12 * 31 * 24 * 60 * 60 * 1000) // 1 year ahead
    let startDateISO = startDate.toISOString()
    let endDateISO = endDate.toISOString()

    let result = await  calendar.events.instances({
        calendarId: "primary",
        eventId: masterEventId,
        maxResults: 1,
        timeMin: startDateISO,
        timeMax: endDateISO,
        orderBy: "startTime",
        timeZone: "UTC"
    })
    let nextInstance = res.data.items[0]

Similarly you can get previous instance if you order results in descending order and reverse the time boundaries (set timeMin to a year back and timeMax before the start of the reference event).