Google Apps Script定时触发器时间与设定不符问题求助
Google Apps Script定时触发器时间不匹配问题排查与解决
我使用Google Apps Script编写代码,意图创建5个指定时间的定时触发器。执行脚本后触发器成功创建,但触发时间为脚本运行时间,而非代码中设定的时间。脚本日志显示计算出的时间均正确,且绑定表格与脚本的时区设置一致。
原代码
function copyResponses() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var ssName = ss.getName() var re=/(q)(\D*)(\d+)/i; // 提取q后的数字 var quizNumber=ssName.match(re)[3] ssSheet = ss.getSheetByName(quizNumber + 'QSummary') var dateOfQuiz = ssSheet.getRange('G1').getValue() // Logger.log(dateOfQuiz) var dateOfQuizinMS = dateOfQuiz.getTime() // console.log(dateOfQuiz,dateOfQuizinMS) var firstReportTime = new Date(dateOfQuizinMS + ((21 * 60 + 45) * 60 * 1000)); // Logger.log(firstReportTime) var secondReportTime = new Date(dateOfQuizinMS + ((22 * 60) * 60 * 1000)); // Logger.log(secondReportTime) var thirdReportTime = new Date(dateOfQuizinMS + ((22 * 60 + 30) * 60 * 1000)); // Logger.log(thirdReportTime) var fourthReportTime = new Date(dateOfQuizinMS + (((24 + 9) * 60+30) * 60 * 1000)); // Logger.log(fourthReportTime) var fifthReportTime = new Date(dateOfQuizinMS + (((24 + 21) * 60 + 30) * 60 * 1000)); // Logger.log(fifthReportTime) ScriptApp.newTrigger('getResponses') .timeBased() .at(new Date(firstReportTime)) .create(); Logger.log(new Date(firstReportTime)) ScriptApp.newTrigger('getResponses') .timeBased() .at(new Date(secondReportTime)) .create(); Logger.log(new Date(secondReportTime)) ScriptApp.newTrigger('getResponses') .timeBased() .at(new Date(thirdReportTime)) .create(); Logger.log(new Date(thirdReportTime)) ScriptApp.newTrigger('getResponses') .timeBased() .at(new Date(fourthReportTime)) .create(); ScriptApp.newTrigger('getResponses') .timeBased() .at(new Date(fifthReportTime)) .create(); }
日志信息
7:24:06 PM Info Fri Feb 17 00:00:00 GMT+05:30 2023 7:24:06 PM Info Fri Feb 17 21:45:00 GMT+05:30 2023 7:24:06 PM Info Fri Feb 17 22:00:00 GMT+05:30 2023 7:24:06 PM Info Fri Feb 17 22:30:00 GMT+05:30 2023 7:24:06 PM Info Sat Feb 18 09:30:00 GMT+05:30 2023 7:24:06 PM Info Sat Feb 18 21:30:00 GMT+05:30 2023
问题原因
核心原因是Google Apps Script的.at()方法如果传入过去的时间,会自动将触发器设置为立即执行,即使用脚本运行的时间作为触发时间。从日志来看,若你计算出的触发时间(如Fri Feb 17 21:45:00)在脚本运行时(7:24 PM,即19:24)本应是未来时间,但实际出现不匹配,大概率是dateOfQuiz的取值为过去的日期(比如你在2024年运行脚本,但G1单元格的日期是2023年2月17日),导致所有计算出的触发时间都已过期,触发器因此立即执行。
另外,代码中多次使用new Date(firstReportTime)是冗余操作(firstReportTime本身已是Date对象),但这不会直接导致时间不匹配问题。
解决方案
- 验证触发时间的有效性:在创建触发器前,检查计算出的时间是否晚于当前时间,避免创建过去时间的触发器。
- 简化Date对象传递:直接使用已创建的Date对象,无需重复包装。
- 确认
dateOfQuiz的取值:确保G1单元格的日期是未来的日期,或者根据当前日期动态调整。
修改后的代码
function copyResponses() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var ssName = ss.getName(); var now = new Date(); // 获取当前时间 var re = /(q)(\D*)(\d+)/i; var quizNumber = ssName.match(re)[3]; var ssSheet = ss.getSheetByName(quizNumber + 'QSummary'); var dateOfQuiz = ssSheet.getRange('G1').getValue(); var dateOfQuizinMS = dateOfQuiz.getTime(); // 计算所有触发时间 var triggerTimes = [ new Date(dateOfQuizinMS + ((21 * 60 + 45) * 60 * 1000)), new Date(dateOfQuizinMS + ((22 * 60) * 60 * 1000)), new Date(dateOfQuizinMS + ((22 * 60 + 30) * 60 * 1000)), new Date(dateOfQuizinMS + (((24 + 9) * 60 + 30) * 60 * 1000)), new Date(dateOfQuizinMS + (((24 + 21) * 60 + 30) * 60 * 1000)) ]; // 遍历创建触发器,仅创建未来时间的触发器 triggerTimes.forEach(function(time) { if (time > now) { ScriptApp.newTrigger('getResponses') .timeBased() .at(time) .create(); Logger.log('创建触发器,触发时间:' + time); } else { Logger.log('跳过已过期的触发时间:' + time); } }); }
额外检查项
- 确认脚本项目的时区设置:在脚本编辑器中点击右上角齿轮图标,查看时区是否与表格时区一致。
- 检查
G1单元格的日期格式:确保是有效的日期值,而非文本格式。
内容的提问来源于stack exchange,提问作者asifdawood
相关产品推荐
相关产品推荐

