Google Apps脚本:event.setTime错误和时间格式 [英] Google Apps Script: event.setTime error and time format

查看:158
本文介绍了Google Apps脚本:event.setTime错误和时间格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个几乎完整的预订系统。目前,我正在从表单中收集数据,并将其传递给工作表,然后使用其中一些信息创建日历事件。这一切都正常。



在创建事件时,我还收集eventID,以便我可以使用它识别事件并从电子表格中更新事件。这些更新也在起作用,除了更新导致以下错误的开始/结束日期和时间外:



TypeError:在对象CalendarEventSeries中找不到函数setTime



这是我正在使用的代码:

  var eventStart = sh.getRange(D+ rowNumber).getValues(); 
var eventEnd = sh.getRange(E+ rowNumber).getValues();
event.setTime(eventStart,eventEnd);

我用setLocation和setTitle完成同样的事情,没有问题。



我是新手,我不知道对象是什么,所以错误信息对我来说意义非常小!但是我可以看到,setTime是类CalendarEvent中列出的一种方法( https://developers.google.com/apps-script/reference/calendar/calendar-event#setTime(Date,Date)),但不在CalendarEventSeries中。我的所有事件都是开关事件吗?



感谢您提供任何指示。



UPDATE



我已经集成了Mogsdad的高级日历服务代码,并且在
$ b $ <$ b $ <$ c $之后c>var endTime = parseDate(event.end.date || event.end.dateTime);



我正在检查/日志记录'startTime'和'event'。 'startTime'会以'无效日期'的形式回来(坏事?),'event'会回来,我可以想象所有的日历条目信息(我希望的好东西?!)。

parseDate函数应该放在哪里?也许我把它放在了错误的地方(我已经试过了所有的地方!),这不被使用?



另外,现在我想要的事件编辑已确定,解析的日期和用于搜索我已经找到的事件,以便返回一个日历事件,我最终可以使用setTime?这是完整的吗?



感谢您的支持。

更新2 - 无效日期?



如果我跳过解析并记录变量,如下所示:

var startTime = event.start.dateTime;

结果是2015-05-24T02:00:00 + 01:00,我认为这是现实。所以无效日期肯定是在解析函数期间发生错误的一种情况,因为它只是在它返回无效日期。



下面的代码。

  function onOpen(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [{name:手动创建事件文档,functionName:addSheet},{name:更新日历条目,functionName:getEventById}
];


ss.addMenu(Select Row& Click Here,menuEntries);
}



/ **
*从ID检索CalendarApp CalendarEvent对象。
*此版本使用高级日历服务,使用前必须先启用
*。
*
* @param {string} calendarId要搜索的日历ID
* @param {字符串} eventId匹配
*
的事件ID * @returns { CalendarE CalendarEvent对象或空
* /


函数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;


//通过ID获取活动。
var event = Calendar.Events.get(calendarId,myEventId);
//这不是CalendarApp CalendarEvent,因此请使用事件中的info
//重新查找它作为正确的类型。




//获取开始&事件的结束时间。全天活动从start.date开始,
//其他事件从start.datetime开始。同样的结局。

var startTime = parseDate(event.start.date || event.start.dateTime);
var endTime = parseDate(event.end.date || event.end.dateTime);



Logger.log('Variables:'+ startTime +'and'+ endTime);

//获取startTime& endTime
var calEvents = CalendarApp.getEvents(startTime,endTime);

//搜索这些事件,通过ID
查找匹配(var i = 0; i< calEvents.length; i ++){
var curId = calEvents [ 。I] .getId()分割( '@')[0]; //从id@calendar.google.com提取id
if(curId == eventId){
//任务完成;我们有一个给定ID的Event对象!
返回calEvents [i];

}
}
//我们没有找到匹配的事件
return null;


}




function parseDate(string){
var parts = string.split( 'T');
parts [0] = parts [0] .replace(/ - / g,'/');
return new Date(parts.join(''));


解决方案

Serge的说法正确 - 问题在于您已经检索了 CalendarEventSeries 对象,而不是 CalendarEvent 。由于服务中唯一会按ID查找事件的方法是 getEventSeriesById(iCalId) ,你有点卡住了。



一种选择是使用改为高级日历服务

  var event = Calendar.Events.get(calendarId,eventId); 

对于新代码,这是一个不错的选择,特别是对于已经习惯了JavaScript API的开发人员。如果您是初学者或者不熟悉高级服务,那么您会发现学习曲线比日历服务更陡峭。 在这种情况下,这些实用程序应该帮助您坚持使用CalendarApp及其类和方法,通过填充 getEventById()函数。

高级日历服务



有两个版本的 getEventById()。第一个使用高级日历服务,必须在使用之前启用。代码非常简单。您必须明确提供日历ID,因为这不是类方法。示例:

  var calendarId = CalendarApp.getDefaultCalendar()。getId(); 
var eventId =smmd8h1dfe9lo9bip52hidnqk0;
var event = getEventById(calendarId,eventId);

代码:

  / ** 
*从ID检索CalendarApp CalendarEvent对象。
*此版本使用高级日历服务,使用前必须先启用
*。
*
* @param {string} calendarId要搜索的日历ID
* @param {字符串} eventId匹配
*
的事件ID * @returns { CalendarEvent} CalendarApp CalendarEvent对象或空
* /
函数getEventById(calendarId,eventId){
//通过ID获取事件。
var event = Calendar.Events.get(calendarId,eventId);
//这不是CalendarApp CalendarEvent,因此请使用事件中的info
//重新查找它作为正确的类型。

//获取开始&事件的结束时间。全天活动从start.date开始,
//其他事件从start.datetime开始。同样的结局。
var startTime = parseDate(event.start.date || event.start.dateTime);
var endTime = parseDate(event.end.date || event.end.dateTime);

//获取startTime& endTime
var calEvents = CalendarApp.getEvents(startTime,endTime);

//搜索这些事件,通过ID
查找匹配(var i = 0; i< calEvents.length; i ++){
var curId = calEvents [ 。I] .getId()分割( '@')[0]; //从id@calendar.google.com提取id
if(curId == eventId){
//任务完成;我们有一个给定ID的Event对象!
返回calEvents [i];
}
}
//我们没有找到匹配的事件
return null;
}



通过UrlFetchApp的日历API



此版本通过UrlFetchApp使用Calendar API,不需要任何特殊的启用。然而,代码比以前的版本更复杂。

/ **
*从ID中检索CalendarApp CalendarEvent对象。
*此版本通过UrlFetchApp使用Calendar API,因此
*不需要启用。但是,它更复杂。
*
* @param {string} calendarId要搜索的日历ID
* @param {字符串} eventId匹配
*
的事件ID * @returns { CalendarEvent} CalendarApp CalendarEvent对象或空
* /
函数getEventById(calendarId,eventId){
//准备对API URL的GET请求,以通过ID获取事件。
var url =https://www.googleapis.com/calendar/v3/calendars/calendarId/events/eventId
.replace(calendarId,calendarId)
.replace( EVENTID,事件ID);

var options = {
headers:{
'Authorization':'Bearer'+ ScriptApp.getOAuthToken()
}
}

//发送请求
var response = UrlFetchApp.fetch(url,options);
var rc = response.getResponseCode();
var text = response.getContentText();

//如果结果代码是200OK,处理响应文本
if(rc == 200){
//事件包含在响应文本中;将其解析为一个对象
var event = JSON.parse(text);
//这不是CalendarApp CalendarEvent,因此请使用事件中的info
//重新查找它作为正确的类型。

//获取开始&事件的结束时间。全天活动从start.date开始,
//其他事件从start.datetime开始。同样的结局。
var startTime = parseDate(event.start.date || event.start.dateTime);
var endTime = parseDate(event.end.date || event.end.dateTime);

//获取startTime& endTime
var calEvents = CalendarApp.getEvents(startTime,endTime);

//搜索这些事件,通过ID
查找匹配(var i = 0; i< calEvents.length; i ++){
var curId = calEvents [ 。I] .getId()分割( '@')[0]; //从id@calendar.google.com提取ID
var desc = calEvents [i] .getDescription();
if(curId == eventId){
//任务完成;我们有一个给定ID的Event对象!
返回calEvents [i];
}
}
//我们没有找到匹配的事件
return null;
}
else
//在读取时出错,任何东西但是200
throw new Error(+ rc + JSON.parse(text).message);



助手功能



getEventById()的两个版本均需要此帮助函数,该函数在 Google的文档


$ b

  / ** 
*从https://developers.google.com/apps-script/advanced/calendar#listing_events
*
*解析RFC 3339日期或日期时间字符串并返回相应的日期
*对象。此功能作为解决方法提供,直到Apps脚本
*支持RFC 3339日期为止。有关更多信息,请参阅
* https://code.google.com/p/google-apps-script-issues/issues/detail?id=3860
* @param {字符串}字符串RFC 3339字符串解析。
* @return {Date}解析的日期。
* /
function parseDate(string){
var parts = string.split('T');
parts [0] = parts [0] .replace(/ - / g,'/');
return new Date(parts.join(''));
}


I'm creating something of a booking system which is nearly complete. Currently I'm collecting data from a form, passing it to a sheet, and then using some of that info to create a calendar event. This all works fine.

On creating the event, I'm also collecting the eventID so that I can use it to identify the event and update it from the spreadsheet. These updates are also working, with the exception of updating the start/end date and time which causes the following error:

TypeError: Cannot find function setTime in object CalendarEventSeries.

This is the code I'm working with:

var eventStart =  sh.getRange("D"+rowNumber).getValues();
var eventEnd =  sh.getRange("E"+rowNumber).getValues();
event.setTime(eventStart, eventEnd);

I'm doing exactly the same thing with setLocation and setTitle without a problem.

I'm new to this, I don't know what an object is and so the error message means very little to me! But I can see that setTime is a method outlined in the class 'CalendarEvent' (https://developers.google.com/apps-script/reference/calendar/calendar-event#setTime(Date,Date)), but not in 'CalendarEventSeries'. All my events are on-off events anyway?

Thanks in advance for any pointers.

UPDATE

I have integrated Mogsdad's Advanced Calendar Service code, and after

"var endTime = parseDate(event.end.date||event.end.dateTime);"

I am checking/logging 'startTime' and 'event'. 'startTime' is coming back as 'invalid date' (bad thing?) and 'event' is coming back with all the calendar entry info I can imagine (good thing I hope?!).

Where should the parseDate function actually go? Maybe I have it in the wrong place (I've tried it all over the place!) and this isn't being used?

Also, now the event I want to edit has been identified, are the dates parsed and used to search for the event I have already found in order to return a Calendar event that I can ultimately use setTime on? Is that the whole point of this?

Thanks for bearing with me.

UPDATE 2 - INVALID DATE?

If I skip the parsing and log the variable like this:

var startTime = event.start.dateTime;

The result is 2015-05-24T02:00:00+01:00 which I think is spot on. So the invalid date is definitely a case of something going wrong during the parse function as it only then that it returns 'invalid date'.

Code in context below.

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(' '));
}

解决方案

Serge has it right - the problem is that you've retrieved a CalendarEventSeries object, not a CalendarEvent. Since the only method in the service that will look for an event by ID is getEventSeriesById(iCalId), you're kinda stuck.

One option is to use the Advanced Calendar Service instead:

var event = Calendar.Events.get(calendarId, eventId);

For new code, that's a great option, especially for developers already used to Javascript APIs. If you're a beginner or not familiar with the Advanced Services, though, you'll find that there's a steeper learning curve than for the Calendar Service.

In that case, these utilities should help you stick with the CalendarApp and its Classes and Methods, by filling the need for a getEventById() function.

Advanced Calendar Service under the hood

There are two versions of getEventById(). This first one utilizes the Advanced Calendar Service, which must be enabled before use. The code is fairly straight-forward. You must provide the Calendar ID explicitly, since this isn't a Class Method. Example:

var calendarId = CalendarApp.getDefaultCalendar().getId();
var eventId = "smmd8h1dfe9lo9bip52hidnqk0";
var event = getEventById(calendarId, eventId);

Code:

/**
 * 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;
}

Calendar API via UrlFetchApp

This version utilizes the Calendar API via UrlFetchApp, which doesn't require any special enablement. However, the code is more complex than the previous version.

/**
 * 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 );
}

Helper function

Both versions of getEventById() require this helper function, provided in 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(' '));
}

这篇关于Google Apps脚本:event.setTime错误和时间格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆