calendarApp createEvent added event on wrong day - google-apps-script

Here is my code:
function calEvent(){
var arrivalDate = "06/10/2013";
var departureDate = "06/18/2013";
var start = new Date(arrivalDate);
var end = new Date(departureDate);
var cal = CalendarApp.getCalendarById('id487g3esn088a00omqa99ugv0#group.calendar.google.com');
cal.createEvent('Apollo 11 Landing',start,end);
}
When I run this it will create the event in the correct calendar however it will only be from June 10 thru June 17. I need the event to cover June 10 - June 18.
I have checked the Timezone setting and the spreadsheet, script and calendar are all on the same time zone (Mountain Time GMT-7)
How can I get this seemingly simple code to set the event on the correct dates? I've tried several date formatting (utilities.formatDate) but can't seem to get the correct format.
Thanks in advance.

How to use timeZone of calendar to set timeZone for date object
I posed the above question a couple a weeks ago, and came up with a working solution. Not sure if it is the best or not, but you can look over and see if it helps. In working on a solution for my question I noticed several things. The script definitely uses the script timezone to create a date object. But when it post to a calendar it adjust the date to executors default calendar timezone not the timezone of the calendar you're writing too. So if a user's default calendar timezone is different from the calendar being written to you will get all kind of crazy time's
So the function gasTimezoneOffset() that is listed in the above question was my solution for this.
Hope this helps.

Related

Old spreadsheets have wrong time and timezone .getValue() from cell

Problem: wrong time and timezone .getValue() from cell with format time
The bug occurs in old spreadsheets from 2017, but not a spreadsheet from 2022 january or new spreadsheets. update: it did appear in a new sheet as well
What steps will reproduce the problem?
Spreadsheet settings -> timezone GMT+1 (your current timezone)
in cell A1 write 20:00:00
set format cell A1 to "time"
execute this function in google apps script
function showTimeInCellA1() {
const date = SpreadsheetApp.getActiveSheet().getRange("A1").getValue();
SpreadsheetApp.getUi().alert("date in A1 is " + date);
}
Problem: it will alert "date in A1 is Sat Dec 30 1899 19:09:21 GMT+0009"
Expected: I expected time 20:00:00 and GMT+1(because settings spreadsheet are GMT+1)
This appears to be a bug!
Leaving this here for future readers as I think this may have been reported by OP.
There is already a report on Google's Issue Tracker which detail the same kind of behaviour:
wrong time and timezone .getValue() from cell with format time
Google does seem to know about this issue but you can also hit the ☆ next to the issue number in the top left of the page so to let Google know more people are encountering the behaviour so it is more likely to be seen to faster.
A workaround could be to add some years and use the time value of the new date object. I did not examine the exact number of years to be added in order to get valid time information - just tried to get past 1970 which worked for me.
var val2=new Date(val).getTime()+1000*60*60*24*365.25*72 // add ~72 years
Logger.log(new Date(val2))
The value of the current cell in Google Sheets is "8:00:00 AM"
A helper function was used to add the time to a given date:
function utils_buildDate(date,time){
var d=new Date(date);
// +-----------------------------------------------------------------
// | fix time value problem (no date is given in sheet)
// | https://issuetracker.google.com/issues/230650549?pli=1
time=new Date(time).getTime()+1000*60*60*24*365.25*72 // add ~72 years
// +-----------------------------------------------------------------
d.setHours(new Date(time).getHours());
d.setMinutes(new Date(time).getMinutes());
d.setSeconds(new Date(time).getSeconds());
return d;
}

google calendar, spreadsheet and script handle time zone differently

I am trying to write a script to add events from Spreadsheet to Calendar. I found the time of added events is always 1 hour off. I checked the time zone settings and here's what I found.
Calendar: (GMT-04:00) Eastern Time
Spreadsheet: (GMT-05:00) Eastern Time
Script: (GMT-05:00) Eastern Time
So they are all Eastern Time, but the Calendar uses the Daylight Savings Time while the Spreadsheet and Script.
I know I can manually adjust GMT every time DST changes so that the resulting time is right. But is there a better way, so that I can set and forget?
Instead of hardcoding the timezone with GMT-04:00 use the literal expression of your geographic area (aka Canonical ID) as defined in this standard : Joda.org
this is what Google Apps Script is using.
You can also get that more simply using
SpreadsheetApp.getActive().getSpreadsheetTimeZone()
or from the calendar object : calendar.getTimeZone()
all these parameters will handle daylight savings automatically, which is not the case for the GMT+xx:xx method.
You shouldn't have any problem as long as both are on the same timezone. Calendars have a setTimeZone(timeZone) method and spreadsheets have a setSpreadsheetTimeZone(timeZone) method so it is easy to synchronize both
EDIT
Following comment
Since you seem to combine date and time in a unique date object and that the daylight saving puts you into trouble (because "pure time" values in spreadsheets are converted to a date JavaScript object automatically and with summer time correction), below is a small code that I use to workaround this issue. I added a few logs to show intermediate values;
function combineDateAndTime(){
// in this example cell A1 has a date and cell B1 has time
var sh = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var dateOnly = sh.getRange('A1').getValue();
var timeOnly = sh.getRange('B1').getValue();
Logger.log('dateOnly object is : '+dateOnly+'\ntimeOnly object is : '+timeOnly);
var hours = Number(Utilities.formatDate(timeOnly, 'GMT'+timeOnly.toString().split('GMT')[1],'hh'));
var minutes = timeOnly.getMinutes();
var completeDateAndTime = new Date(dateOnly.setHours(hours,minutes,0,0));
Logger.log('completeDateAndTime is : '+completeDateAndTime);
}
Note : there are other ways to retrieve hour values, see this post for example.

Google apps script - form input time changes when copied

I have a Google form to collect info on people leaving the organisation. One of the questions is 'What date and what time do they leave' The response is in the format dd/mm/yyyy, hh:mm. so a typical response would be 24/04/2015 17:00:00, and that's what I see in the Form responses 1 worksheet when the form is submitted.
I need to add the day of the week and copy the information into another worksheet within the spreadsheet, so I use
var leaveDate = inputSheet.getRange("G" + lastRow).getValue();
var leaveDateTime = Utilities.formatDate(leaveDate, "GMT", "EEE dd-MM-yyyy hh:mm:ss");
The issue I'm seeing is that when I paste the value the time is changing, and what gets pasted is
Fri 24-04-2015 04:00:00
Can anyone explain why this is happening and what I can do to resolve it?
Thanks
Apps Script converts date types to the time zone set up in the script editor. In the script editor, you need to set the time zone, even if you've set it in the spreadsheet.
Set the time zone to your local time zone.
Make sure the time zone in your spreadsheet, and the time zone in your script editor match.
If you have multiple editors of the spreadsheet in multiple time zones, and the other users have set the time to their local time, then obviously, their time and your time won't be the same. If someone left the organization on the other side of the world, at 4pm their time, they didn't leave the organziation at 4pm your time. You could assume that if the spreadsheet states 4pm, that it was their local time, and convert the time. In that case, you'd need to know the time zone of every time entry that is made, and then adjust it as necessary.
Try:
...
// var leaveDateTime = Utilities.formatDate(leaveDate, "GMT", "EEE dd-MM-yyyy hh:mm:ss");
var leaveDateTime = Utilities.formatDate(leaveDate, "GMT", "EEE dd-MM-yyyy HH:mm:ss");
...
UPDATE
Thanks to #sandy-good and #wchiquito for pointing me in the right direction. There were 2 issues. First issue is using hh instead of HH. The second issue is that we are on GMT+1 at the moment, and will be until end October, at which point we go back to GMT! As I don't want to code around that I'm going to simplify it by dropping the day, which then means I don't have to reformat the date.

How to create AllDay Event with Google Apps Script that span multiple days and show as a single bar

I have a script that takes event information for google sheet and adds them into a specified google calendar. So far everything works fine except when I try to create an all day event that spans multiple days. The scenario that I am fighting with is for vacation. If I create the event manually, I can choose "All day" and set a start and end date of two different days. Note, "Repeat..." is not used. Visually the event spans the days specified. This is what I want to duplicate with my script.
As far as I can tell, the API only provides:
calendar.createEvent(title, startTime, endTime)
which creates a non-all day event that does span days, but it shows the start time which is not what I want. The event is truly and all day event.
calendar.createAllDayEvent(title, date)
which creates and all day event for only one day.
What seems to be missing is
calendar.createAllDayEvent(title, startDate, endDate)
which is what is discussed here: https://code.google.com/p/google-apps-script-issues/issues/detail?id=952, but there isn't any significant movement on the issue.
A possible work around is discussed here: How to create two days AllDay Event with Google Apps Script?. The problem is creates what looks like multiple single all day events. I want the multi day to show up as spanning multiple days.
Has anyone found any other work around?
You can use createEventFromDescription(), it works perfectly for "n" full days.
var start = Utilities.formatDate(new Date(date_from), "GMT"-0500, "MM-dd-yyyy");
var end = Utilities.formatDate(new Date(date_to), "GMT"-0500, "MM-dd-yyyy");
var vacationCalendar = CalendarApp.getCalendarById(CALENDAR_ID);
vacationCalendar.createEventFromDescription(title+" "+start+"-"+end);
Edy's suggestion of createEventFromDescription() is nice and clean, +1.
With that being said, if you need more fine-grained control over the event and have a lot of metadata you're trying to set (such as location, description, attendees, etc), I would recommend using the new version of the Google Cal API aka "Advanced Calendar Service", which natively supports multiple-day all-day events.
Basically looks like this:
// end dates are exclusive, so this creates a 2-day event
// starting on the 9th and ending on the 10th
var event = {
summary: 'My Event',
start: {
date: '2015-04-09' // unfortunate it doesn't seem to accept JS Date() objects :(
},
end: {
date: '2015-04-11'
}
};
event = Calendar.Events.insert(event, calId);
For what it's worth, "use this new API" is also the answer given by a google dev on the issue ticket mentioned in the original description of this StackOverflow post.

Google Apps Script getEventsForDay() returns invalid recurring events

In trying to extract a day agenda from Google Calendars as part of a workflow process administered using Google Apps Script I call getEventsForDay() from the CalendarApp service.
A specific (simplified) example:
var calendarView = CalendarApp.getCalendarById(ScriptProperties.getProperty("calendarID"));
var today = new Date();
var todaysEvents = calendarView.getEventsForDay(today);
This populates the array todaysEvents with all the days events fine, but also includes recurring events prior to and post where the recurrence spans the date in the query but does not occur on the day itself. (query Wed, recurring event on Mon, Tue, Fri will be returned)
We run our calendars to GMT/BST so I have looked into whether this is a function of Date() returning dates as PDT and not UTC, but on occasion events that are over 24 hours in either direction are returned.
Assuming this is not a bug, I can't work out a good way of filtering out these 'invalid' events from the returned array. Can you?
Or is this a bug?
Thanks
Jonathan,
We're figuring it out. Internally, an all day event is represented in UTC, so this will bleed over into either the previous day or the following day depending on what time zone you're in. Someone asked me a question about this a week ago, and I proposed the following workaround while we sort this out:
var startOfDay = new Date();
startOfDay.setUTCHours(0);
startOfDay.setMinutes(0);
startOfDay.setSeconds(0);
startOfDay.setMilliseconds(0);
var endOfDay = new Date(startOfDay.getTime() + 24 * 60 * 60 * 1000);
var events = CalendarApp.getDefaultCalendar().getEvents(startOfDay, endOfDay)
I realize that this isn't the best experience right now, but it should do what you need. You can abstract this into a function.