Google apps script 当web界面每天只显示一个事件时,Google日历API会报告多个全天事件

Google apps script 当web界面每天只显示一个事件时,Google日历API会报告多个全天事件,google-apps-script,google-sheets,google-calendar-api,Google Apps Script,Google Sheets,Google Calendar Api,我正在使用下面的代码从Google工作表更新事件。当代码报告日历中存在特定日期的事件,但这些事件不会显示在web界面中时,出现了问题。我将代码更改为删除所有事件,并始终插入一个新事件,而不是进行更新,这样可以按预期工作 但这并不能解释API如何在web界面中没有显示事件的情况下报告事件的存在。这是API中的错误吗 更新:真正的问题是对getEventsForDay(d)的API调用一次返回两天的事件。因此,没有遗漏事件。但我仍然没有弄清楚如何在一天内返回事件。此日历中的所有事件都是通过API插入

我正在使用下面的代码从Google工作表更新事件。当代码报告日历中存在特定日期的事件,但这些事件不会显示在web界面中时,出现了问题。我将代码更改为删除所有事件,并始终插入一个新事件,而不是进行更新,这样可以按预期工作

但这并不能解释API如何在web界面中没有显示事件的情况下报告事件的存在。这是API中的错误吗

更新:真正的问题是对
getEventsForDay(d)
的API调用一次返回两天的事件。因此,没有遗漏事件。但我仍然没有弄清楚如何在一天内返回事件。此日历中的所有事件都是通过API插入的

function updateCalold(cell,title, calendar) {

  var d;

  try {
    d = new Date(cell.getValue()); 
  }
  catch(err) {
    return false;
  }
  var txt_date = Utilities.formatDate(d, "EST", "yyyy-MM-dd");

  var events = calendar.getEventsForDay(d);

  if ( events.length == 0 ) {
    var event = calendar.createAllDayEvent(title, d);
  }
  else {
    for (var i = 0; i < events.length; i++) {
      events[i].setVisibility(CalendarApp.Visibility.PUBLIC);
      if (events[i].getTitle() !== title) {
        events[i].setTitle(title);
      }
    }
  }
}
函数updateCald(单元格、标题、日历){
变量d;
试一试{
d=新日期(cell.getValue());
}
捕捉(错误){
返回false;
}
var txt_date=Utilities.formatDate(美国东部时间、yyyy-MM-dd);
var events=calendar.getEventsForDay(d);
如果(events.length==0){
var event=calendar.createAllDayEvent(标题,d);
}
否则{
对于(var i=0;i
您的问题很有趣,我几乎从不使用
allDayEvents
getEventsForDay
,因此我没有注意到这一点,但我显然是一个问题

getEvents()
返回的事件在定义为0小时的开始时间前一天结束,而这些事件在前一天的0小时结束。。。如果我通过添加时区偏移量来更改getEvents中的startTime,那么它可以正常工作

所以这个问题与时区有关,但我不明白它为什么会这样

无论如何,当我还在搜索精确的原点时,我找到了一个返回精确结果的解决方法

当我遇到更好的解释时,我会尽力更新这篇文章

下面是演示解决方案如何工作的代码。要获得错误,只需将
offset
值替换为0,您将再次获得多个事件

在默认日历中执行测试的条件:问题仅发生在
AllDayEvents
上,当然,您必须在昨天(在默认日历中)有另一个
OneDayEvent
。另外,手动将单元格A1设置为今天的日期!

功能测试(){
var calendar=CalendarApp.getDefaultCalendar();
var cell=SpreadsheetApp.getActive().getRange('A1');//A1有一个测试日期,我手动设置为今天的测试日期
var title='testevent rename by script@'+Utilities.formatDate(new Date(),Session.getScriptTimeZone(),'HH:mm:ss');
var result=updatecalld(单元格、标题、日历);
Logger.log('result from function='+result.join('\n\n'));
}
函数updateCald(单元格、标题、日历){
变量d;
var结果=[];
结果。推送('\n');
Logger.log(新日期().toString().split('GMT+')[1])
var offset=Number(新日期().toString().split('GMT+')[1].substr(0,2));
Logger.log(偏移量);
//offset=0;//取消对此的注释以获取错误
试一试{
d=新日期(cell.getValue());
}
捕捉(错误){
返回false;
}
var startTime=新日期(d.设定小时数(偏移量,0,0,0));
var endTime=新日期(新日期(d.setHours(0,0,0,0)).setDate(d.getDate()+1));
var events=calendar.getEvents(开始时间、结束时间);
Logger.log('startTime='+startTime+'endTime='+endTime);
Logger.log('events.length='+events.length)
如果(events.length==0){
var event=calendar.createAllDayEvent(标题,d);
}
否则{
对于(var i=0;i
编辑:当偏移量=0时,在其下方捕获日志,即出现错误:

编辑2:想法

考虑到这一点,我们可以认为今天上午0:00结束的事件可以被认为是(从某种意义上说)属于今天的事件。即使我不喜欢这种逻辑,我最终也可以接受,但当我在1小时后开始获取事件时(例如,startTime=01 AM),我不应该获取在1小时前结束的事件

错误(IMHO)是我们必须使用偏移量值=GMT偏移量才能正确。。。任何较小的值都将捕获前一天的事件!在我的例子(GMT+2)中,我也得到了偏移量为1的错误结果

恐怕这会出现在问题追踪器中,除非有人能解释


编辑3:如果这些电子表格、脚本和日历都设置为GMT0000(GMT0000不含夏令时),则即使使用
getEventsForDay()
,一切都可以正常工作,无需任何修改。请参阅,如果您的默认日历设置为GMT0而不使用夏令时,则可以进行测试,当然这只是为了测试,因为您的所有活动都将显示错误的日期!!!除非您生活在一个没有DL存储的地区,并且使用GMT0,但我认为这是不可能的;-)

你的问题很有趣,我几乎从不使用
allDayEvents
getEventsForDay
,所以我没有注意到这一点,但我显然是个问题

getEvents()
返回的事件在定义为0小时的开始时间前一天结束,而这些事件在前一天的0小时结束。。。如果我通过添加时区偏移量来更改getEvents中的startTime,那么它可以正常工作

所以这个问题与Ti有关
function test(){
  var calendar = CalendarApp.getDefaultCalendar();
  var cell = SpreadsheetApp.getActive().getRange('A1');// A1 had a test date that I set manually to today's date for test
  var title = 'test event renamed by script @ '+Utilities.formatDate(new Date(), Session.getScriptTimeZone(), 'HH:mm:ss');

  var result = updateCalold(cell,title, calendar);
  Logger.log('result from function = '+result.join('\n\n'));
}


function updateCalold(cell,title, calendar) {
  var d;
  var result = [];
  result.push('\n');
  Logger.log(new Date().toString().split('GMT+')[1])
  var offset = Number(new Date().toString().split('GMT+')[1].substr(0,2));
  Logger.log(offset);
  //offset=0; // uncomment this to get the error
  try {
    d = new Date(cell.getValue()); 
  }
  catch(err) {
    return false;
  }
  var startTime = new Date(d.setHours(offset,0,0,0));
  var endTime = new Date(new Date(d.setHours(0,0,0,0)).setDate(d.getDate()+1));
  var events = calendar.getEvents(startTime, endTime);
  Logger.log('startTime = '+startTime+'  endTime = '+endTime);
  Logger.log('events.length = '+events.length)
  if ( events.length == 0 ) {
    var event = calendar.createAllDayEvent(title, d);
  }
  else {
    for (var i = 0; i < events.length; i++) {
      events[i].setVisibility(CalendarApp.Visibility.PUBLIC);
      if (events[i].getTitle() !== title) {
        events[i].setTitle(title+' event nr'+i);
        result.push(events[i].getTitle()+' starting @ '+events[i].getStartTime()+' ending @ '+events[i].getEndTime());
      }
    }
  }
  return result;
}
Mon May 25 2015 00:00:00 GMT+0100 (BST) Spring Bank Holiday
Mon Aug 03 2015 00:00:00 GMT+0100 (BST) Summer Bank Holiday
Mon Aug 31 2015 00:00:00 GMT+0100 (BST) Summer Bank Holiday
Fri Dec 25 2015 00:00:00 GMT-0000 (GMT) Christmas Day
Sat Dec 26 2015 00:00:00 GMT-0000 (GMT) Boxing Day
Mon Dec 28 2015 00:00:00 GMT-0000 (GMT) Bank Holiday
var offset = Number(new Date().toString().split('GMT')[1].substr(0,3));
function updateEvent(cell,title, calendar) {

  var d;
  try {
    // extract date from sheet cell
    d = new Date(cell.getValue()); 
    Logger.log("updateCal: %s",d);
  }
  catch(err) {
    Logger.log("Not a date: %s", cell.getValue());
    Logger.log(err);
    return false;
  }

  var events = calendar.getEventsForDay(d);
  var foundEvent = false;
  Logger.log("numEvents: %s", events.length);

  if ( events.length > 0 ) {
    for (var i = 0; i < events.length; i++) {
      if ( events[i].isAllDayEvent() && 
           events[i].getAllDayStartDate().getDay() === d.getDay() ) { 
        foundEvent = true
        if (events[i].getTitle() !== title) {
          events[i].setTitle(title);
          Logger.log('index: %s ,updated title on event %s', i, d); 
        } 
      }
    }
  }

  if ( !foundEvent ){
    var event = calendar.createAllDayEvent(title, d);
    Logger.log('day was empty, inserted: %s on %s',title, d);
  }
}