Hours of Operation Status - javascript

I made this little object that lets you know if a place is open based on two variables. However I would like to make this even better, because I am not very good at javascript I want to know what's best practice. How would I update open/close status in real-time for the user that gets there a minute before they close or open.
CodePen Source
html
<h1 class="status"></h1>
<h2 class="hours"></h2>
css
body {
color: white;
text-align: center;
font-size: 2em;
}
.open { background-color: #00a638; }
.closed { background-color: black; }
js
// variables
var open = "7:00";
var close = "5:00";
// setup miliary time
var mClose = close.replace(/:/g,'') + 1200;
var mOpen = open.replace(/:/g,'');
if (mOpen < 1000) {
mOpen = "0" + mOpen;
}
// setup hours
var now = new Date();
var hour = now.getHours();
if (hour >= 10) { mHour = hour;
} else { mHour = "0" + hour; }
// setup minutes
var minute = now.getMinutes();
if (minute < 10) {
minute = "0" + minute;
}
var time = "" + mHour + minute;
console.log("Time is " + time);
// open/close status
if ((time >= mOpen) && (time < mClose)) {
$("body").addClass("open");
$(".status").html("Yes, We're Open");
} else {
$("body").addClass("closed");
$(".status").html("Sorry We're Closed");
}
// display hours
$(".hours").html(open + " to " + close);

Related

How to show Open/Closed based on two shift working hours on website

I'm trying to display Open or Closed based on a shift (two Shifts daily) using Javascript. I want to be able to use that data which is stored within a span and then determine if the business is open or closed and display that. for me only one shift is working during second shift its displaying We are now closed.
Might be something better to do the same but only in HTML.
any other suggestion is appreciated.
Here is the code I have so far:
function isOpen(timeRangeEl, date) {
var day = '' + date.getDay();
var hhmm = ('0' + date.getHours()).slice(-2) + ':' + ('0' + date.getMinutes()).slice(-2);
var days = timeRangeEl.getAttribute('data-days');
var openTime = timeRangeEl.getAttribute('data-open');
var closeTime = timeRangeEl.getAttribute('data-close');
return days.indexOf(day) >= 0 && openTime <= hhmm && hhmm < closeTime;
}
function openClose() {
var date = new Date();
var display = document.getElementById('open-display');
var els = display.getElementsByClassName('timerange');
var anyActive = false;
for (var i = 0; i < els.length; i++) {
if (isOpen(els[i], date)) {
anyActive = true;
els[i].className = els[i].className.replace(/ *inactive\b/g, '');
} else if (els[i].className.indexOf('inactive') < 0) {
els[i].className += ' inactive';
}
}
if (anyActive) {
display.className = 'open';
} else {
display.className = 'closed';
}
}
setInterval(openClose, 5000);
openClose();
#open-display.open > .timerange.inactive,
#open-display.open > .timerange2.inactive,
#open-display.open .days {
display: none;
}
#open-display.open > .openclosed::before {
content: 'We are now Open';
}
#open-display.closed > .openclosed::before {
content: 'We are now Closed';
}
<div class="text">
<h3>Working Hours</h3>
<div id="open-display">
<div class="openclosed"></div>
<div class="timerange" data-days="1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31" data-open="12:30" data-close="15:30"><span class="days">Noon</span> 12:30pm - 3:30pm</div>
<div class="timerange2" data-days="1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31" data-open="18:00" data-close="00:30"><span class="days">Dine</span> 6:00pm - 12:30am</div>
</div>
</div>
Successfully done after trying and doing trial and error method.

Sunrise Sunset time image on current time with javascript

var doc = document;
clock({
twentyfour: !!twentyfour,
padzero: true,
refresh: 5000,
success: function(clock) {
doc.getElementById('time').innerHTML = clock.hour() + ":" + clock.minute();
document.getElementById('todate').innerHTML = clock.date() + ' ' + translate[current].month[clock.month()] + ' ' + clock.year();
document.getElementById('today').innerHTML = translate[current].weekday[clock.day()]
}
});
function mainUpdate(type) {
doc.getElementById("sunrise").innerHTML = weather.sunriseTimeFormatted;
doc.getElementById("sunset").innerHTML = weather.sunsetTimeFormatted;
var dtime = document.getElementById('time');
var dsunrise = document.getElementById('sunrise');
var dsunset = document.getElementById('sunset');
var sunriseI = document.getElementById('sunriseImg');
var sunsetI = document.getElementById('sunsetImg');
function sunriseI() {
if (dtime >= dsunrise) {
sunriseI.src = 'images/daytwilight.png';
} else {
sunriseI.src = 'images/blank.png';
}
}
function sunsetI() {
if (dtime == dsunset) {
sunsetI.src = 'images/nighttwilight.png';
} else {
sunriseI.src = 'images/blank.png';
}
}
}
<img onload="sunriseI()" id="sunriseImg" src="images/blank.png" />
<img onload="sunsetI()" id="sunsetImg" src="images/blank.png" />
not working. I wanna put twilight image on sunrise and sunset time for a while. on current time = sunset or sunrise. Or You can show me different alterrnative.Thank you for your help.
var sunrise = 5;
var sunset = 19;
var sunriseImage = "https://img.freepik.com/free-vector/mountain-landscape-background_1284-10559.jpg?size=338&ext=jpg";
var sunsetImage = "https://img.freepik.com/free-photo/3d-hazy-mountain-range-against-sunset-sky_1048-10361.jpg?size=626&ext=jpg";
var nightImage = "https://img.freepik.com/free-vector/starry-night-sky-background_23-2148058243.jpg?size=338&ext=jpg";
var dayImage = "https://img.freepik.com/free-photo/sky-with-sun-rays_1048-4473.jpg?size=626&ext=jpg";
var initClock = function(){
setInterval(function(){
var date = new Date();
var hour = date.getHours();
var minute = date.getMinutes();
var seconds = date.getSeconds();
changeTime(hour + " : " + minute + " : " + seconds);
if(hour == sunrise){
changeImage(sunriseImage);
}else if(hour == sunsetImage){
changeImage(sunsetImage);
}else if(hour > sunset || hour < sunrise){
changeImage(nightImage);
}else{
changeImage(dayImage);
}
}, 1000);
}
var changeTime = function(time){
document.getElementById("clock").innerHTML = time;
}
var changeImage = function(img){
document.getElementById("clock").style.backgroundImage = "url('"+img+"')";
document.getElementById("clock").style.backgroundSize = "cover";
}
initClock();
#clock{
width: 300px;
height: 140px;
background-size: cover;
text-align: center;
vertical-align: middle;
display: table-cell;
overflow:hidden;
background-repeat: no-repeat;
border: 1px solid black;
color: blue;
}
<div id="clock">
</div>
You should check if current time is around sunset / sunrise with some offset, and set image element's source based on that.
To compare times, First you should convert time string to a Date object. here is a function for it :
function parse_time(str){
var d_ = new Date();
d_.setHours(str.split(':')[0]);
d_.setMinutes(str.split(':')[1]);
d_.setSeconds(0);
return d_;
}
second for checking if a time is around other time with some period, you can use an isAround function like this:
function addHours(date, h) {
var result = new Date(date);
result.setTime(result.getTime() + (h*60*60*1000));
return result;
}
function isAround(d1,d2,period){
return (d1 >= (addHours(d2,-period)) && d1 <= (addHours(d2,period)));
}
And last, for checking if current time is around sunset or sunrise, use isAround function. And then set source of image element to corresponding image.
if (isAround(dtime, dsunrise, 1)) {
weatherImage.src = "sunrise_img";
}
else if (isAround(dtime, dsunset, 1)) {
weatherImage.src = 'sunset_img';
} else {
weatherImage.src = 'empty_img';
}
And also there was couple of other issues to your file, like using functions with same names as variables (sunriseI, sunsetI), using wrong variables(sunriseI in last line), using onload events which had wrong scopes and wasn't necessary, using two image elements which was unnecessary, etc.
Here is corrected code with weather check (i tested it and its working):
https://pastebin.com/dKmy8Rcu
Note that: replace clock1.0.3.2.js with your clock.js version. also i removed translate function usages in your code. also i removed weather, and replaced it with custom variables for sunset and sunrise.
I removed them because you didn't provided those in your source code, so just change them back if you have that resources.

JavaScript Timer Based Popup

trying to make a simple timer based popup.
once the timer reach 10 second popup will be visible.
timer should pause or stop, after clicking on 'ok' button of popup, timer should restart from 0. please help
https://jsfiddle.net/ckf0g9qj/5/
var span = document.querySelector("#time");
countDown(0);
function countDown(counter) {
var interval = setInterval(function() {
var minutes = ((counter / 60) | 0) + "";
var seconds = (counter % 60) + "";
var format = "" +
new Array(3 - minutes.length).join("0") + minutes + ':' + new Array(3 - seconds.length).join("0") + seconds;
span.innerHTML = format;
counter++;
if (seconds == 10) {
// $("#timeModal").modal(); BS model box open
// countDown(0);
document.getElementById("popup").style.visibility = "visible";
}
}, 1e3)
}
function timerReset() {
countDown(0);
alert("ok");
document.getElementById("popup").style.visibility = "hidden";
}
use clearInterval when you reach seconds == 10 condition
I think this is what you are looking for:
#popup {
width:200px;
height:200px;
border:solid 1px red;
visibility:hidden;
}
<!-- begin snippet: js hide: false console: true babel: false -->
<div id="time"></div>
<div id="popup">
<button id="ok" onclick="timerReset()">
Ok
</button>
</div>
<script>
var span = document.querySelector("#time");
countDown(0);
function countDown(counter) {
var interval = setInterval(function() {
var minutes = ((counter / 60) | 0) + "";
var seconds = (counter % 60) + "";
var format = "" +
new Array(3 - minutes.length).join("0") + minutes +
':' +
new Array(3 - seconds.length).join("0") + seconds;
span.innerHTML = format;
counter++;
if (seconds == 10) {
clearInterval(interval);
// $("#timeModal").modal(); BS model box open
// countDown(0);
document.getElementById("popup").style.visibility = "visible";
}
}, 1e3)
}
function timerReset() {
countDown(0);
alert("ok");
document.getElementById("popup").style.visibility = "hidden";
}
</script>

Call a function when my timer reaches zero

I've got a timer function as follows (which I've just grabbed off a jsfiddle):
function countdown( elementName, minutes, seconds )
{
var element, endTime, hours, mins, msLeft, time;
function returnDate(){
return Number(new Date);
}
function twoDigits( n )
{
return (n <= 9 ? "0" + n : n);
}
function updateTimer()
{
msLeft = endTime - (returnDate());
if ( msLeft < 1000 ) {
element.innerHTML = "0:00";
} else {
time = new Date( msLeft );
hours = time.getUTCHours();
mins = time.getUTCMinutes();
element.innerHTML = (hours ? hours + ':' + twoDigits( mins ) : mins) + ':' + twoDigits( time.getUTCSeconds() );
setTimeout( updateTimer, time.getUTCMilliseconds() + 500 );
}
}
element = document.getElementById( elementName );
endTime = (+new Date) + 1000 * (60*minutes + seconds) + 500;
updateTimer();
}
I call the function and set it to countdown to 2 minutes like so:
$(".btn-start").click(function(){
countdown("countdown-2-minutes",2,0);
});
I have another element with id countdown-8-minutes that I want to start immediately when the timer on countdown-2-minutes reaches 0. How should I do this? I suppose an okay way would be to monitor when the html on the first element reads "0:00" but I don't exactly know how to implement that.
Here's what I would suggest; First change your countdown() function to accept a callback parameter:
function countdown( elementName, minutes, seconds, callback )
{
var element, endTime, hours, mins, msLeft, time;
function returnDate(){
return Number(new Date);
}
function twoDigits( n )
{
return (n <= 9 ? "0" + n : n);
}
function updateTimer()
{
msLeft = endTime - (returnDate());
if ( msLeft < 1000 ) {
element.innerHTML = "0:00";
if (typeof callback === 'function') {
callback.call()
}
} else {
time = new Date( msLeft );
hours = time.getUTCHours();
mins = time.getUTCMinutes();
element.innerHTML = (hours ? hours + ':' + twoDigits( mins ) : mins) + ':' + twoDigits( time.getUTCSeconds() );
setTimeout( updateTimer, time.getUTCMilliseconds() + 500 );
}
}
element = document.getElementById( elementName );
endTime = (+new Date) + 1000 * (60*minutes + seconds) + 500;
updateTimer();
}
then pass that callback with your initial call:
$(".btn-start").click(function(){
countdown("countdown-2-minutes",2,0, function(){countdown("countdown-8-minutes",8,0);});
});
Just call countdown() with the proper parameters when you detect that the timer is finished. Try this:
if ( msLeft < 1000 ) {
element.innerHTML = "0:00";
countdown("countdown-8-minutes",8,0);
}
You don't need to watch the element's content to know when to start the next timer. In fact you're already reacting to that happening on the line you check if ( msLeft < 1000 ) { in which you can start your next timer.
Once your current timer hits zero you can just start the next one inside that if statement.
Alternatively you can separate your timer logic from your element logic using something like this:
// CountdownTimer object. Give it a length (ms) to count to, a period (ms)
// to loop updates to the callback, and a callback (function(done:bool)) that
// handles update ticks where done=false and the final tick where done=true.
function CountdownTimer(length, period, callback) {
this.length = length;
this.period = period;
this.callback = callback;
// Assert the callback to be a function to avoid messy error handling, and
// show we noticed in the console.
if (typeof this.callback !== 'function') {
console.warn('Callback was not a function.');
this.callback = function(){};
}
// Some publically visible variables for time keeping.
this.startTime = 0;
this.elapsed = 0;
this.remaining = length;
// The _loop scope's 'this' is itself. Give it a handle on the CountdownTimer's
// 'this' so we can reference the variables inside the loop.
var scope = this;
// Main loop of the countdown timer.
this._loop = function() {
// Get the number of milliseconds since the countdown started.
scope.elapsed = Date.now() - scope.startTime;
if (scope.elapsed < scope.length) {
// Keep looping if the countdown is not yet finished.
scope.remaining = scope.length - scope.elapsed;
scope.callback(false);
} else {
// Finished looping when the countdown hits or passes the target.
scope.elapsed = scope.length;
scope.remaining = 0;
scope.callback(true);
// Stop the interval timer from looping again.
clearInterval(scope._t);
}
};
}
// This function starts up the CountdownTimer
CountdownTimer.prototype.start = function() {
this.startTime = Date.now();
this._t = setInterval(this._loop, this.period);
}
// Our test elements.
var progress2 = document.getElementById('prog-2m');
var progress8 = document.getElementById('prog-8m');
var clockElement = document.getElementById('clock');
var startButton = document.getElementById('start');
// The 2-minute timer.
var m2 = new CountdownTimer(2 * 60 * 1000, 33, function(done) {
// Calculate the time to display.
var mins = Math.floor(m2.remaining / 60 / 1000);
var secs = Math.floor(m2.remaining / 1000) % 60;
if (secs < 10) secs = '0' + secs;
clockElement.textContent = mins + ':' + secs;
if (done) {
// If we're done, set the timer to show zero and start the next timer.
clockElement.textContent = '0:00';
m8.start();
}
// Progress bar display update.
progress2.style.width = (40 * (m2.elapsed / m2.length)) + 'px';
progress8.style.width = (160 * (m8.elapsed / m8.length)) + 'px';
});
// The 8-minute timer.
var m8 = new CountdownTimer(8 * 60 * 1000, 33, function(done) {
// Calculate the time to display.
var mins = Math.floor(m8.remaining / 60 / 1000);
var secs = Math.floor(m8.remaining / 1000) % 60;
if (secs < 10) secs = '0' + secs;
clockElement.textContent = mins + ':' + secs;
if (done) {
// Once done, set the timer to zero and display "Done".
clockElement.textContent = '0:00 Done';
}
// Progress bar display update.
progress2.style.width = (40 * (m2.elapsed / m2.length)) + 'px';
progress8.style.width = (160 * (m8.elapsed / m8.length)) + 'px';
});
// Start the 2-minute timer when the button is clicked.
startButton.addEventListener('click', function() {
m2.start();
});
#progress {
width: 200px;
height: 20px;
border: 2px solid #fff;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
border-radius: 2px;
position: relative;
margin: 8px 0;
}
#prog-2m {
width: 40px;
height: 20px;
background-color: #3c9;
position: absolute;
left: 0;
top: 0;
}
#prog-8m {
width: 160px;
height: 20px;
background-color: #c33;
position: absolute;
left: 40px;
top: 0;
}
<div id="progress">
<div id="prog-2m"></div>
<div id="prog-8m"></div>
</div>
<div id="clock">0:00</div>
<button id="start">Begin</button>

Browser Bug showing time text on input

I am dealing with the following puzzle and I cannot understand why it is happening.
I have the following [I believe to be] equivalent pieces of javascript code, but one does not work as expected (notice the Console.Log):
Updates the UI a single time, then unexpectantly stops updating : http://jsfiddle.net/silentwarrior/1m0v6oj1/
jQuery(function () {
var isWorking = true;
if (isWorking) {
var timeEnd = 1431220406000; // generated from php
var timeNow = 1431210557000; // generated from php
var counter = 1;
var t = "";
setInterval(function () {
try {
var c = timeEnd - timeNow - counter;
console.log(c);
var d = new Date(c);
if (c <= 1) {
window.location.href = window.location.href;
return;
}
t = "";
if (d.getHours() > 0) {
t += d.getHours() + "h ";
}
if (d.getMinutes() > 0) {
t += d.getMinutes() + "m ";
}
t += d.getSeconds();
jQuery("#factory_start_prod").val("Working ... " + t + "s left");
counter = counter + 1;
} catch (e) {
}
}, 1000);
}
});
Updates the UI constantly as expected: http://jsfiddle.net/silentwarrior/n3gkum2e/
jQuery(function () {
var isWorking = true;
if (isWorking) {
var timeEnd = 1431220406000;
var timeNow = 1431210557000;
var counter = 1;
var t = "";
setInterval(function () {
try {
var c = timeEnd - Date.now();
console.log(c);
var d = new Date(c);
if (c <= 1) {
window.location.href = window.location.href;
return;
}
t = "";
if (d.getHours() > 0) {
t += d.getHours() + "h ";
}
if (d.getMinutes() > 0) {
t += d.getMinutes() + "m ";
}
t += d.getSeconds();
jQuery("#factory_start_prod").val("Working ... " + t + "s left");
counter = counter + 1;
} catch (e) {
}
}, 1000);
}
});
The only difference from each other is that, the one that works uses Date.now() to get the current timestamp, while the other one uses a pre-built time stamp.
Why would one example update the text in the input correctly while the other wouldn't?
PS: it is important to me to use generated timestamps instead of Date.now() in order to not depend on the users system when calculating the time left.
Your first example is working, however with each iteration you are only subtracting 1 from the timestamp value, which is equivalent to 1ms. Hence the value never appears to change unless you wait a really long time. You need to increment the counter by 1000 on each iteration for a second to be counted:
counter = counter + 1000;
Updated fiddle

Categories