I decided to take the plunge, given my previous warnings about reliance upon the client's time, and write a pure JavaScript version:
var timeList = [
{ 'days': [0,1,2,3,4], 'times': [ [ 10, 18 ], [12, 30] ] },
{ 'days': [5,6], 'times': [ [ 10,30 ], [12, 30] ] }
];
var minutesNearTimeListToShow = 30;
var pollSeconds = 60;
$(document).ready(function() {
checkForShowing();
});
function checkForShowing() {
var now = new Date();
var currentDay = now.getDay();
var currentHour = now.getHours();
var currentMinute = now.getMinutes();
var timeAndDay = getNextTimeAndDay (currentDay, currentHour, currentMinute);
var nextAlertDue = new Date(now.getYear() + 1900, now.getMonth(), now.getDate(), timeAndDay.hour, timeAndDay.minute);
nextAlertDue.setDate(now.getDate() - currentDay + timeAndDay.day);
var differenceSeconds = (nextAlertDue - now) / 1000;
if (differenceSeconds < minutesNearTimeListToShow * 60) {
$(".myButton").show();
window.setTimeout (function() {
$(".myButton").hide();
}, differenceSeconds * 1000);
} else {
$(".myButton").hide();
window.setTimeout(checkForShowing, pollSeconds * 1000);
}
}
function getNextTimeAndDay(tDay, tHour, tMinute) {
var times = getTimesForDay(tDay);
var nextTime = getNextTime (tHour, tMinute, times)
if (!nextTime) {
tHour = 0;
tMinute = 0;
tDay++;
if (tDay == 7) { tDay = 0; }
times = getTimesForDay(tDay);
nextTime = getNextTime (tHour, tMinute, times);
}
return { day: tDay, hour: nextTime[0], minute: nextTime[1] };
}
function getNextTime (tHour, tMinute, times) {
for (var i in times) {
if ((tHour < times[i][0]) || (tHour == times[i][0] && tMinute <= times[i][1])) {
return times[i];
}
}
return false;
}
function getTimesForDay(currentDay) {
var times = false;
for (var i in timeList) {
var days = timeList[i].days;
if (days.indexOf(currentDay) > -1) {
times = timeList[i].times;
}
}
return times;
}
The main configuration is right at the top, allowing different times to be specified for different days.
Once a minute, the code will check to see if it is within half an hour of one of these times; if it is, then the button will be shown and a setTimeout
set up to hide it again (and restart polling) when the half-hour is up.
Note that if the code starts within the half-hour (e.g. 20 minutes in), it will pick up on that, show the button, and schedule the hiding for just 10 minutes later.
The date checking is reasonably well tested, the scheduling not so much - feel free to suggest corrections!