How to schedule a local notification in windows phone app 8.1 rt? - windows-phone-8

In my application i want to schedule a local notification for a particular time.
This local notification need to send when the app is closed too. (back ground Task )
I am using win RT, not silver light.
Thank you in advance.

you have yo use ScheduledToastNotification
The following example shows a toast notification scheduled to display in one hour.
var Notifications = Windows.UI.Notifications;
var currentTime = new Date();
var seconds = 60;
var dueTime = new Date(currentTime.getTime() + seconds * 60 * 1000);
var idNumber = Math.floor(Math.random() * 100000000); // Generates a unique ID number for the notification.
// Set up the notification text.
var toastXml = Notifications.ToastNotificationManager.getTemplateContent(Notifications.ToastTemplateType.toastText02);
var strings = toastXml.getElementsByTagName("text");
strings[0].appendChild(toastXml.createTextNode(This is a scheduled toast notification));
strings[1].appendChild(toastXml.createTextNode("Received: " + dueTime.toLocaleTimeString()));
// Create the toast notification object.
var toast = new Notifications.ScheduledToastNotification(toastXml, dueTime);
toast.id = "Toast" + idNumber;
// Add to the schedule.
Notifications.ToastNotificationManager.createToastNotifier().addToSchedule(toast);
you have to work with dueTime and toast id

Related

SendEmail duration / Count per week in Googlsheet AppScript

I'm sorry if this question was already asked, I tried to look for it but couldn't find it.
I'm trying to send out alert emails with app script based on a specific cell value in google sheets. To point out the value is generated by a formula not by a user.
I created the below with a trigger that runs weekly.
My challenge is, that I want to be able to set up the trigger for the script to run daily to check for the condition but only send the email one time every 7 days until the condition is no longer met.
I greatly appreciate any advice if this is possible.
function CheckSessions() {
// Fetch the sessions available
var sessionsRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Billing").getRange("K1");
var sessions = sessionsRange.getValue();
var ui = SpreadsheetApp.getUi();
// Check totals sessions
if (sessions == 1){
// Fetch the email address
var emailRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Billing").getRange("H2");
var emailAddress = emailRange.getValue();
// Send Alert Email.
var message = 'This is your Alert email!'; // Second column
var subject = 'Your Google Spreadsheet Alert';
MailApp.sendEmail(emailAddress, subject, message);
}
}
I believe you're saying you want the script to run daily, but if you've already sent the email within the past 7 days, don't send it again even if the condition is true.
One approach is to store the date for the last time you sent the reminder, and then do some date math to see if it has been 7 days since the last reminder.
You could store that date in a designated cell of the spreadsheet, but there are some good reasons not to (e.g. so a spreadsheet editor doesn't accidentally overwrite it). This is a typical use case for PropertiesService.
Properties are stored as a string, so you'll have to convert dates to/from strings.
Properties store values based on a key. If your script is only managing email alerts to one address, you can use a static key like lastSent. If you're managing alerts to multiple addresses then you could key by the email address itself. That's what I've done here:
function CheckSessions()
{
// Fetch the sessions available
var sessionsRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Billing").getRange("K1");
var sessions = sessionsRange.getValue();
// Check totals sessions
if (sessions == 1)
{
// Fetch the email address
var emailRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Billing").getRange("H2");
var emailAddress = emailRange.getValue();
// Check if we've sent to this email within 7 days
var propertyStore = PropertiesService.getScriptProperties()
var lastSent = propertyStore.getProperty(emailAddress)
if (!lastSent || getDaysDifference(new Date(lastSent), new Date()) >= 7)
{
// Send Alert Email.
var message = 'This is your Alert email!'; // Second column
var subject = 'Your Google Spreadsheet Alert';
MailApp.sendEmail(emailAddress, subject, message);
// Store the date in properties as an ISO string, to be fetched on next execution
propertyStore.setProperty(emailAddress, (new Date()).toISOString())
} else
{
console.log("Last email was sent on %s so we won't send one today", lastSent)
}
}
}
/**
* Get days elapsed between two dates
* #param {Date} startDate
* #param {Date} endDate
*/
function getDaysDifference(startDate, endDate)
{
var start = new Date(startDate);
var end = new Date(endDate);
start.setHours(0, 0, 0, 0);
end.setHours(0, 0, 0, 0);
var days = Math.round((end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24));
return days;
}
Send Email once a day
function CheckSessions() {
const ss = SpreadsheetApp.getActive()
var sessions = ss.getSheetByName("Billing").getRange("K1").getValue();
if (sessions == 1) {
var emailAddress = ss.getSheetByName("Billing").getRange("H2").getValue();
var message = 'This is your Alert email!';
var subject = 'Your Google Spreadsheet Alert';
MailApp.sendEmail(emailAddress, subject, message);
}
}
function createTrigger() {
if(ScriptApp.getProjectTriggers().filter(t => t.getHandlerFunction() == "CheckSessions").length == 0) {
ScriptApp.newTrigger("CheckSessions").timeBased().everyDays(1).atHour(2).create();//keeps you from creating more than one
}
}

Listing Google calendar events using API

I am trying to write a Google Apps script to modify calendar events so I have modified an example to list events first. When I try debugging this it reports an error that "Calendar is not defined" on the line "events = Calendar.Events.list(calendarId, options);"
I have enabled the advanced calendar API, and am basing my script on one from the Google documentation, so I assume that one worked. Is there anything else I need to do to access the relevant objects and methods?
/*
Adapted from code in https://developers.google.com/apps-script/advanced/calendar
*/
function syncColourCode() {
var calendarId = CalendarApp.getDefaultCalendar();
var properties = PropertiesService.getUserProperties();
var fullSync = properties.getProperty('fullSync'); // sync status is stored in user properties
var options = {
maxResults: 100
};
var syncToken = properties.getProperty('syncToken'); // pointer token from last sync also stored in user properties
if (syncToken && !fullSync) { // if there is a sync token from last time and sync status has not been set to full sync
options.syncToken = syncToken; // adds the current sync token to the list of sync options
} else {
// Sync events from today onwards.
options.timeMin = new Date().toISOString(); //change to new Date().toISOString() from getRelativeDate(-1, 0).toISOString()
}
// Retrieve events one page at a time.
var events;
var pageToken;
do {
try {
options.pageToken = pageToken;
events = Calendar.Events.list(calendarId, options);
} catch (e) {
Not a google-apps expert, but from reviewing the code, I see a possible problem. At no point do I see your code checking to see if getDefaultCalendar() actually returned a valid calendar ID. Later your code uses that ID under the assumption that it is good. Have you checked the value of calendarId that is returned?
Sometimes you have to read a little deeper into the message, but I always try to start with trusting the error return. In this case "Calendar is not defined" makes me question the value of calendarId.
It seem that Google made some change so that there is no Calendar reference from the AppScript API.
Anyway to get the event you may use this API:
CalendarApp.getEvents(startTime, endTime)
https://developers.google.com/apps-script/reference/calendar/calendar-app#geteventsstarttime-endtime
Below are my example function running within google sheet.
function listEventsWithinTwoMonth(){
var calendar = CalendarApp.getDefaultCalendar();
var spreadsheet = SpreadsheetApp.getActiveSheet();
var now = new Date();
var twoMonthFromNow = new Date(now.getTime() + (24 * 60 * 60 * 30 * 4 * 1000));
var events = calendar.getEvents(now, twoMonthFromNow);
if (events.length > 0) {
// Header Rows
spreadsheet.appendRow(["#่","id","StartTime","EndTime","Title","Description"]);
for (i = 0; i < events.length; i++) {
var event = events[i];
Logger.log("" + (i+1) + event.getId() +" "+ event.getStartTime()+" "+event.getEndTime()+" "+event.getTitle()+" "+event.getDescription())
spreadsheet.appendRow([(i+1),event.getId(),event.getStartTime(),event.getEndTime(),event.getTitle(),event.getDescription()]);
}
} else {
Logger.log('No upcoming events found.');
}
}
Hope this help.
CalendarApp.getDefaultCalendar() retrieves an object of the class Calendar that has multiple properties, among others an Id.
To retrieve the calendar Id, you need to define
var calendarId = CalendarApp.getDefaultCalendar().getId();

Export all events from a shared calendar, including events added by non-owners

I'm trying to extract Google Calendar event data into a spreadsheet, which works. However, the code I use only exports data which has been created by the owner of the Google Account/Calendar, not events that have been added by other users.
Below is a sample of some of the code I am using to get to the calendar and to retrieve events details.
Is there any way of achieving the above with details added by all users..?
var cal = CalendarApp.getCalendarById("name of calendar");
var events = cal.getEvents(new Date("18/08/2018 12:00 AM"), new Date("30/08/2018 12:00 AM"))
Edit:
Further to my original post, this may help..
Thanks for the replies so far... I'm not entirely sure what is going on in the code that has just been quoted, my full function is below. It may also help too if I give the practical example of what I'm trying to do.
A warehouse moves in /out a number of pallets each day. Details of these various in/outs are added as events on the "in" and "out" calendars. One calendar for each type of operation. Details are only entered into the "Title" section (e.g. PO numbers, etc.) and a time given. I had the idea of putting the number of pallets into the "Description" section so that when we extract events into a spreadsheet, we get a count of pallets in and out, each day, hour, etc.
function goodsin() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var cal = CalendarApp.getCalendarById("name of calendar");
var events = cal.getEvents(new Date("18/08/2018 12:00 AM"), new Date("30/08/2018 12:00 AM"));
for (var i = 0; i < events.length; i++) {
var title = events[i].getTitle();
var sd = events[i].getStartTime();
var ed = events[i].getEndTime();
var des = events[i].getDescription();
ss.getRange(i+2, 1).setValue(title)
ss.getRange(i+2, 2).setValue(sd);
ss.getRange(i+2, 2).setNumberFormat("dd/mm/yyyy h:mm:ss AM/PM")
ss.getRange(i+2, 3).setValue(ed);
ss.getRange(i+2, 3).setNumberFormat("dd/mm/yyyy h:mm:ss AM/PM")
ss.getRange(i+2, 4).setValue(des);
}
}
I can't reproduce your issue.
Events in "default" calendars
Using account A, I created an event on its default calendar, and invited account B. Account B has not accepted the invitation.
From account B, if I run the following code, I get the event information in my Stackdriver logs:
function getNextEvent_(calendars) {
if (!calendars)
calendars = CalendarApp.getAllCalendars();
const now = new Date();
const end = new Date();
return calendars.map(function (cal) {
var weeks = 4;
end.setTime(now.getTime());
do {
end.setDate(end.getDate() + 7)
var e = cal.getEvents(now, end, {max: 1}).pop();
} while (!e && --weeks);
return cal.getName() + ': ' +
(!e
? 'No visible events up to ' + end.toLocaleString()
: e.getTitle() + ' (Org. by ' + e.getCreators().join(',') + ')'
);
});
}
function logNextEvents() {
console.log({
message: "Upcoming Events",
events: getNextEvent_()
});
}
If I dig deeper, the event is found for the default calendar of Account B, i.e. CalendarApp.getDefaultCalendar().getEvents(...) contains the event owned and organized by Account A.
Events in a shared calendar
Setup:
Account A makes a new Google Calendar.
Account B is added with the permission to make changes to events.
Account C is added with the permission to make changes to events.
All accounts create an event on the calendar (3 events created).
Code:
function querySharedCal() {
const id = 'notarealgroupid#group.calendar.google.com';
const cal = CalendarApp.getCalendarById(id);
if (!cal) throw new Error("no calendar");
const now = new Date();
const end = new Date();
end.setDate(end.getDate() + 4);
const events = cal.getEvents(now, end).map(function (e) {
return cal.getName() + ': ' + e.getTitle() +
' (Org. by ' + e.getCreators().join(',') + ')';
});
console.log({message:"search result by " + Session.getTemporaryActiveUserKey(), events: events});
}
Cases:
Account A runs the above code
Account B runs the above code
Account C runs the above code
Results:
All cases return the 3 events. Even if each of the accounts a, b, c writes their own code (rather than having a single project which each can execute), all queries are successful.
Perhaps there is something you aren't sharing with us regarding the permission levels of the calendar, the accounts that create the events, the event visibilities, and the account from which you perform the queries.

Google Apps Script - Creating Calendar Events with Appointment Color

So I have a script that creates calendar events just fine, I am now trying to have the appointment color red without success. What is the best way to do this? Here is a portion of the code that I am currently using.
Here is the revised code that is now working!
function createCalendarEvent(eventObject) {
//Get a calendar object by opening the calendar using the
//calendar id stored in the GLOBAL variable object
//var startTime = eventObject.startDate+" "+eventObject.startTime
//var endTime = eventObject.endDate+" "+eventObject.endTime
var calendar = CalendarApp.getCalendarById(GLOBAL.calendarId),
//The title for the event that will be created
title = eventObject.eventTitle,
//The start time and date of the event that will be created
startTime1 = moment(eventObject.startDate+" "+eventObject.startTime).toDate(),
//The end time and date of the event that will be created ---moved up
APLength = eventObject.AppLength1;
//an options object containing the description and guest list
//for the event that will be created
var comboDescription = title+" in "+ eventObject.county +" is interested in a "+eventObject.deckStyle+". The referral source was "+eventObject.referral+". "+" Their email address is "+eventObject.Cemail+"."+" They can be reached at "+eventObject.phone1+" "+eventObject.phone2+" "+eventObject.Gdescription+" "+eventObject.Qdescription;
var options = {
description : comboDescription,
guests: eventObject.Cemail,
location: eventObject.location,
};
if(APLength=="1 hour") {var endTime1 = moment(eventObject.startDate+" "+eventObject.startTime).add(1, 'h').toDate()};
if(APLength=="2 hour") {var endTime1 = moment(eventObject.startDate+" "+eventObject.startTime).add(2, 'h').toDate()};
//////Send a reminder email
//MailApp.sendEmail ("-----------", "New Appointment with "+title, "I have added the following information to your calender. The appointment range is "+moment(startTime1).format("dddd, MMM Do YYYY, h:mm:ss a")+" till "+ moment(endTime1).format("dddd, MMM Do YYYY, h:mm:ss a")+" See the following appointment details....."+comboDescription);
try {
//create a calendar event with given title, start time,
//end time, and description and guests stored in an
//options argument
//calendarEvent.setColor(11);
//eventObject.colorId: 11
var event = calendar.createEvent(title, startTime1, endTime1, options)
event.setColor("11")
//var event = Calendar.Events.insert(title, startTime1, endTime1, options)
//CalendarApp.event.setColor("10")
} catch (e) {
//delete the guest property from the options variable,
//as an invalid email address with cause this method to
//throw an error.
delete options.guests
//create the event without including the guest
//var eventObject.colorId = 11
//var event = calendar.createEvent(title, startTime1, endTime1, options)
var event = calendar.createEvent(title, startTime1, endTime1, options)
event.setColor("11")
//CalendarApp.event.setColor("10")
//var event = calendarEvent.setColor(11);
//colorId: Red
}
return event;
}
Does calendarEvent.setColor not work for you?
https://developers.google.com/apps-script/reference/calendar/calendar-event#setColor(String)
In your code above, have you tried adding:
event.setColor(CalendarEvent.EventColor.RED)?

How to use timeZone of calendar to set timeZone for date object

I want to use the calendar timezone to set the time zone of a date object. I'm looking for the proper technique. We have several bases around the nation, and each has their own calendar for journal and daily activities. We have multiple scripts that post to the calendars. I want to use the timezone of the calendar to set the date Object timezone, because the users travel around to different bases, and their computers might not be set to the correct time zone. We want to avoid incorrect time settings.
Should the script's timeZone be set to UTC?
This is where I'm currently at:
function submitUiTest(e) {
var app = UiApp.getActiveApplication();
var cal = CalendarApp.getCalendarById('calendarId');
var timeZone = cal.getTimeZone();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1');
var startTime = e.parameter.startDate
startTime.setHours(e.parameter.startHour, e.parameter.startMin, 0)
startTime = formatTime(startTime, timeZone);
Logger.log(startTime)
var endTime = e.parameter.endDate
endTime.setHours(e.parameter.endHour, e.parameter.endMin, 0);
endTime = formatTime(endTime, timeZone);
Logger.log(endTime)
cal.createEvent('TimeZone Test', new Date(startTime), new Date(endTime));
ss.appendRow([startTime, endTime]);
return app;
}
function formatTime(time, timeZone){
return Utilities.formatDate(time, (timeZone-time.getTimezoneOffset()), 'M/d/yyyy HH:mm');
}
Edit:
Currently there are 3 calendars, they are not user calendars, just each a separate calendar created for individual Air Stations. The air stations are each in separate time zone's. As crew members work at these stations they post daily activities to the calendars, and there are also several Ui scripts we have that post to the same calendars ex. a flight log. When an entry to a calendar is posted to any calendar, the time relates only to the timezone set on the script, not the timezone on the calendar. When the date or timestamp object is created, how can I use the timeZone that the calendar itself is set to.
What is best practice for scripts that record dates for different time zones?
Set the script timezone to UTC and do the conversion?
What do you use to get the user's timezone or in this case, I don't care what the user's timezone is set too, I need to use the timezone of the calendar.
Here is a modified version of the answer, without the UI stuff:
function gasTimezoneOffset(date, hour){
var cal,calTimeZone,calTz,date,dateString,scriptTimeZone,sessionTz;
var testMonth = "March",
testDayOfMnth = "26",
testYr = "2016",
hour = "10:00",
timeZoneDiff = 0;
Logger.log("Script Time Zone: " + Session.getScriptTimeZone());
dateString = testMonth + " " + testDayOfMnth + ", " + testYr;
Logger.log("dateString: " + dateString);
date = new Date(dateString);
cal = CalendarApp.getDefaultCalendar();
calTimeZone = cal.getTimeZone();
calTimeZone = Utilities.formatDate(date, calTimeZone, 'Z');
scriptTimeZone = Utilities.formatDate(date, Session.getTimeZone(), 'Z');
calTz = Number(calTimeZone.slice(0,3));
sessionTz = Number(scriptTimeZone.slice(0,3));
//If both time zones are the same sign, get the difference between the
//two. E.g. -4 and -2. Difference is 2
//if each time zone is a different sign, add the absolute values together.
//-4 and +1 should be 5
if (calTz < 0 && sessionTz > 0 || calTz > 0 && sessionTz < 0){
timeZoneDiff = Math.abs(Math.abs(calTz) + Math.abs(sessionTz));
} else {
timeZoneDiff = Math.abs(Math.abs(calTz) - Math.abs(sessionTz));
};
hour = Number(hour.slice(0,2));
return hour + timeZoneDiff;
};
EDIT : I wrote a small test UI and ran it with 2 calendars in 2 different timezones.
Calendar events are created in the Calendar timezone and the user interface shows user values. Google takes care of timezone settings in both calendars and I didn't notice any anomalies : events where created as I wanted to, ie at the time shown in the UI in the calendar Timezone.
(screen capture)
Here is the code I used for testing :
var tz = [['test_agenda(pacific Time)','test_agenda'],['testencodage(Belgium time)','testencodage']]
function doGet() {
var app = UiApp.createApplication().setStyleAttribute('padding','15PX');
var hpanel = app.createHorizontalPanel();
var dateBox = app.createDateBox().setId('dateBox').setName('dateBox');
var hour = app.createListBox(false).setId('hour').setName('hour')
for(h=0;h<25;++h){
if(h/2==parseInt(h/2)){hour.addItem(parseInt(h/2)+':00')
}else{
hour.addItem(parseInt(h/2)+':30')
}
}
var amPm = app.createListBox(false).setId('am').setName('amPm')
.addItem('AM').addItem('PM');
var dateTimeLabel = app.createLabel('',false).setId('dateTimeLabel');
var submit = app.createButton('Submit').setId('submit');
var tzList = app.createListBox().setName('tzList');
for(var c in tz){tzList.addItem(tz[c][0],tz[c][1])}
var handler1 = app.createClientHandler().validateMatches(dateBox, '2','g').forEventSource().setEnabled(false);
var handler2 = app.createServerHandler('createE').validateMatches(dateBox, '2','g').addCallbackElement(hpanel).addCallbackElement(tzList);
submit.addClickHandler(handler1).addClickHandler(handler2);
hpanel.add(dateBox).add(hour).add(amPm)
app.add(hpanel);
app.add(tzList).add(submit);
app.add(dateTimeLabel);
return app;
}
function createE(e) {
var app = UiApp.getActiveApplication();
var date = e.parameter.dateBox;
var cal = CalendarApp.getCalendarsByName(e.parameter.tzList)[0]
var timeZone = cal.getTimeZone();
var sessionTz = Session.getTimeZone()
Logger.log(sessionTz)
Logger.log(timeZone)
var hour = Number(e.parameter.hour.split(':')[0]);
var min = Number(e.parameter.hour.split(':')[1]);
var amPm = e.parameter.amPm;
if (amPm == 'PM' ){hour = hour+12}; // ADD 12 HOURS TO PM HOURS, EXCEPT 12PM
if (hour == 24){hour = 0;amPm='AM'}; // HANDLE 12AM HOUR CORRECTLY
var newDate=new Date(date)
newDate.setHours(hour,min,0,0)
Logger.log('start : '+newDate)
var newDateString = Utilities.formatDate(newDate, sessionTz, 'MM/dd/yyyy hh:mm aaa');
app.getElementById('dateTimeLabel').setText('tz = '+timeZone+' - '+newDateString);
Logger.log('end : '+new Date(newDate.getTime()+3600000))
cal.createEvent('test Event in TZ '+timeZone, newDate, new Date(newDate.getTime()+3600000))
app.getElementById('submit').setEnabled(true);
return app;
}
first comment :
I began to write a comment to ask you some questions but it was getting too long... so please consider this as a comment, not an answer ;-).
I'm not sure I understand what you say about 'their computer not being set to the right timezone' the timezone of their computer is not relevant if they use Google Calendar, it is only a matter of parameter in Google Cal. If I understood your goal is that if the script sets an appointment at 8:00 AM they will see it shown at 8:00 AM in their Calendar wherever they are (8:00 AM in their 'local' timezone), right ?
So to summarize, you are running this script from one place and creating events for people in other timezones in their own calendars ? And are the users moving across different timezones ? These are 2 separate questions and it doesn't have one single solution.
If a single user is moving across timezones all the events will be shifted unless he doesn't change his GCal parameters. But if he does so he won't be notified at the right time and the Calendar interface will be out of time... so that's not a reasonable solution.
My last question : when you create an event in another calendar (in another tz) can it be an appointment between you and this person ? in other words is the absolute time of any importance for you use case ?
Ok here is a solution to the problem. I've probably went way out of my way or missed something simple but this finally works like I was hoping. Feel free to critique. I set the webapp timezone to GMT-0000 just for simplicity.
function uiTest() {
var app = UiApp.createApplication();
var startDate = app.createDateBox().setName('startDate').setId('startDate').setWidth('75');
var startHour = app.createListBox().setName('startHour').setId('startHour').setWidth('45');
var startMin = app.createListBox().setName('startMin').setId('startMin').setWidth('45');
var endDate = app.createDateBox().setName('endDate').setId('endDate').setWidth('75');
var endHour = app.createListBox().setName('endHour').setId('endHour').setWidth('45');
var endMin = app.createListBox().setName('endMin').setId('endMin').setWidth('45');
for (h=0;h<24;++h){
if(h<10){
var hourstr='0'+h
}else{
var hourstr=h.toString()
}
startHour.addItem(hourstr)
endHour.addItem(hourstr)
}
for (m=0;m<60;++m){
if(m<10){
var minstr='0'+m
}else{
var minstr=m.toString()
}
startMin.addItem(minstr)
endMin.addItem(minstr)
}
var grid = app.createFlexTable().setId('grid');
app.add(grid);
grid.setWidget(0, 0, app.createLabel('Start Date'));
grid.setWidget(1, 0, startDate);
grid.setWidget(0, 1, app.createLabel('Hour'));
grid.setWidget(1, 1, startHour);
grid.setWidget(0, 2, app.createLabel('Min'));
grid.setWidget(1, 2, startMin);
grid.setWidget(2, 0, app.createLabel('End Date'));
grid.setWidget(3, 0, endDate);
grid.setWidget(2, 1, app.createLabel('Hour'));
grid.setWidget(3, 1, endHour);
grid.setWidget(2, 2, app.createLabel('Min'));
grid.setWidget(3, 2, endMin);
app.add(app.createButton('Submit', app.createServerHandler('submitUiTest').addCallbackElement(grid)));
SpreadsheetApp.getActiveSpreadsheet().show(app);
}
function submitUiTest(e) {
var app = UiApp.getActiveApplication();
var cal = CalendarApp.getCalendarById('');//Info Sys Calendar set to Central Time
//var cal = CalendarApp.getCalendarById('');//Fort Bliss (Mountain Time)
var calTimeZone = cal.getTimeZone();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1');
var startTime = e.parameter.startDate
startTime.setHours(gasTimezoneOffset(startTime, e.parameter.startHour, calTimeZone), e.parameter.startMin, 0);
Logger.log('startTime: '+Utilities.formatDate(startTime, calTimeZone, 'M/d/yyyy HH:mm z'));
var endTime = e.parameter.endDate
endTime.setHours(gasTimezoneOffset(endTime, e.parameter.endHour, calTimeZone), e.parameter.endMin, 0);
Logger.log('endTime: '+endTime)
var timeStamp = Utilities.formatDate(startTime, calTimeZone, 'M/d/yyyy HH:mm z');
cal.createEvent(timeStamp, new Date(startTime), new Date(endTime));
ss.appendRow([startTime, endTime]);
return app;
}
function gasTimezoneOffset(date, hour, calTimeZone){
var calTz = new Number(Utilities.formatDate(date, calTimeZone, 'Z').substr(1,2));
var sessionTz = new Number(Utilities.formatDate(date, Session.getTimeZone(), 'Z').substr(1,2));
switch (Utilities.formatDate(date, calTimeZone, 'Z').substring(0,1)){
case '+':
var timeZoneOffset = sessionTz - calTz;
break;
case '-':
var timeZoneOffset = sessionTz + calTz;
break;
}
hour = new Number(hour);
return hour + timeZoneOffset;
}
Here's the version of Sandy's code that I ended up using to create a function that takes the Calendar object and the "script time" and returns the "calendar time":
/**
* Given a script date object, return the time in the user's calendar
*
* Sandy Good's answer to this SO question:
*
* http://stackoverflow.com/questions/15645343/how-to-use-timezone-of-calendar-to-set-timezone-for-date-object
*
* #param {Date} scriptDateTime
* #param {Calendar} calendar
*
* #return {Date} calendarDateTime
*/
function getCalendarDateTime (scriptDateTime, calendar) {
Logger.log('scriptDateTime: ' + scriptDateTime)
var calendarTimeZoneString = calendar.getTimeZone()
var calendarTimeZone = Utilities.formatDate(scriptDateTime, calendarTimeZoneString, 'Z')
var calendarTz = Number(calendarTimeZone.slice(0,3))
Logger.log('calendarTimeZone: %s (%s)', calendarTimeZoneString, calendarTz)
var scriptTimeZoneString = Session.getScriptTimeZone()
var scriptTimeZone = Utilities.formatDate(scriptDateTime, scriptTimeZoneString, 'Z')
var sessionTz = Number(scriptTimeZone.slice(0,3))
Logger.log('scriptTimeZone: %s (%s)', scriptTimeZoneString, sessionTz)
// If both time zones are the same sign, get the difference between the
// two. E.g. -4 and -2. Difference is 2
//
// If each time zone is a different sign, add the absolute values together.
// -4 and +1 should be 5
var timeZoneDiff
if (calendarTz < 0 && sessionTz > 0 || calendarTz > 0 && sessionTz < 0) {
timeZoneDiff = Math.abs(Math.abs(calendarTz) + Math.abs(sessionTz))
} else {
timeZoneDiff = Math.abs(Math.abs(calendarTz) - Math.abs(sessionTz))
}
Logger.log('timeZoneDiff: ' + timeZoneDiff)
var scriptHour = scriptDateTime.getHours()
var calendarHour = scriptHour + timeZoneDiff
var calendarDateTime = new Date(
scriptDateTime.getYear(),
scriptDateTime.getMonth(),
scriptDateTime.getDate(),
calendarHour,
scriptDateTime.getMinutes())
Logger.log('calendarDateTime: ' + calendarDateTime)
return calendarDateTime
}
// Script is PST (GMT-8) and calendar is GMT
function test_getCalendarDateTime() {
var calendar = CalendarApp.getDefaultCalendar()
var scriptDateTime = new Date(2017, 0, 30, 12, 0) // 2017-01-30 12:00 PST
var calendarDateTime = getCalendarDateTime(scriptDateTime, calendar) // 2017-01-30 20:00 PST
}
Could try deploying a separate web app for each time zone. Set the time zone of each app to match that of the unique calendar they are linked to. Since you only have 3 calendars in different time zones, seems like it would work for your case.