# Duplicate multiple Google Calendar events, changing their dates/times

My Google Calendar has several (50 or more) events that happened in Spring 2016. They are individual events, not a single repeated event. I will be running very similar events in Spring 2017: same number of weeks, same days of weeks, same titles of events. (One example of such situation is the schedule of classes).

How to batch-copy the existing 2016 events so that they work for me in 2017?

This can be done with the Apps Script shown below. The calendar Id is found on the Settings page of a calendar. The startPeriod and endPeriod indicate the range in which the original events take place (2016-01-01 to 2016-06-01 in my example).

The adjustment of dates is separated into a separate function, tweak. I also adjusted start/end time of the events that are not all-day events; these lines are commented below.

function batchCopy() {
var id = '...@group.calendar.google.com';   // enter Calendar Id
var cal = CalendarApp.getCalendarById(id);
var startPeriod = new Date('2016-01-01T00:00:00.000Z');
var endPeriod = new Date('2016-06-01T00:00:00.000Z');
var events = cal.getEvents(startPeriod, endPeriod);
for (var i = 0; i < events.length; i++) {
var event = events[i];
var title = event.getTitle();
if (event.isAllDayEvent()) {
cal.createAllDayEvent(title, tweak(event.getAllDayStartDate()));
}
else {
var start = tweak(event.getStartTime());
start.setHours(9, 30, 0, 0);    // new starting time, 9:30
var finish = new Date(start);
finish.setHours(10, 25, 0, 0);  // new ending time, 10:25
cal.createEvent(title, start, finish);
}
Utilities.sleep(1000);
}
}


Next, the function tweak which receives the old date of the event and returns the new date. If the goal was to have the same date in another year, then the first two lines of this function would be enough. But I wanted to have the same days of week. Normally, a year has 52 weeks and 1 more day, so one should subtract 1 from the date to have the same day of week. This is done by the line

tweaked.setDate(date.getDate() - 1);  // normal offset


But the dates in January-February of 2016 have to be offset by 2 because 2016 was a leap year while 2017 isn't. Hence the if statement below.

function tweak(date) {
var tweaked = new Date(date.getTime());
tweaked.setYear(2017);                  // changed the year

// the rest is to offset the date to have the same day of week

if (tweaked.getMonth() < 2) {
tweaked.setDate(date.getDate() - 2);  // leap year offset
}
else {
tweaked.setDate(date.getDate() - 1);  // normal offset
}
return tweaked;
}


The above is all that one need to batch-copy events. But if a mistake happens, there should also be a way to delete the incorrectly created events. This is what the function below is for: it deletes all events between startClearPeriod and endClearPeriod - in my example, 2017-01-01 to 2017-06-01.

function deleteEvents() {

The Utilities.sleep calls are inserted because CalendarApp does not like creating or deleting many events (50+) without any pause in between.