I have a time span between two epoch times (in seconds). I want a function that returns the epoch times (in seconds) of all midnights within that time span.
In pseudocode I would want something like this:
const epoch_start = 1600000;
const epoch_end = 16040000;
function getMidnights(start, end){
// do your magic
}
console.log(getMidnights(epoch_start, epoch_end));
I would expect the return of that function to look like this: [1600020, 1600400] (these are just example values).
What would be the most efficient way to do this?
My ideas were: get unique list of days within range and return their midnight.
You might step by day rounding by day:
const epoch_start = 1600000000;
const epoch_end = 1600400000;
const day = 86400;
function getMidnights(start, end){
midnites = [];
while (start < end) {
midnites.push((start/day + .5|0)*day);
start += day;
}
return midnites;
}
console.log(getMidnights(epoch_start, epoch_end))
console.log('* check it *')
console.log(getMidnights(epoch_start, epoch_end).map(t => new Date(t*1e3)));
I am using a counter library that will count down the amount of time allowed for user for reading a book section, that library will accept a milliseconds value to work.
Now i have function for getting the allowed time from api which contain the following code :-
// api request -> var data.created_at = contain the section read request created_at date/time.
var readAllowedurationInHr = 2;
var readAllowedDurationInDay = null;
var createdAt = new Date(data.created_at);
if (readAllowedDurationInDay) {
createdAt.setDate(createdAt.getDate() + readAllowedDurationInDay);
var diffInMilliseconds = createdAt.getTime() - Date.now();
}
if (readAllowedurationInHr) {
createdAt.setDate(createdAt.getHours() + readAllowedurationInHr);
var now = new Date();
var diffInMilliseconds = createdAt.getTime() - now.getTime();
}
setCounterValue(diffInMilliseconds);
The code for getting the days difference "if (readAllowedDurationInDay)" is working, but for handling the hour difference "if (readAllowedurationInHr)" it show in the counter a count down starting from 16 days.
How can i get the difference in hours between dates in millisecond unit ?
I have a script in a Google Sheet that is sending out an alert if a certain condition is met. I want to trigger the script to run hourly, however, if an alert was already sent out today, I don't want to send out another one (only the next day). What is the best way to achieve this?
I've tried formatting the date several ways, but somehow the only thing working for me so far is getting the year, month and day from the date object as int and comparing them separately.
function sendAlert{
var now = new Date();
var yearNow = now.getYear();
var monthNow = now.getMonth() + 1;
var dayNow = now.getDate();
var sheet = SpreadsheetApp.getActive().getSheetByName('CHANGE_ALERT');
var sentYear = sheet.getRange("R2").getValue();
var sentMonth = sheet.getRange("S2").getValue();
var sentDay = sheet.getRange("T2").getValue();
if (yearNow != sentYear || monthNow != sentMonth || dayNow != sentDay) {
sendEmail();
var sentYear = sheet.getRange("R2").setValue(yearNow);
var sentMonth = sheet.getRange("S2").setValue(monthNow);
var sentDay = sheet.getRange("T2").setValue(dayNow);
else {
Logger.log('Alert was already sent today.');
}
}
I think this solution is definitely not the best approach, but I cannot come up with another that merges the date into one. Only comparing the new Date() doesn't work, since the time of day will not necessarily be the same. If I format the date to YYYY-MM-dd, it should work, but then when I get the date again from the spreadsheet it gets it as a full date with the time again.
Requirement:
Compare dates and send an email if one hasn't been sent already today.
Modified Code:
function sendAlert() {
var sheet = SpreadsheetApp.getActive().getSheetByName('blank');
var cell = sheet.getRange(2,18); //cell R2
var date = new Date();
var alertDate = Utilities.formatDate(cell.getValue(), "GMT+0", "yyyy-MM-dd");
var currentDate = Utilities.formatDate(date, "GMT+0", "yyyy-MM-dd");
if (alertDate !== currentDate) {
sendEmail();
cell.setValue(date);
} else {
Logger.log('Alert was already sent today.');
}
}
As you can see, I've removed all of your year/month/day code and replaced it with Utilities.formatDate(), this allows you to compare the dates in the format you specified in your question. I've also changed the if statement to match this, so now we only need to compare alertDate and currentDate.
References:
Utilities.formatDate()
Class SimpleDateFormat
Am doing a script in which have need of know if the store is open or closed, depending on the time local. Currently, I get the data of an api, which I keep in my database and call it via an Ajax request. The data that return are (equal that which I get):
["Mo-Sa 11:00-14:30", "Mo-Th 17:00-21:30", "Fr-Sa 17:00-22:00"]
I have been assessing the possibility of converting it as well (I still have to see how to do it):
{
"monday": ["11:00-14:30", "17:00-21:30"],
"tuesday": ["11:00-14:30", "17:00-21:30"],
"wednesday": ["11:00-14:30", "17:00-21:30"],
"thursday": ["11:00-14:30", "17:00-21:30"],
"friday": ["11:00-14:30", "17:00-22:00"],
"saturday": ["11:00-14:30", "17:00-22:00"],
"sunday": null
}
I've seen examples in these questions:
Create a function to check if a business is open and write text to html
Determine If Business Is Open/Closed Based On Business Hours (php)
Before programming code with any routine for this, I want to know if anyone knows any way to make it simple or has seen some portion of code on the web; to not reinvent the wheel. Thanks a lot.
Best regards
With opening times, I prefer to convert all values to be compared to full minutes (hour*60 + minutes). That way it's easier to compare to actual times.
Having minutes as starting point, I would do the conversion somewhat different by using an array for each weekday (with the same index as returned by Date.getDay() ), with each day containing sub-arrays with the open start-end times in minutes (start and end also in sub arrays, or in an object)
const arr= ["Mo-Sa 11:00-14:30", "Mo-Th 17:00-21:30", "Fr-Sa 17:00-22:00"],
days = ['Su','Mo','Tu','We', 'Th', 'Fr', 'Sa'], //start with sunday to be compatible with Date.getDay
times = Array.from(days, (d,i) => []),
getDay = (s,i) => days.indexOf(s.slice(i,i+2)), //helper function for parsing day name
getMinutes = s => s.split(':').reduce((m, n) => m * 60 + parseInt(n,10),0); //helper to store time in minutes of day
//convert to new format
for(let s of arr){
let d = getDay(s,0), end = getDay(s,3);
while(true){
times[d].push( s.slice(6).split('-').map(getMinutes));
if(d===end)break;
d = ++d % 7; //the %7 makes it possible to have ranges as Th-Mo
}
}
//now times contains an array with a day in each index, containing subarrays of the opening times in minutes
function isOpen(dt){
let mins = dt.getHours() * 60 + dt.getMinutes();
return times[dt.getDay()].some(a=>a[0] <= mins && a[1] >= mins)
}
//----------------------------------------------------------
//test functions only
console.log('Is open now: ' , isOpen(new Date()));
function test(dts){let dt = new Date(dts); console.log(days[dt.getDay()], dts,':', isOpen(dt));}
test('2016/12/29 8:00'); //th
test('2016/12/29 10:59');
test('2016/12/29 11:00');
test('2016/12/29 12:00');
test('2016/12/30 12:00'); //fr
test('2017/1/1 12:00'); //su
test('2016/12/29 21:45'); //th
test('2016/12/30 21:45'); //fr
var dates=yourdateobj;
//its easier to work with numbers then string for example (1-3 is easier then mo-wed)
var daytoindex={"Mo":1,"Tu":2,"Wed":3,"Thu":4,"Fr":5,"Sat":6,"Sun":7};
//the better structured table:
var destructdates=[];
//for each old timestring:
dates.forEach((e,i)=>{
//destructure timestring
e=e.split(" ");
var days=e[0].split("-");
var hours=e[1];
//add time to all days inbetween (1-3 (Mo-Wed) is 1,2,3 (Mo,Tue;Wed)
for(var i=daytoindex[days[0]];i<=daytoindex[days[1]];i++){
//the day is an array,add the open hours
destructdates[i]=destructdates[i]||[];
destructdates[i].push(hours);
}
});
That creates your second object ( similar):
destructdates:
[
1:["12:33-15:44","12:33-0:30"] //Mo
2:...
]
Now you can do this:
function open(day,hour,second){
//get the todays times Array
var dayhours=destructdates[daytoindex[day]];
//if now falls into one of the times:
return dayhours.some((e,i)=>{
//destructure the times:
e=e.split("-");
var start=e[0].split(":");
var starthour= +start[0];
var startminute= +start[1];
var end=e[1].split(":");
var endhour= +end[0];
var endminute= +end[1];
//check:
if(starthour<=hour && startminute<=minute && endhour>=hour &&endminute>=minute){
return true;
}
return false;
});
}
Use like this:
alert(open("Tu",12,33)?"Open":"Close");
Problems/TODO ( i dont do all of your work):
Sunday-Friday wont work, the for loop will fail.
You need to convert the todays date into the open arguments somehow.
I am working on programming a page in JS that grabs calendar data from an outside source, imports it into a multidimensional array and uses it to display who is currently working along with their photo, phone number, etc.
Right now I have it set up so that the page reloads every 15 minutes. I'd prefer to have this all done dynamically so that when, say, the clock strikes 5pm the page knows to update without having to wait until the 15 minute refresh is triggered.
All of the work times are pulled from the other calendar in 24 hour format (so 5pm is 1700).
Here's how I'm generating the current time to compare with the start/end times in the calendar:
//Get the current date and time
var dateTime = new Date();
var month = dateTime.getMonth() + 1;
var day = dateTime.getDate();
var dayOfWeek = dateTime.getDay();
var year = dateTime.getYear() + 1900;
//converting hours and minutes to strings to form the 24h time
var hours = dateTime.getHours().toString();
if (hours.length === 1) {
var hours = '0' + hours
};
var minutes = dateTime.getMinutes().toString();
if (minutes.length === 1) {
var minutes = '0' + minutes
};
var time = hours + minutes;
//convert the 24h time into a number to read from later
var timeNumber = parseInt(time);
I then use if statements to compare the start/end times from the imported schedule with timeNumber to determine who is currently working and push that to an array that is eventually displayed on the page with this code:
//figure out who is currently working and put them in the workingNow array
var workingNow = [];
for (i = 0; i < workingToday.length; i++){
//convert time strings to numbers to compare
var startTime = parseInt(workingToday[i][7]);
var endTime = parseInt(workingToday[i][8]);
//compare start and end times with the current time and add those who are working to the new list
if(startTime < timeNumber && timeNumber < endTime){
workingNow.push(workingToday[i]);
}
};
I guess I have just been trying to figure out how to make this comparison of the data in an array with the current time something that is dynamic. Is this possible or would I need to go about this in a completely different way from the ground up?
You should have a look at momentjs. This is a really good library to handle all sort of time and date manipulation.
http://momentjs.com/