简体   繁体   中英

Date/Time in Google Sheet not transferring the correct time into Google calendar

I have this script which is to populate a google calendar with an event. I have a date field and a start and finish time field. While in the google spreadsheet the start time is say 13:00:00 when I run the below script the resulting calendar start time is 14:00:00. Same thing happens with the end time.

    function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{
    name : "Export Events",
    functionName : "exportEvents"
  }];
  sheet.addMenu("Calendar Actions", entries);
};

/**
 * Export events from spreadsheet to calendar
 */
function exportEvents() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var headerRows = 1;  // Number of rows of header info (to skip)
  var range = sheet.getDataRange();
  var data = range.getValues();
  var calId = "trade.nsw.gov.au_004rslcuubrtlg81mkv48lse9c@group.calendar.google.com";
  var cal = CalendarApp.getCalendarById(calId);
  for (i in data) {
    if (i < headerRows) continue; // Skip header row(s)
    var row = data[i];
    var date = new Date(row[2]);  // First column
    var title = row[1];           // Second column
    var tstart = new Date(row[3]);
    tstart.setDate(date.getDate());
    tstart.setMonth(date.getMonth());
    tstart.setYear(date.getYear());
    var tstop = new Date(row[4]);
    tstop.setDate(date.getDate());
    tstop.setMonth(date.getMonth());
    tstop.setYear(date.getYear());
    var loc = row[5];
    var desc = row[6];
    var id = row[10];              // Sixth column == eventId
    // Check if event already exists, update it if it does
    try {
      var event = cal.getEventSeriesById(id);
    }
    catch (e) {
      // do nothing - we just want to avoid the exception when event doesn't exist
    }
    if (!event) {
      //cal.createEvent(title, new Date("March 3, 2010 08:00:00"), new Date("March 3, 2010 09:00:00"), {description:desc,location:loc});
      var newEvent = cal.createEvent(title, tstart, tstop, {description:desc,location:loc}).getId();
      row[10] = newEvent;  // Update the data array with event ID
    }
    else {
      event.setTitle(title);
      event.setDescription(desc);
      event.setLocation(loc);
      // event.setTime(tstart, tstop); // cannot setTime on eventSeries.
      // ... but we CAN set recurrence!
      //var recurrence = CalendarApp.newRecurrence().addDailyRule().times(1);
      //event.setRecurrence(recurrence, tstart, tstop);
    }
    debugger;
  }
  // Record all event IDs to spreadsheet
  range.setValues(data);
}

The problem is simple but the explanation is less simple...

Let us try anyway !

code modification :

var tstart = new Date(row[3]);
Logger.log('hour only = '+tstart)
tstart.setDate(date.getDate());
Logger.log('setDate = '+tstart)
tstart.setMonth(date.getMonth());
Logger.log('setMonth = '+tstart)
tstart.setYear(date.getYear());
Logger.log('setYear = '+tstart)

As you see, I added a couple of Logger.log in your code and notice a difference in time value like shown below

[14-07-28 16:18:53:441 BST] hour only = Sat Dec 30 1899 10:00:00 GMT-0000 (GMT)
[14-07-28 16:18:53:442 BST] setDate = Fri Dec 29 1899 10:00:00 GMT-0000 (GMT)
[14-07-28 16:18:53:442 BST] setMonth = Sat Jul 29 1899 10:00:00 GMT+0100 (BST)
[14-07-28 16:18:53:442 BST] setYear = Tue Jul 29 2014 10:00:00 GMT+0100 (BST)

When you create the date object with hours only, the date is logically december 30 1899 which is in winter.(december 30 1899 is the "epoch" used as reference in JS date)

Then you set the date (still in december) and then the month which is July and July is obviously in summer... as you can see in the logger, the date object has switched from GMT to BST (british summer time I guess ?) and from there it is 1 hour later.

To solve that you have a few possibilities, the simplest one would be to combine time and date in the spreadsheet itself, this would create a complete date object that wouldn't need any change.

If you can't (or don't want) to change your SS layout I guess the easier way would be to convert your time value to a string using Utilities.formatDate() and parse this string into integer values to get hours and minutes.

You'll have to change a bit the sequence order of your date manipulations but from what I see of your coding skills that should not be a problem.

Hoping my explanation was clear enough ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM