Created
January 23, 2026 02:07
-
-
Save billygl/48a09fbb422ee9f62d2068cf9cf5c8f6 to your computer and use it in GitHub Desktop.
move_events_tasks_from_one_day_to_another
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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