Skip to content

Instantly share code, notes, and snippets.

@billygl
Created January 23, 2026 02:07
Show Gist options
  • Select an option

  • Save billygl/48a09fbb422ee9f62d2068cf9cf5c8f6 to your computer and use it in GitHub Desktop.

Select an option

Save billygl/48a09fbb422ee9f62d2068cf9cf5c8f6 to your computer and use it in GitHub Desktop.
move_events_tasks_from_one_day_to_another
const CALENDAR_IDS = [
'micorreo@gmail.com',
'micalendarioID@group.calendar.google.com'//
]
const TASK_LIST_ID = 'milistadetareaID';//
function main() {
// Format: YYYY-MM-DD
const ORIGINAL_DATE_STR = '2026-01-17';
const NEW_DATE_STR = '2026-02-02';
const originalDate = new Date(ORIGINAL_DATE_STR + 'T00:00:00');
const newDate = new Date(NEW_DATE_STR + 'T00:00:00');
if (isNaN(originalDate.getTime()) || isNaN(newDate.getTime())) {
Logger.log('Error: Invalid date format. Please use YYYY-MM-DD for both dates.');
return;
}
let titleFilter = '[ ]'
CALENDAR_IDS.forEach((calendarId) => {
moveAllEventsToNewDate(calendarId, titleFilter, originalDate, newDate, true);
})
titleFilter = ''
moveAllTasksToNewDate(titleFilter, originalDate, newDate, true);//use performMove false to simulate
}
/**
* Moves all events from an original date to a new date, preserving their times.
* @param {String} titleFilter Filters title.
* @param {Date} originalDate The date to find events on (at midnight).
* @param {Date} newDate The date to move events to (at midnight).
* @param {Boolean} performMove If true, move the tasks. If false, only list
*/
function moveAllEventsToNewDate(calendarId, titleFilter, originalDate, newDate, performMove) {
const calendar = CalendarApp.getCalendarById(calendarId);
if (!calendar) {
Logger.log('Error: Calendar not found with ID: ' + CALENDAR_ID);
return;
}
const startTime = originalDate;
const endTime = new Date(startTime.getTime());
endTime.setDate(startTime.getDate() + 1);
const events = calendar.getEvents(startTime, endTime);
const originalDateStr = originalDate.toLocaleDateString();
const newDateStr = newDate.toLocaleDateString();
if (events.length === 0) {
Logger.log('No events found on ' + originalDateStr + '.');
return;
}
if (performMove) {
Logger.log('Moving ' + events.length + ' events from ' + originalDateStr + ' to ' + newDateStr + '...');
} else {
Logger.log('SIMULATION: Found ' + events.length + ' events on ' + originalDateStr + ' that would be moved to ' + newDateStr + ':');
}
events.forEach(function(event) {
const title = event.getTitle();
if(!title.startsWith(titleFilter)){
return
}
if (event.isAllDayEvent()) {
if (performMove) {
event.moveTo(newDate);
Logger.log(' Moved (all-day): "' + title + '" to ' + newDateStr);
} else {
Logger.log(' [All-day] "' + title + '"');
}
} else {
const originalEventStart = event.getStartTime();
const newStartDateTime = new Date(newDate.getTime());
newStartDateTime.setHours(originalEventStart.getHours());
newStartDateTime.setMinutes(originalEventStart.getMinutes());
newStartDateTime.setSeconds(originalEventStart.getSeconds());
if (performMove) {
const originalEventEnd = event.getEndTime();
const duration = originalEventEnd.getTime() - originalEventStart.getTime();
const newEndDateTime = new Date(newStartDateTime.getTime() + duration);
event.setTime(newStartDateTime, newEndDateTime);
Logger.log(' Moved (timed): "' + title + '" to ' + newStartDateTime.toLocaleString());
} else {
Logger.log(' [Timed] "' + title + '" (originally at ' + originalEventStart.toLocaleTimeString() + ')');
}
}
});
if (performMove) {
Logger.log('Move complete.');
} else {
Logger.log('Simulation complete. No events were moved.');
}
}
/**
* Moves or lists all incomplete tasks due on an original date to a new due date.
* * @param {String} titleFilter Filters title.
* @param {Date} originalDate The exact due date to find tasks on.
* @param {Date} newDate The new due date to set for those tasks.
*D* @param {boolean} performMove If true, moves the tasks. If false, only lists them.
*/
function moveAllTasksToNewDate(titleFilter, originalDate, newDate, performMove) {
const originalDateFriendly = originalDate.toLocaleDateString();
const newDateFriendly = newDate.toLocaleDateString();
const dueMinStr = originalDate.toISOString();
const endTime = new Date(originalDate.getTime());
endTime.setDate(originalDate.getDate() + 1);
const dueMaxStr = endTime.toISOString();
let tasksResponse;
try {
const options = {
dueMin: dueMinStr,
dueMax: dueMaxStr,
showCompleted: false,
maxResults: 100 // Get up to 100 tasks
};
tasksResponse = Tasks.Tasks.list(TASK_LIST_ID, options);
} catch (e) {
Logger.log('Error: Could not list tasks. ' + e);
Logger.log('Check your TASK_LIST_ID and API permissions.');
return;
}
const tasksToMove = tasksResponse.items;
if (!tasksToMove || tasksToMove.length === 0) {
Logger.log('No incomplete tasks found due on ' + originalDateFriendly + '.');
return;
}
if (performMove) {
Logger.log('Moving ' + tasksToMove.length + ' tasks due on ' + originalDateFriendly + ' to ' + newDateFriendly + '...');
} else {
Logger.log('SIMULATION: Found ' + tasksToMove.length + ' tasks due on ' + originalDateFriendly + ':');
}
tasksToMove.forEach(function(task) {
const title = task.title; // Note: 'task.title', not 'task.getTitle()'
if(!title.startsWith(titleFilter)){
return
}
if (performMove) {
const oldDateTime = new Date(task.due)
const newDateTime = new Date(newDate.getTime());
newDateTime.setHours(oldDateTime.getHours());
newDateTime.setMinutes(oldDateTime.getMinutes());
newDateTime.setSeconds(oldDateTime.getSeconds());
const newResource = {
due: newDateTime.toISOString()
};
// Call the 'patch' method to update the task
var taskI = Tasks.Tasks.get(TASK_LIST_ID, task.id);
Tasks.Tasks.patch(newResource, TASK_LIST_ID, task.id);
Logger.log(' Moved: "' + title + '" to be due on ' + newDateTime.toLocaleString());
} else {
// This is the simulation.
Logger.log(' [Task] "' + title + '"');
}
});
// Final message
if (performMove) {
Logger.log('Task move complete.');
} else {
Logger.log('Simulation complete. No tasks were moved.');
}
}
/**
* Helper function to format time nicely (e.g., "10:30 AM" or "All-day")
* @param {Date} date The event's start or end time.
* @return {string} A formatted time string.
*/
function formatEventTime(date) {
if (date.getHours() === 0 && date.getMinutes() === 0 && date.getSeconds() === 0) {
}
return date.toLocaleTimeString(); // Formats as '10:30:00 AM'
}
/**
* Helper function to find your Task List IDs.
* Run THIS function once to see all your task lists and their IDs in the log.
*/
function listAllTaskLists() {
Logger.log('Finding your Task List IDs...');
let taskListsResponse;
try {
// This uses the 'Tasks' advanced service you enabled
taskListsResponse = Tasks.Tasklists.list();
} catch (e) {
Logger.log('Error: Could not access Tasks API. ' + e);
Logger.log('Please make sure the "Google Tasks API" advanced service is enabled (in Services +).');
return;
}
if (!taskListsResponse.items || taskListsResponse.items.length === 0) {
Logger.log('No task lists found.');
return;
}
// The 'items' property holds the array of lists
taskListsResponse.items.forEach(function(list) {
Logger.log(' - List Name: "%s", ID: "%s"', list.title, list.id);
});
Logger.log('Copy the ID of the list you want to use into the TASK_LIST_ID_TO_USE constant below.');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment