How to read a time in googlespreadsheet with google apps script? - time

After hours spent to identify a rational or a solution, my hope is now with this community !
I'm desesperatly trying to get ("read") a time entered by user in a google spreasheet and to use it correctly in a google apps script for example to create google calendar event.
The desired format is "HH:mm"
My starting point is the google apps script example provided on https://developers.google.com/apps-script/quickstart/forms
From this example I modified the parameters of the spreasheet (sorry for the french!) using the "Change locale and time zone" instructions :
settings illustration
I also changed the display format of the columns 'C' and 'D' to not have the AM/PM put in the initial example:
Start Time End Time
13:00:00 14:55:00
13:00:00 14:55:00
...
To enable debug in script editor, I removed "_" at the end of setUpConference (line 14).
I launched the script "setUpConference" in debug to check the values read from the datasheet.
My surprise is to have for the first data line
Ethics for monsters 5/15/2013 13:00:00 14:55:00 Rm 323: Minotaur's Labyrinth
the corresponding data of the variable "session"
["Ethics for monsters", (new Date(1368568800000)), (new Date(-2209115361000)), (new Date(-2209108461000)), "Rm 323: Minotaur's Labyrinth"]
and sessions[2] is showned in the script editor as:
Sat Dec 30 1899 13:50:39 GMT+0100 (CET)
I understand that having only "time" (HH:mm), the date is incomplete (so the 1899 day) but how to obtain the time "13:00:00" rather than this strange "13:50:39" ?
Ps: my calendar time zone is also GMT+0100 (CET)
some edits with more information:
I share the google spreadsheet I used for test
I simplified the code of my google app script to focus on the issue (initial code was the one provided by google on https://developers.google.com/apps-script/quickstart/forms
/**
* A special function that inserts a custom menu when the spreadsheet opens.
*/
function onOpen() {
var menu = [{name: 'Set up conference', functionName: 'setUpConference'}];
SpreadsheetApp.getActive().addMenu('Conference', menu);
}
/**
* A set-up function that uses the conference data in the spreadsheet to create
* Google Calendar events, a Google Form, and a trigger that allows the script
* to react to form responses.
*/
function setUpConference() {
/* if (ScriptProperties.getProperty('calId')) {
Browser.msgBox('Your conference is already set up. Look in Google Drive!');
}*/
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName('Conference Setup');
var range = sheet.getDataRange();
var values = range.getValues();
setUpCalendar(values, range);
}
/**
* Creates a Google Calendar with events for each conference session in the
* spreadsheet, then writes the event IDs to the spreadsheet for future use.
*
* #param {String[][]} values Cell values for the spreadsheet range.
* #param {Range} range A spreadsheet range that contains conference data.
*/
function setUpCalendar(values, range) {
// comment cal for debug
//var cal = CalendarApp.createCalendar('Test Conference Calendar');
for (var i = 1; i < values.length; i++) {
var session = values[i];
var title = session[0];
Logger.log("i= "+i+" - "+ "session[2]= " + session[2] + " | session[3] =" + session[3] );
// This formats the date as Greenwich Mean Time in the format
// year-month-dateThour-minute-second.
var formattedHour = Utilities.formatDate(session[2], "GMT+1", "HH:mm");
Logger.log("formattedHour = "+formattedHour);
var start = joinDateAndTime(session[1], session[2]);
var end = joinDateAndTime(session[1], session[3]);
var options = {location: session[4], sendInvites: true};
// comment cal and event creation
/*var event = cal.createEvent(title, start, end, options)
.setGuestsCanSeeGuests(false);
session[5] = event.getId();*/
}
range.setValues(values);
}
/**
* Creates a single Date object from separate date and time cells.
*
* #param {Date} date A Date object from which to extract the date.
* #param {Date} time A Date object from which to extract the time.
* #return {Date} A Date object representing the combined date and time.
*/
function joinDateAndTime(date, time) {
date = new Date(date);
date.setHours(time.getHours());
date.setMinutes(time.getMinutes());
return date;
}

As linked in some of the comments sheets and JS use different date epochs and they don't always play nice.
change the var values = range.getValues(); to var values = range.getDisplayValues();
this will force it to grab the cells values as string.
changing your date join function as follows will make it handle the strings(may need to ensure the dates in your spread sheet to have leading zeros):
function joinDateAndTime(date, time) {
var t = new Date(date);
t.setHours(parseInt(time.substring(0, 2)));
t.setMinutes(parseInt(time.substring(3, 5)));
return t;
}

Related

Office.SeriesTime TypeScript definition is missing the Properties only has Methods

Office.context.mailbox.item.recurrence.getAsync() returns an object but I'm unable to cast parts of it to other variables.
e.g. interface Office.SeriesTime only defines the GetXXX() methods
/**
* Gets the duration in minutes of a usual instance in a recurring appointment series.
*
* [Api set: Mailbox 1.7]
*
* #remarks
*
* **{#link https://learn.microsoft.com/office/dev/add-ins/outlook/understanding-outlook-add-in-permissions | Minimum permission level}**: `ReadItem`
*
* **{#link https://learn.microsoft.com/office/dev/add-ins/outlook/outlook-add-ins-overview#extension-points | Applicable Outlook mode}**: Compose or Read
*/
getDuration(): number;
e.g. This won't compile because interface Office.SeriesTime does not define the properties.
const fixedRecurrence: Office.SeriesTime = recurrence.seriesTime;
if (fixedRecurrence.endYear === 0) {
fixedRecurrence.endYear = fixedEndDate.getFullYear();
fixedRecurrence.endMonth = fixedEndDate.getMonth() + 1;
fixedRecurrence.endDay = fixedEndDate.getDate();
}
See the Office.SeriesTime interface members. It seems you need to use the getEndDate() method instead which allows to get the end date of a recurrence pattern in the following ISO 8601 date format: "YYYY-MM-DD".
// This example gets the end date of a recurring appointment series.
Office.context.mailbox.item.recurrence.getAsync(callback);
function callback(asyncResult) {
var context = asyncResult.context;
var recurrence = asyncResult.value;
var endDate = recurrence.seriesTime.getEndDate();
}

Automatically fill the current date in a cell if the data is not empty in Google sheet

I have 9 columns of data. With the requirement in column 9 that there are data, the first column will dynamically fill in the current date.
I use the formula "= ArrayFormula (IF (ISTEXT (D7), TODAY ()," "))" but the problem is that if it passes the next day it will change to the next day's date. I do not want it to change the day after the new day, what should I do?
I am not sure if it is possible using a simple google sheet function.
If you want to use a google script to solve this then you can apply below:
function onEdit(){
dateStamp();
}
function dateStamp() {
const ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data')//change sheet name per your requirement;
const date = new Date();
const lr = ss.getDataRange().getLastRow();
const dataRange = ss.getRange(2,9,lr-1).getValues() //change range per your requirement;
const dateRange = ss.getRange(2,2,lr-1).getValues() //change range per your requirement;
for (i=0; i<dataRange.length; i++){
if(dataRange[i] !=''){
if (dateRange[i] == '')
ss.getRange(i+2,2).setValue(date);
}
}
}

Shopify Time difference

I am newbie to shopify, I have to display a time counter up-to 9 PM everyday. The logic includes to deduct current time from specified time and the difference time will display as counter(remaining time).
I am able to retrieve current timestamp in shopify using the code below
{% assign timestamp = 'now' | date %}
Now I have a date "21-03-2016 21:00:00" and wants to convert in timestamp but not able to get the solution.
Let me know if any one can help me in this. Thank You.
Note that the value will be the current time of when the page was last
generated from the template, not when the page is presented to a user
if caching or static site generation is involved.
http://shopify.github.io/liquid/filters/date/
This is probably best done using Javascript, not pure-Liquid. You generally want your pages to be as cache-able as possible for Shopify's servers to keep loading times as lean as possible.
You will want to use Liquid to compensate for timezones, however. You can get the store's configured timezone and drop that into a Javascript variable:
var timezone = {{ 1 | date: '%z' | json }};
The above liquid statement takes some arbitrary input, runs it through the date filter and outputs only the timezone component configured for that store (using '%z'), then runs that through the json filter to ensure that whatever the output will always be javascript-legal.
Now that you know your timezone offset, you can assemble your timer logic in Javascript using all your normal date/time tricks. For example:
var now = new Date();
var nowStr = now.toISOString(); // Output format: '2019-01-01T00:00'
// Chop off the time portion, then append your desired time & store timezone
var closingTimeStr = nowStr.split('T')[0] + 'T21:00' + timezone;
// We make a new date using today's date/time string
var closingTime = new Date(closingTimeStr);
// And now we can do math based on the difference
var difference_ms = closingTime - now;
if(difference_ms > 0){
// Parse the difference into hours, minutes and seconds if a positive amount of time remains. Writing a better parsing function is left as an exercise for the reader.
var hours = parseInt(difference_ms / (60 * 60 * 1000) );
difference_ms %= (60 * 60 * 1000);
var minutes = parseInt(difference_ms / (60 * 1000) );
difference_ms %= (60 * 1000);
var seconds = parseInt(difference_ms / (1000) );
console.log('Hurry down! Closing in ' + hours + ' hours, ' + minutes + ' minutes, and ' + seconds + ' seconds!');
} else {
// Show appropriate message if we're out-of-bounds
console.log('Closed for today - try again tomorrow!');
}

How can I make a CakePHP 3 time object remain consistent between AJAX and PHP?

When I load a page with a Time object and echo it out on the page through PHP, I get this:
<?= $user->last_login ?>
// 12/30/14, 5:21 pm
When I load data through ajax, it's returned to me like this:
console.log(response.user.last_login);
// 2014-12-30T17:21:31+0000
I haven't set anything different from the default CakePHP 3 setup, and I need events that are added to the page (returned via ajax) to be in the same time format as events that were pulled on page load (return via PHP).
The default output in string format for Time objects is controlled by the setToStringFormat method http://book.cakephp.org/3.0/en/core-libraries/time.html#setting-the-default-locale-and-format-string
It is a good practice to not hardcode a format there, but to only change the current locale so that the right format is selected for you,
But the format that is used to encode to json is not possible to control it via configuration as it is a standard that dates should be presented in such format when encoded in a JSON API. Instead, what you can do is alter the jsonSerialize method in your User entity:
public function jsonSerialize() {
$toEncode = parent::jsonSerialize();
return ['last_login' => (string)$this->last_login] + $toEncode;
}
What it does is converting to string the last_login property before it is encoded to json. Converting to string will then use the globally configured toString format.
You can convert the format of the date using the javascript Date object
JSFiddle
var date = new Date(response.user.last_login)
//returns a timestamp of 1419960091000
var n = date.getTime();
var day = date.getDate();
var month = date.getMonth();
month = month + 1;
//increment the month by 1 as it starts from 0
var year = date.getFullYear();
year = year.toString().substr(2,2);
//this removes the first 2 characters to give yy, remove the above line for yyyy
var hours = date.getHours();
var minutes = date.getUTCMinutes();
var period='am';
if(hours==0){ //At 00 hours we need to show 12 am
hours=12;
}
else if(hours>12){
hours=hours%12;
//remove the above line for 24 hour format
period='pm';
}
Now you can piece together the date in the required format
var last_login = day + '/' + month + '/' + year + ' ' + hours + ':' + minutes + ' ' + period;
//gives 30/12/14 5:21 pm
Hope this helps!

How to Select a Week using kendodatepicker

I an using kendodate picker in my solution.I want to retrieve the dates for full week whenever user selects some date from the kendodatepicker.e.g.lets say today is Feb 21,2014(Friday) whenever user selects some day say Feb 24,2014(Monday) then i need to retrieve its week's dates(starting and ending date).the answer should be(Feb 22,2014-Feb 28,2014)considering the fact that my week starts from Saturday(Feb 22)and ends on Friday(Feb 28).Kindly guide.i am new very much new to kendoUI.thanks
Define the change event handler as:
change : function (e) {
// Get a reference to the row (week) containing the selected date
var tr = $(".k-state-selected", cal._table).closest("tr");
// Get the first day
var first = $("td:first", tr).text();
// Get the last day
var last = $("td:last", tr).text());
}
Example here : http://jsfiddle.net/OnaBai/W9VFB/9/
If you want to have the first and last date as text, then you might use:
var first = $("td:first", tr).find("a").attr("title");
var last = $("td:last", tr).find("a").attr("title");
Example here : http://jsfiddle.net/OnaBai/W9VFB/12/

Resources