Google Apps 脚本:event.setTime 错误和时间格式
Google Apps Script: event.setTime error and time format
我正在创建一个即将完成的预订系统。目前我正在从表单中收集数据,将其传递给 sheet,然后使用其中的一些信息来创建日历事件。这一切都很好。
在创建事件时,我还收集了 eventID,以便我可以使用它来识别事件并从传播中更新它sheet。这些更新也有效,除了更新 start/end 日期和时间会导致以下错误:
类型错误:在对象 CalendarEventSeries 中找不到函数 setTime。
这是我正在使用的代码:
var eventStart = sh.getRange("D"+rowNumber).getValues();
var eventEnd = sh.getRange("E"+rowNumber).getValues();
event.setTime(eventStart, eventEnd);
我对 setLocation 和 setTitle 做了完全相同的事情,没有问题。
我是新手,我不知道对象是什么,所以错误消息对我来说意义不大!但我可以看到 setTime 是 class 'CalendarEvent' (https://developers.google.com/apps-script/reference/calendar/calendar-event#setTime(Date,Date)) 中概述的方法,但不是 'CalendarEventSeries' 中的方法。反正我所有的事件都是开关事件?
提前感谢您的指点。
更新
我集成了Mogsdad的高级日历服务代码,之后
"var endTime = parseDate(event.end.date||event.end.dateTime);"
我是checking/logging'startTime'和'event'。 'startTime' 作为 'invalid date' 回来了(坏事?)并且 'event' 回来了我能想象到的所有日历条目信息(我希望是好事?!)。
parseDate 函数应该去哪里?也许我把它放错地方了(我到处都试过了!)而且它没有被使用?
此外,现在我要编辑的事件已经确定,日期是否已解析并用于搜索我已经找到的事件,以便 return 我最终可以使用 setTime 的日历事件在?这就是重点吗?
谢谢你的包容
更新 2 - 无效日期?
如果我跳过解析并像这样记录变量:
var 开始时间 = event.start.dateTime;
结果是 2015-05-24T02:00:00+01:00 我认为是正确的。因此,无效日期肯定是解析函数期间出现问题的情况,因为它只是 returns 'invalid date'。
下面上下文中的代码。
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [{name: "Create Event Document Manually", functionName: "addSheet"},{name: "Update Calendar Entry", functionName: "getEventById"}
];
ss.addMenu("Select Row & Click Here", menuEntries);
}
/**
* Retrieve a CalendarApp CalendarEvent object from IDs.
* This version utilizes the Advanced Calendar Service, which must be
* enabled before use.
*
* @param {string} calendarId ID of calendar to be searched
* @param {string} eventId Event ID to match
*
* @returns {CalendarEvent} CalendarApp CalendarEvent object or null
*/
function getEventById(calendarId, eventId) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getActiveSheet();
var rowNumber = sh.getActiveRange().getRowIndex();
var myEventId = "q8q533oioluipirksmno88qv2g";
var calendarId = "mydomain.tv_q9608ku2min78rasgt2s2n233c@group.calendar.google.com";
// Get event by ID.
var event = Calendar.Events.get(calendarId, myEventId);
// This isn't a CalendarApp CalendarEvent though, so use the info
// in the event to find it AGAIN as the right type.
// Get start & end times of event. All-day events start at start.date,
// while other events start at start.datetime. Likewise for end.
var startTime = parseDate(event.start.date||event.start.dateTime);
var endTime = parseDate(event.end.date||event.end.dateTime);
Logger.log('Variables: ' + startTime + ' and ' + endTime);
// Get array of events that fall between startTime & endTime
var calEvents = CalendarApp.getEvents(startTime, endTime);
// Search through those events, looking for a match by ID
for (var i=0; i<calEvents.length; i++) {
var curId = calEvents[i].getId().split('@')[0]; // extract id from id@calendar.google.com
if (curId == eventId) {
// Mission accomplished; we have an Event object with given id!
return calEvents[i];
}
}
// We did not find matching event
return null;
}
function parseDate(string) {
var parts = string.split('T');
parts[0] = parts[0].replace(/-/g, '/');
return new Date(parts.join(' '));
}
当您从事件 ID 检索事件时,您(很可能)正在使用方法 getEventSerieById(ID) which returns a CalendarEventSeries, not a CalendarEvent。
如果您查看这 3 个参考文档,您会注意到 CalendarEventSeries class 没有 setTime()
方法。
在这种情况下,您收到的错误消息实际上非常明确。
你应该找到一些处理这个问题的帖子,例如这个:Create Google Calendar Events from Spreadsheet but prevent duplicates
Serge 说得对 - 问题是您检索了一个 CalendarEventSeries
object, not a CalendarEvent
. Since the only method in the service that will look for an event by ID is getEventSeriesById(iCalId)
,您有点卡住了。
一种选择是使用 Advanced Calendar Service 代替:
var event = Calendar.Events.get(calendarId, eventId);
对于新代码,这是一个很好的选择,特别是对于已经习惯了 Javascript API 的开发人员。但是,如果您是初学者或不熟悉高级服务,您会发现学习曲线比日历服务更陡峭。
在那种情况下,这些实用程序应该可以帮助您坚持使用 CalendarApp 及其 Classes 和方法,满足对 getEventById()
函数的需求。
后台高级日历服务
getEventById()
有两个版本。第一个使用高级日历服务,它必须是 enabled before use。代码相当简单。您必须明确提供日历 ID,因为这不是 Class 方法。示例:
var calendarId = CalendarApp.getDefaultCalendar().getId();
var eventId = "smmd8h1dfe9lo9bip52hidnqk0";
var event = getEventById(calendarId, eventId);
代码:
/**
* Retrieve a CalendarApp CalendarEvent object from IDs.
* This version utilizes the Advanced Calendar Service, which must be
* enabled before use.
*
* @param {string} calendarId ID of calendar to be searched
* @param {string} eventId Event ID to match
*
* @returns {CalendarEvent} CalendarApp CalendarEvent object or null
*/
function getEventById(calendarId, eventId) {
// Get event by ID.
var event = Calendar.Events.get(calendarId, eventId);
// This isn't a CalendarApp CalendarEvent though, so use the info
// in the event to find it AGAIN as the right type.
// Get start & end times of event. All-day events start at start.date,
// while other events start at start.datetime. Likewise for end.
var startTime = parseDate(event.start.date||event.start.dateTime);
var endTime = parseDate(event.end.date||event.end.dateTime);
// Get array of events that fall between startTime & endTime
var calEvents = CalendarApp.getEvents(startTime, endTime);
// Search through those events, looking for a match by ID
for (var i=0; i<calEvents.length; i++) {
var curId = calEvents[i].getId().split('@')[0]; // extract id from id@calendar.google.com
if (curId == eventId) {
// Mission accomplished; we have an Event object with given id!
return calEvents[i];
}
}
// We did not find matching event
return null;
}
日历 API 通过 UrlFetchApp
此版本通过 UrlFetchApp 使用日历 API,不需要任何特殊启用。不过代码比之前的版本复杂多了。
/**
* Retrieve a CalendarApp CalendarEvent object from IDs.
* This version utilizes the Calendar API via UrlFetchApp, so
* requires no enablement. However, it's more complex.
*
* @param {string} calendarId ID of calendar to be searched
* @param {string} eventId Event ID to match
*
* @returns {CalendarEvent} CalendarApp CalendarEvent object or null
*/
function getEventById(calendarId, eventId) {
// Prepare a GET request to API URL, to Get event by ID.
var url = "https://www.googleapis.com/calendar/v3/calendars/calendarId/events/eventId"
.replace("calendarId",calendarId)
.replace("eventId",eventId);
var options = {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()
}
}
// Send request
var response = UrlFetchApp.fetch(url, options);
var rc = response.getResponseCode();
var text = response.getContentText();
// If result code is 200OK, process response text
if (rc == 200) {
// The event is contained in the response text; parse it into an object
var event = JSON.parse(text);
// This isn't a CalendarApp CalendarEvent though, so use the info
// in the event to find it AGAIN as the right type.
// Get start & end times of event. All-day events start at start.date,
// while other events start at start.datetime. Likewise for end.
var startTime = parseDate(event.start.date||event.start.dateTime);
var endTime = parseDate(event.end.date||event.end.dateTime);
// Get array of events that fall between startTime & endTime
var calEvents = CalendarApp.getEvents(startTime, endTime);
// Search through those events, looking for a match by ID
for (var i=0; i<calEvents.length; i++) {
var curId = calEvents[i].getId().split('@')[0]; // extract id from id@calendar.google.com
var desc = calEvents[i].getDescription();
if (curId == eventId) {
// Mission accomplished; we have an Event object with given id!
return calEvents[i];
}
}
// We did not find matching event
return null;
}
else
// An error in fetch, anything BUT 200
throw new Error( ""+rc+JSON.parse(text).message );
}
辅助函数
getEventById()
的两个版本都需要 Google's documentation 中提供的辅助函数。
/**
* From https://developers.google.com/apps-script/advanced/calendar#listing_events
*
* Parses an RFC 3339 date or datetime string and returns a corresponding Date
* object. This function is provided as a workaround until Apps Script properly
* supports RFC 3339 dates. For more information, see
* https://code.google.com/p/google-apps-script-issues/issues/detail?id=3860
* @param {string} string The RFC 3339 string to parse.
* @return {Date} The parsed date.
*/
function parseDate(string) {
var parts = string.split('T');
parts[0] = parts[0].replace(/-/g, '/');
return new Date(parts.join(' '));
}
我正在创建一个即将完成的预订系统。目前我正在从表单中收集数据,将其传递给 sheet,然后使用其中的一些信息来创建日历事件。这一切都很好。
在创建事件时,我还收集了 eventID,以便我可以使用它来识别事件并从传播中更新它sheet。这些更新也有效,除了更新 start/end 日期和时间会导致以下错误:
类型错误:在对象 CalendarEventSeries 中找不到函数 setTime。
这是我正在使用的代码:
var eventStart = sh.getRange("D"+rowNumber).getValues();
var eventEnd = sh.getRange("E"+rowNumber).getValues();
event.setTime(eventStart, eventEnd);
我对 setLocation 和 setTitle 做了完全相同的事情,没有问题。
我是新手,我不知道对象是什么,所以错误消息对我来说意义不大!但我可以看到 setTime 是 class 'CalendarEvent' (https://developers.google.com/apps-script/reference/calendar/calendar-event#setTime(Date,Date)) 中概述的方法,但不是 'CalendarEventSeries' 中的方法。反正我所有的事件都是开关事件?
提前感谢您的指点。
更新
我集成了Mogsdad的高级日历服务代码,之后
"var endTime = parseDate(event.end.date||event.end.dateTime);"
我是checking/logging'startTime'和'event'。 'startTime' 作为 'invalid date' 回来了(坏事?)并且 'event' 回来了我能想象到的所有日历条目信息(我希望是好事?!)。
parseDate 函数应该去哪里?也许我把它放错地方了(我到处都试过了!)而且它没有被使用?
此外,现在我要编辑的事件已经确定,日期是否已解析并用于搜索我已经找到的事件,以便 return 我最终可以使用 setTime 的日历事件在?这就是重点吗?
谢谢你的包容
更新 2 - 无效日期?
如果我跳过解析并像这样记录变量:
var 开始时间 = event.start.dateTime;
结果是 2015-05-24T02:00:00+01:00 我认为是正确的。因此,无效日期肯定是解析函数期间出现问题的情况,因为它只是 returns 'invalid date'。
下面上下文中的代码。
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [{name: "Create Event Document Manually", functionName: "addSheet"},{name: "Update Calendar Entry", functionName: "getEventById"}
];
ss.addMenu("Select Row & Click Here", menuEntries);
}
/**
* Retrieve a CalendarApp CalendarEvent object from IDs.
* This version utilizes the Advanced Calendar Service, which must be
* enabled before use.
*
* @param {string} calendarId ID of calendar to be searched
* @param {string} eventId Event ID to match
*
* @returns {CalendarEvent} CalendarApp CalendarEvent object or null
*/
function getEventById(calendarId, eventId) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getActiveSheet();
var rowNumber = sh.getActiveRange().getRowIndex();
var myEventId = "q8q533oioluipirksmno88qv2g";
var calendarId = "mydomain.tv_q9608ku2min78rasgt2s2n233c@group.calendar.google.com";
// Get event by ID.
var event = Calendar.Events.get(calendarId, myEventId);
// This isn't a CalendarApp CalendarEvent though, so use the info
// in the event to find it AGAIN as the right type.
// Get start & end times of event. All-day events start at start.date,
// while other events start at start.datetime. Likewise for end.
var startTime = parseDate(event.start.date||event.start.dateTime);
var endTime = parseDate(event.end.date||event.end.dateTime);
Logger.log('Variables: ' + startTime + ' and ' + endTime);
// Get array of events that fall between startTime & endTime
var calEvents = CalendarApp.getEvents(startTime, endTime);
// Search through those events, looking for a match by ID
for (var i=0; i<calEvents.length; i++) {
var curId = calEvents[i].getId().split('@')[0]; // extract id from id@calendar.google.com
if (curId == eventId) {
// Mission accomplished; we have an Event object with given id!
return calEvents[i];
}
}
// We did not find matching event
return null;
}
function parseDate(string) {
var parts = string.split('T');
parts[0] = parts[0].replace(/-/g, '/');
return new Date(parts.join(' '));
}
当您从事件 ID 检索事件时,您(很可能)正在使用方法 getEventSerieById(ID) which returns a CalendarEventSeries, not a CalendarEvent。
如果您查看这 3 个参考文档,您会注意到 CalendarEventSeries class 没有 setTime()
方法。
在这种情况下,您收到的错误消息实际上非常明确。
你应该找到一些处理这个问题的帖子,例如这个:Create Google Calendar Events from Spreadsheet but prevent duplicates
Serge 说得对 - 问题是您检索了一个 CalendarEventSeries
object, not a CalendarEvent
. Since the only method in the service that will look for an event by ID is getEventSeriesById(iCalId)
,您有点卡住了。
一种选择是使用 Advanced Calendar Service 代替:
var event = Calendar.Events.get(calendarId, eventId);
对于新代码,这是一个很好的选择,特别是对于已经习惯了 Javascript API 的开发人员。但是,如果您是初学者或不熟悉高级服务,您会发现学习曲线比日历服务更陡峭。
在那种情况下,这些实用程序应该可以帮助您坚持使用 CalendarApp 及其 Classes 和方法,满足对 getEventById()
函数的需求。
后台高级日历服务
getEventById()
有两个版本。第一个使用高级日历服务,它必须是 enabled before use。代码相当简单。您必须明确提供日历 ID,因为这不是 Class 方法。示例:
var calendarId = CalendarApp.getDefaultCalendar().getId();
var eventId = "smmd8h1dfe9lo9bip52hidnqk0";
var event = getEventById(calendarId, eventId);
代码:
/**
* Retrieve a CalendarApp CalendarEvent object from IDs.
* This version utilizes the Advanced Calendar Service, which must be
* enabled before use.
*
* @param {string} calendarId ID of calendar to be searched
* @param {string} eventId Event ID to match
*
* @returns {CalendarEvent} CalendarApp CalendarEvent object or null
*/
function getEventById(calendarId, eventId) {
// Get event by ID.
var event = Calendar.Events.get(calendarId, eventId);
// This isn't a CalendarApp CalendarEvent though, so use the info
// in the event to find it AGAIN as the right type.
// Get start & end times of event. All-day events start at start.date,
// while other events start at start.datetime. Likewise for end.
var startTime = parseDate(event.start.date||event.start.dateTime);
var endTime = parseDate(event.end.date||event.end.dateTime);
// Get array of events that fall between startTime & endTime
var calEvents = CalendarApp.getEvents(startTime, endTime);
// Search through those events, looking for a match by ID
for (var i=0; i<calEvents.length; i++) {
var curId = calEvents[i].getId().split('@')[0]; // extract id from id@calendar.google.com
if (curId == eventId) {
// Mission accomplished; we have an Event object with given id!
return calEvents[i];
}
}
// We did not find matching event
return null;
}
日历 API 通过 UrlFetchApp
此版本通过 UrlFetchApp 使用日历 API,不需要任何特殊启用。不过代码比之前的版本复杂多了。
/**
* Retrieve a CalendarApp CalendarEvent object from IDs.
* This version utilizes the Calendar API via UrlFetchApp, so
* requires no enablement. However, it's more complex.
*
* @param {string} calendarId ID of calendar to be searched
* @param {string} eventId Event ID to match
*
* @returns {CalendarEvent} CalendarApp CalendarEvent object or null
*/
function getEventById(calendarId, eventId) {
// Prepare a GET request to API URL, to Get event by ID.
var url = "https://www.googleapis.com/calendar/v3/calendars/calendarId/events/eventId"
.replace("calendarId",calendarId)
.replace("eventId",eventId);
var options = {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()
}
}
// Send request
var response = UrlFetchApp.fetch(url, options);
var rc = response.getResponseCode();
var text = response.getContentText();
// If result code is 200OK, process response text
if (rc == 200) {
// The event is contained in the response text; parse it into an object
var event = JSON.parse(text);
// This isn't a CalendarApp CalendarEvent though, so use the info
// in the event to find it AGAIN as the right type.
// Get start & end times of event. All-day events start at start.date,
// while other events start at start.datetime. Likewise for end.
var startTime = parseDate(event.start.date||event.start.dateTime);
var endTime = parseDate(event.end.date||event.end.dateTime);
// Get array of events that fall between startTime & endTime
var calEvents = CalendarApp.getEvents(startTime, endTime);
// Search through those events, looking for a match by ID
for (var i=0; i<calEvents.length; i++) {
var curId = calEvents[i].getId().split('@')[0]; // extract id from id@calendar.google.com
var desc = calEvents[i].getDescription();
if (curId == eventId) {
// Mission accomplished; we have an Event object with given id!
return calEvents[i];
}
}
// We did not find matching event
return null;
}
else
// An error in fetch, anything BUT 200
throw new Error( ""+rc+JSON.parse(text).message );
}
辅助函数
getEventById()
的两个版本都需要 Google's documentation 中提供的辅助函数。
/**
* From https://developers.google.com/apps-script/advanced/calendar#listing_events
*
* Parses an RFC 3339 date or datetime string and returns a corresponding Date
* object. This function is provided as a workaround until Apps Script properly
* supports RFC 3339 dates. For more information, see
* https://code.google.com/p/google-apps-script-issues/issues/detail?id=3860
* @param {string} string The RFC 3339 string to parse.
* @return {Date} The parsed date.
*/
function parseDate(string) {
var parts = string.split('T');
parts[0] = parts[0].replace(/-/g, '/');
return new Date(parts.join(' '));
}