Get remaining time with an array for opening hours - javascript

I'm trying to create a countdown to get the remaining time before my shop will close
// My array for the opening hours :
var openTime = [
{ open : 9, close : 17},
{ open: 9, close : 18 },
{ open: 9, close : 18 },
{ open: 9, close : 18 },
{ open: 9, close : 18 },
{ open: 9, close : 18 },
{ open: 10, close : 16.5 }
]
var current = new Date();
var day = current.getDay();
var currentTime = current.getHours() + (current.getMinutes() / 60);
var remainTime = 0;
if (openTime[day].open >= 0 && openTime[day].open < currentTime && openTime[day].close >
currentTime) {
remainTime = (openTime[day].close - currentTime).toFixed(2)
}
console.log("the shop will close in %s hours", remainTime);
But I have a problem with this line :
var currentTime = current.getHours() + (current.getMinutes()/60);
Because when I execute the code, for exemple, actually it's 17h22, the code give me on my debugger that current time equal to 17.36 ?
There is something wrong with the line, because it's give me the wrong remaining time...

0.36 of an hour (a decimal magnitude) equals 21.6 (≈22) minutes.
It's simple to convert decimal to minutes: 60*decimal. Or (60*decimal).toFixed(0) or (60*decimal).round() if you want a round number.
Also, remember that JS uses the device's time. Today most devices sync their time, but if you don't want to rely on it, you should bring the time from your server (ie. storing it in a JS variable at preprocessing time, like var time=<?=time()?>;).

If you want current time as string you have to:
var currentTime = current.getHours() + ":" + (current.getMinutes() / 60);
but thats not what you want I guess. You get of coures 17.36 because 17:22 converted to decimal base 10 instead of 60 minutes gives this value (22 min /60 =0.363636 rounded two digits 0.36). If you want to have the timer working you convert either back the decimal part by *60 to easy find it. Use:
var decimalPart = remainTime % 1;
var remainTimeHours = remainTime - decimalPart;
var remainTimeMin = decimalPart * 60;
Of course you can simplify it - just to show the logic
-in your closing time you use already 16.5 means 16:30 or should it be 16:50 -> then 16.83
or preferred seperate logic for hours and minutes not converted to decimal using even seconds if needed.

Related

Run a function at time increments of 3 minutes - JS

I want to run a function at specific time points in a particular timeframe, say from 5:30 to 14:30. The specific time points would be increments of 3 minutes from 5:30 like so, 5:30, 5:33, 5:36,...,6:00 etc until 14:30. I thought the logic would be as simple as checking if the current time in integer format was a multiple of 3 and checking if the "seconds" in the current time was "00", since I want to run it only at the beginning of these specific time points. But this logic is incorrect. Since a lot of time points such as 10:00, 11:00, 13:00, 14:00 etc are not divisible by 3. Also, the browser freezes because of the while loop. How do I go about this and what is the correct logic here?
myFunc = () => {
//Some Task
};
myFunc();
var dateToday = Date();
while (Number(dateToday.getHours()+(dateToday.getMinutes()<10?'0':'') + dateToday.getMinutes())) >= 530 && Number(dateToday.getHours()+(dateToday.getMinutes()<10?'0':'') + dateToday.getMinutes()) <= 1430){
var dateTodayCheck = new Date(),
hoursCheck = dateTodayCheck.getHours(),
minutesCheck = (dateTodayCheck.getMinutes()<10?'0':'')
+ dateTodayCheck.getMinutes(),
secondsCheck = (dateTodayCheck.getSeconds()<10?'0':'')
+ dateTodayCheck.getSeconds();
var timeNowCheck = Number(hoursCheck+minutesCheck)
var remainder = timeNowCheck % 3
if (remainder === 0 && secondsCheck==="00") {
myFunc();
};
};
Okay, I got it to work for me. I came up with new logic. I hard-coded the minutes, I wanted the function to run at, ex: [0, 3, 6, 9, 12, 15,....,60]. Now say the current time is 6:35:15 the "minutes" part of the current time would be 35, so I checked for the number from my array that was closest to 35, which would be 36 (Found the code for this online). Then I took the difference between the closest value and the "minutes" part of the current time, in this case, 36 - 35 = 1 (1 minute). Later I accounted for the seconds, so 1 min - 15 seconds = 45 seconds. Finally, passed 45 seconds into a Timeout Function which contains an Interval Function that calls myFunc() every 3 minutes. This way if I open the app at 6:35:15, the program would know to wait for 45 seconds and call myFunc() at 6:36, and every 3 minutes from that point.
var dateToday = new Date(),
hours = dateToday.getHours(),
minutes = (dateToday.getMinutes()<10?'0':'') + dateToday.getMinutes(),
seconds = (dateToday.getSeconds()<10?'0':'') + dateToday.getSeconds();
var timeNow = hours+minutes
if(Number(timeNow) >= 530 && Number(timeNow) <= 1430){
const closest = [0, 3, 6, 9, 12, 15, 18, 21, 24,
27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57,
60].reduce((a, b) => {
let aDiff = Math.abs(a - Number(minutes));
let bDiff = Math.abs(b - Number(minutes));
if (aDiff === bDiff) {
return a > b ? a : b;
} else {
return bDiff < aDiff ? b : a;
};
});
var difference = closest - Number(minutes)
var timeoutTime = difference === -1 ? 2 : difference
var timeoutTimeCorrected = (timeoutTime * 1000 * 60) - (Number(seconds) * 1000)
setTimeout(() => {
myFunc();
setInterval(() => {
myFunc();
}, 180000);
},timeoutTimeCorrected);
};
Please let me know, if there is a more elegant way to do this.

Count down and reset count with javascript

I want to show a countdown on my website. for all users but I don't want to use any backend language.
Countdown is starting from 20 and after each 1min I am decreasing number by 1. Means after 2mins the value will be 18 and when it reachs at 3 the number should reset to 20. I use the time difference to do that it count down correctly but reseting is not working. I have two functions
function change_html() {
var start_number = 20;
var start = new Date("November 11, 2020 00:00:00"); // This will get the all milisec
var end = new Date(); // This will get the all milisec of current
var final = (get_difference(start,end)); // This will return all the mins passed
var new_start = (final/20); // This will get how many 20 are passed
var new_final = new_start.toString();
new_final = new_final.split(".");
var final_to_show = new_start-parseInt(new_final[0]);
final_to_show = final_to_show*20; // This will get how many numbers are remain to complete 20
final_to_show = Math.round(((20)-final_to_show));
document.getElementById('html_element').innerHTML = final_to_show;
}
And second for converting milisec to mins
function get_difference(start,end) {
var difference =((end.getTime() - start.getTime()) / 1000)/60;
return Math.abs(Math.round(difference));
}
I didn't want to reset the countdown on reload and the loop is endless.
I don't understand what to do with reset because it is not based on any static value it will be done in jQuery and Javascript. Please help me with this or suggest me to do it with another way.
You just need to use a setInterval method
the most complicated was to set your countdown of 17 minutes in offset of 3 points, with a first start at 20.
...and you should have a look about how the modulo works in math
const showElement = document.getElementById('html_element')
, one_Sec = 1000
, one_Min = one_Sec * 60
, countMax = 20
, countMin = 3
, countRange = countMax - countMin +1
, startDateT = (new Date("November 11, 2020 00:00:00")).getTime()
, timeNowDiff = () => Math.floor(Math.abs(((new Date()).getTime() -startDateT) / one_Min ))
;
showElement.textContent = countMax -(timeNowDiff() % countRange)
setInterval(()=>
{
showElement.textContent = countMax -(timeNowDiff() % countRange)
}
, one_Sec *10); // check display change every 10 seconds....
changing every minutes : <span id="html_element" style="color:red"></span> until 3

Javascript/Moment - Issue with generating time slots

I am trying to generate time slots with a gap of 15min between each one, like the following :
["15:30", "15:45", "16:00", "16:15"...]
So far, I managed to make it. However, if the current time is 15:25 (just an example) the generated array will start from 15:30 what I need instead (in this case) to generate time slots starting from 16:00 meaning that only the first time slot should be approximately away 30 min from the current time.
Currently, I have the following code :
//Used momentJS library
function getTimeStops(end) {
var roundedUp, startTime, endTime, timeStops;
roundedUp = Math.ceil(moment().utc().minute() / 30) * 30;
startTime = moment().utc().set({
minute: roundedUp
});
endTime = moment(end, 'HH:mm');
if (endTime.isBefore(startTime)) {
endTime.add(1, 'day');
}
timeStops = [];
while (startTime <= endTime) {
timeStops.push(new moment(startTime).format('HH:mm'));
startTime.add(15, 'minutes');
}
return timeStops;
}
var timeStops = getTimeStops('02:00');
console.log('timeStops ', timeStops);
You're rounding to the nearest half hour here:
roundedUp = Math.ceil(moment().utc().minute() / 30) * 30;
Round to the nearest hour instead:
roundedUp = Math.ceil(moment().utc().minute() / 60) * 60;
Edit: just realised that the above is wrong and doesn't actually answer your question.
You do need to change your roundedUp value though.
What you need to do is:
Add 30 minutes to the current time
Round it to the closest 15 minute interval
That way - at most - you'll be 7.5 minutes out.
So for step 1, add 30 minutes
var add30mins = moment.utc().add(30, 'minutes')
Now we need to find the closest 15 minute interval.
var roundTo15Mins = Math.round(add30Mins.minute() / 15) * 15;
Then you can plug that into your startTime.
HTH

JavaScript calculate time and seconds

I was having some problem when trying to perform some calculation logic using JavaScript. Basically along a route there is 80 steps and it took around 9 minutes to finish up the entire route.
So I was trying to do an auto route which will tell you the minutes left to destination. My logic is as below:
9 * 60 / 80 = 6.75
So basically for each step is 6.75 seconds but I wanted to show a round number like 9 instead of 8.4 minutes. Here is the code:
getAllBusLoc(function(busList) {
var totalBusLoc = busList.length;
var busLeftPct = Math.round(parseFloat(busList.length) * 40 / 100)
document.getElementById("busStopLeft").innerHTML = totalBusLoc;
pointArr.forEach(function(coord,index){
setTimeout(function(){
var travelTime = document.getElementById(travelDistMin").value;
moveNext(coord.x, coord.y);
}, 1000* index);
});
});
I got the travel time as variable travelTime which in this case is 9 minutes. For each point, I wanted to minus 6.75 seconds from the 9 minutes and display a round number instead of 8.2.
Any ideas?
Thanks in advance.
Use Math.round() for subtracting 6.75 from travelTime.
This is will round to the nearest whole number.
An idea that I could suggest is to write a generic function that transforms a decimal time interval (for example, 8.25 minutes) into its equivalent 'mm:ss' value instead of rounding so that you display the precise time representation:
Number.prototype.toMMSS = function () {
d = this;
var sign = d < 0 ? "-" : "";
var min = Math.floor(Math.abs(d))
var sec = Math.floor((Math.abs(d) * 60) % 60);
return sign + (min < 10 ? "0" : "") + min + ":" + (sec < 10 ? "0" : "") + sec;
};
Example:
8.25.toMMSS() // "08:15"
JSFiddle
Or, you could try the moment plugin duration function like:
moment.duration(8.25, 'minutes').minutes(); // 8
Or, the humanize method to round off:
console.log(moment.duration(8.51, "minutes").humanize()); // "9 minutes"
console.log(moment.duration(8.15, "minutes").humanize()); // "8 minutes"

Javascript time difference via timepicker

I'm working on a web timesheet where users use timepicker to determine start & end times and I'd like to have the form automatically find the difference between the two times and place it in a 3rd input box. I understand that I need to get the values, convert them to milliseconds, then subtract the first number from the second, convert the difference back to human time and display that in the third box. But I can't seem to wrap my head around time conversion in javascript. Here's what I have so far:
function date1math(){
var date1in = document.getElementById("date-1-in").value;
var date1out = document.getElementById("date-1-out").value;
date1in = date1in.split(":");
date1out = date1out.split(":");
var date1inDate = new Date(0, 0, 0, date1in[0], date1in[1], 0);
var date1outDate = new Date(0, 0, 0, date1out[0], date1out[1], 0);
var date1math = date1outDate.getTime() - date1inDate.getTime();
var hours = Math.floor(date1math / 1000 / 60 / 60);
date1math -= hours * 1000 * 60 * 60;
var minutes = Math.floor(date1math / 1000 / 60);
return (hours < 9 ? "0" : "") + hours + ":" + (minutes < 9 ? "0" : "") + minutes;
document.getElementById("date-1-subtotal").value = date1math(date1in, date1out);
}
I want to take the timepicker result (say 9:00am) from the input date-1-in, the timepicker result (say 5:00pm) from the input date-1-out, and then place the difference as a number in date-1-subtotal.
Presumably the input is a string in the format hh:mm (e.g. 09:54) and that the two strings represent a time on the same day. You don't mention whether an am/pm suffix is included, but it's there in the text so I'll assume it might be.
If daylight saving changes can be ignored, the simplest method is to convert the string to minutes, find the difference, then convert back to hours and minutes, e.g.:
// Convert hh:mm[am/pm] to minutes
function timeStringToMins(s) {
s = s.split(':');
s[0] = /m$/i.test(s[1]) && s[0] == 12? 0 : s[0];
return s[0]*60 + parseInt(s[1]) + (/pm$/i.test(s[1])? 720 : 0);
}
// Return difference between two times in hh:mm[am/pm] format as hh:mm
function getTimeDifference(t0, t1) {
// Small helper function to padd single digits
function z(n){return (n<10?'0':'') + n;}
// Get difference in minutes
var diff = timeStringToMins(t1) - timeStringToMins(t0);
// Format difference as hh:mm and return
return z(diff/60 | 0) + ':' + z(diff % 60);
}
var t0 = '09:15am';
var t1 = '05:00pm';
console.log(getTimeDifference('09:15am', '05:00pm')); // 07:45
console.log(getTimeDifference('09:15', '17:00')); // 07:45
If daylight saving is to be incorporated, you'll need to include the date so that date objects can be created and used for the time difference. The above can use either 12 or 24 hr time format.

Categories