set a time interval based on current date Object (javascript) - javascript

So I am currently using the Google Calendar API, specifically the freebusy query (as seen here https://developers.google.com/google-apps/calendar/v3/reference/freebusy/query).
The request body requires a 'timeMin' and 'timeMax'. And here comes my question...
How would I set these two values dynamically based off the current datetime. Basically use the current datetime to set an interval, say an hour before now, and an hour after now.
I have seen other stackoverflow posts (Subtracting hours from date string) on how to setHours by getHours but the problem with this method seems to be that it alters the current time instead of creating a new instance.
Also I need to keep the resulting min and max datetimes in ISOstring format (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) because this is what is used in Google Calendar API request body.

I believe you're looking for something like this:
var now = new Date();
var msNow = now.getTime(); // total mil1iseconds since 1970/01/01
var timeMax = new Date(msNow + 60 * 60 * 1000); // "now" plus one hour
var timeMin = new Date(msNow - 60 * 60 * 1000); // "now" minus one hour
console.log(now);
console.log(timeMin);
console.log(timeMax);

Related

Need help subtracting time and date with Google SCRIPT

I have this code here:
var date = a.created_at_timestamp.substring(0,10)
var time = a.created_at_timestamp.substring(11,19)
And both these values return strings with these values:
date = 2020-05-19 //
Time = 17:00:08
I need to subtract 3 hours since it's coming in GMT time and I'm on GMT-3. Therefore, I thought about adding them together, subtracting three hours, and putting them apart again. Something like:
Orig Date: 20/05/19 //
Orig Time: 20:15:19
Time + Date: 20/05/19 20:15 //
Time + Date - 3h: 20/05/19 17:15
New Date: 20/05/19 00:00 //
New Time: 17:15:19
I tried converting it to milliseconds as suggested in other post here, doing with formulas, where a function would trigger formulas adding both cells, which I was able to do, but couldn't tear them apart together. In addition, if possible, I'd like to do it inside the script.
Can someone help me with that?
I'm new at this and I'm somewhat used to VBA. Tried some things from VBA, but they don't really apply here.
Instead of having separate strings for date and time, it'd likely be easier to just create a new Date object with both combined.
var dateTime = new Date(a.created_at_timestamp.substring(0,19));
You can then subtract 3 hours by doing:
var timeOffset = 3 * 60 * 60 * 1000; // 3hrs of millis
var offsetDate = new Date(dateTime.getTime() - timeOffset);

Javascript comparing current date to a timestamp

I'm using the Scala Play framework and I have a form that lets a user search for records, they can then search using today's date and a time stamp 2016-12-17T09:26:47.676Z to create a search range. Note that I mean a 24 hour period, as a single day is usually defined, and not as a difference in a date definition.
I don't have any experience with Javascript, I'd like to compare today's date with this time stamp, calculate the difference in days, and then return the amount of whole days between the two time stamps e.g if the two timestamps had 48 hours difference then it would return 2 days.
I can declare the search time stamp in the script tag on the HTML page, but I would like to know how to call today's date, do some logic to calculate the difference between the dates DaysDifference, and then call this variable in a link on the page:
<a target="_blank" href="#baseLogsUrl/#/discover?_g=(time:(from:no#DaysDifference/d,to:now))&_a=(query:(query_string:(query:'#data._id')))">
You can compute the difference between the current date and a timestamp with the Date API like this: Date.now() - Date.parse('2016-12-17T09:26:47.676Z'). This will return the difference in milliseconds, so we can divide the answer by the number of milliseconds in a day to obtain the difference in days. Summarizing:
var MS_IN_A_DAY = 1000 * 60 * 60 * 24;
var difference = Date.now() - Date.parse('2016-12-17T09:26:47.676Z');
var daysDifference = Math.floor(difference/MS_IN_A_DAY);

Why does the following code not shift the current date forward by five days in JavaScript?

I am learning the Date class in JavaScript and am trying to move the current date forward by five days with the following code:
var today = new Date();
today = today.setDate(today.getDate() + 5);
However, when I run the code I get an extremely long number. Can anyone please explain what I am doing wrong?
This should be enough:
var today = new Date();
today.setDate(today.getDate() + 5);
... as you modify object stored in today anyway with setDate method.
However, with today = in place you assign the result of setDate call to today instead - and that's the number in milliseconds, according to docs:
Date.prototype.setDate(date)
[...]
4. Let u be TimeClip(UTC(newDate)).
5. Set the [[PrimitiveValue]] internal property of this Date object to u.
6. Return u.
Apparently, that number becomes a new value of today, replacing the object stored there before.
The setDate function updates your object with the correct time. You should do
var d = new Date()
d.setDate(d.getDate() + 5);
The d object will have the current date plus five days.
Another way is to use the setTime function. This function accepts as parameter the number of milliseconds since 1969 (the "Epoch" in UNIX time). Correspondingly, the getTime function returns the current date in milliseconds since the Epoch.
To add 5 days to the current date you need to add 5 * 24 * 3600 * 1000, that is, 5 times 24 hours (3600 seconds) times 1000.
var d = new Date()
d.setTime(d.getTime() + 5 * 24 * 3600 * 1000);
Note that your object will be updated and you don't need to watch for the return of neither setTime of setDate.

How to read the correct time/duration values from Google Spreadsheet

I'm trying to get from a time formatted Cell (hh:mm:ss) the hour value, the values can be bigger 24:00:00 for example 20000:00:00 should give 20000:
Table:
if your read the Value of E1:
var total = sheet.getRange("E1").getValue();
Logger.log(total);
The result is:
Sat Apr 12 07:09:21 GMT+00:09 1902
Now I've tried to convert it to a Date object and get the Unix time stamp of it:
var date = new Date(total);
var milsec = date.getTime();
Logger.log(Utilities.formatString("%11.6f",milsec));
var hours = milsec / 1000 / 60 / 60;
Logger.log(hours)
1374127872020.000000
381702.1866722222
The question is how to get the correct value of 20000 ?
Expanding on what Serge did, I wrote some functions that should be a bit easier to read and take into account timezone differences between the spreadsheet and the script.
function getValueAsSeconds(range) {
var value = range.getValue();
// Get the date value in the spreadsheet's timezone.
var spreadsheetTimezone = range.getSheet().getParent().getSpreadsheetTimeZone();
var dateString = Utilities.formatDate(value, spreadsheetTimezone,
'EEE, d MMM yyyy HH:mm:ss');
var date = new Date(dateString);
// Initialize the date of the epoch.
var epoch = new Date('Dec 30, 1899 00:00:00');
// Calculate the number of milliseconds between the epoch and the value.
var diff = date.getTime() - epoch.getTime();
// Convert the milliseconds to seconds and return.
return Math.round(diff / 1000);
}
function getValueAsMinutes(range) {
return getValueAsSeconds(range) / 60;
}
function getValueAsHours(range) {
return getValueAsMinutes(range) / 60;
}
You can use these functions like so:
var range = SpreadsheetApp.getActiveSheet().getRange('A1');
Logger.log(getValueAsHours(range));
Needless to say, this is a lot of work to get the number of hours from a range. Please star Issue 402 which is a feature request to have the ability to get the literal string value from a cell.
There are two new functions getDisplayValue() and getDisplayValues() that returns the datetime or anything exactly the way it looks to you on a Spreadsheet. Check out the documentation here
The value you see (Sat Apr 12 07:09:21 GMT+00:09 1902) is the equivalent date in Javascript standard time that is 20000 hours later than ref date.
you should simply remove the spreadsheet reference value from your result to get what you want.
This code does the trick :
function getHours(){
var sh = SpreadsheetApp.getActiveSpreadsheet();
var cellValue = sh.getRange('E1').getValue();
var eqDate = new Date(cellValue);// this is the date object corresponding to your cell value in JS standard
Logger.log('Cell Date in JS format '+eqDate)
Logger.log('ref date in JS '+new Date(0,0,0,0,0,0));
var testOnZero = eqDate.getTime();Logger.log('Use this with a cell value = 0 to check the value to use in the next line of code '+testOnZero);
var hours = (eqDate.getTime()+ 2.2091616E12 )/3600000 ; // getTime retrieves the value in milliseconds, 2.2091616E12 is the difference between javascript ref and spreadsheet ref.
Logger.log('Value in hours with offset correction : '+hours); // show result in hours (obtained by dividing by 3600000)
}
note : this code gets only hours , if your going to have minutes and/or seconds then it should be developped to handle that too... let us know if you need it.
EDIT : a word of explanation...
Spreadsheets use a reference date of 12/30/1899 while Javascript is using 01/01/1970, that means there is a difference of 25568 days between both references. All this assuming we use the same time zone in both systems. When we convert a date value in a spreadsheet to a javascript date object the GAS engine automatically adds the difference to keep consistency between dates.
In this case we don't want to know the real date of something but rather an absolute hours value, ie a "duration", so we need to remove the 25568 day offset. This is done using the getTime() method that returns milliseconds counted from the JS reference date, the only thing we have to know is the value in milliseconds of the spreadsheet reference date and substract this value from the actual date object. Then a bit of maths to get hours instead of milliseconds and we're done.
I know this seems a bit complicated and I'm not sure my attempt to explain will really clarify the question but it's always worth trying isn't it ?
Anyway the result is what we needed as long as (as stated in the comments) one adjust the offset value according to the time zone settings of the spreadsheet. It would of course be possible to let the script handle that automatically but it would have make the script more complex, not sure it's really necessary.
For simple spreadsheets you may be able to change your spreadsheet timezone to GMT without daylight saving and use this short conversion function:
function durationToSeconds(value) {
var timezoneName = SpreadsheetApp.getActive().getSpreadsheetTimeZone();
if (timezoneName != "Etc/GMT") {
throw new Error("Timezone must be GMT to handle time durations, found " + timezoneName);
}
return (Number(value) + 2209161600000) / 1000;
}
Eric Koleda's answer is in many ways more general. I wrote this while trying to understand how it handles the corner cases with the spreadsheet timezone, browser timezone and the timezone changes in 1900 in Alaska and Stockholm.
Make a cell somewhere with a duration value of "00:00:00". This cell will be used as a reference. Could be a hidden cell, or a cell in a different sheet with config values. E.g. as below:
then write a function with two parameters - 1) value you want to process, and 2) reference value of "00:00:00". E.g.:
function gethours(val, ref) {
let dv = new Date(val)
let dr = new Date(ref)
return (dv.getTime() - dr.getTime())/(1000*60*60)
}
Since whatever Sheets are doing with the Duration type is exactly the same for both, we can now convert them to Dates and subtract, which gives correct value. In the code example above I used .getTime() which gives number of milliseconds since Jan 1, 1970, ... .
If we tried to compute what is exactly happening to the value, and make corrections, code gets too complicated.
One caveat: if the number of hours is very large say 200,000:00:00 there is substantial fractional value showing up since days/years are not exactly 24hrs/365days (? speculating here). Specifically, 200000:00:00 gives 200,000.16 as a result.

Increment a var by one every 24 hours from a specific date

I've never used Javascript before (or any other programming language) so sorry for asking this question because im sure it's very simple.
What I want to do is set a date in Javascript, then increment it by one every 24 hours. So three days after the date is set, 3 is displayed in the HTML (not the date itself). And after 100 days, 100 is displayed.
Thank you.
You have to create two date objects, one representing your initial date, and another one representing right now. Then, calculate the difference:
// Calculate days since Dec 1st 2012
var initialDate = new Date(2012, 11, 1); // Attention: month is zero-based
var now = Date.now();
var difference = now - initialDate;
var millisecondsPerDay = 24 * 60 * 60 * 1000;
var daysSince = Math.floor(difference / millisecondsPerDay);
alert(daysSince); // 80
http://jsfiddle.net/PmYFc/
If you are looking to show how many days the page has been open, you want to use the setInterval function: https://developer.mozilla.org/en-US/docs/DOM/window.setInterval.
So, if your HTML element looked like <span id='example'>0</span>, your JS might look like this:
var date = 0,
element = document.getElementById("example");
setInterval(function(){
date++;
element.innerText = date;
}, 1000 * 60 * 60 * 24); //milliseconds, seconds, minutes, hours
Though, it seems unlikely any page would sit unrefreshed for any significant length of time. If you need to persist the date variable beyond page refreshes you could look into localstorage.

Categories

Resources