I have a list of events on a given day. (events time is a moment object)
[
{ id: 1, start: '2017-05-01 05:00'},
{ id: 2, start: '2017-05-01 08:00'},
{ id: 3, start: '2017-05-01 14:00'},
{ id: 4, start: '2017-05-01 17:00'}
]
I need to add one event in this array so that the new event time is not less than 5am, is at least 3 hours after the previous event (if there is one) and 3h before the next event (if there is one). The new event should be planned on the same day.
In this case, it would insert the new event just after id = 2 and at 11am.
I started something but it ended up with a dozen of ifs and I got lost after a few hours thinking:
// for each event, check if there's time before or after (not less than 5am, not more than 11:59pm)
for(var i = 0; i < events.length; i++) {
var eventTime = events[i].start.clone();
var before = eventTime.clone();
var after = eventTime.clone();
before.subtract('hours', 3);
after.add('hours', 3);
if(i == 0 && !before.hour() < 5 && !before.isBefore(date, 'day')) {
// first event of the day, new time cannot be before 5am and cannot be on the previous day
hour = before.hour();
} else if(i == 0 && !after.isAfter(date, 'day')) {
// same as above but we test time + 3h
} else if(i == events.length - 1 && !after.isAfter(date, 'day')) {
// last event of the day, new time cannot be the next day (after 11:59pm)
hour = after.hour();
} else if (i > 0 && i < events.length - 1) {
// middle events
// new time should be at least 3H after previous event and 3H before next event
// ex: 5h, 8h, 12h ok but 5h, 8h, 10h not ok or 5h, 6h, 9h not ok
var previousEventTime = events[i-1].start.clone();
var nextEventTime = events[i+1].start.clone();
if(before.hour() >= previousEventTime.hour() && after.hour() <= nextEventTime.hour()) {
}
//
}
}
Here is a snippet that can be used:
var events = [
{ id: 1, start: 'Mon, 01 May 2017 05:00:00 +0200'},
{ id: 2, start: 'Mon, 01 May 2017 08:00:00 +0200'},
{ id: 3, start: 'Mon, 01 May 2017 14:00:00 +0200'},
{ id: 4, start: 'Mon, 01 May 2017 17:00:00 +0200'}
];
for(var i = 0; i < events.length; i++) {
var eventTime = moment(events[i].start).clone();
var before = moment(eventTime).clone();
var after = moment(eventTime).clone();
before.subtract(3, 'hours');
after.add(3, 'hours');
console.log(eventTime, before, after);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
After spending a day on this I came up with a "mathematical" solution.
In my array I want to insert an event y between an event x and an event z. (x being the previous event and z the next one)
Since I need 3 hours minimum between each event I figured:
x+3 <= y-3 || y+3 <= z-3
The one I implemented is a little bit different. I figured I needed at least 6 hours between 2 events to be able to insert a new event in the middle.
y-x > =6 || z-y >= 6
Since my brain is not far from burning out the code looks like this...
for(var i = 0; i < events.length; i++) {
var x = null;
var y = events[i].start.clone().hour();
var z = null;
if(i > 0) {
x = events[i-1].start.clone().hour();
}
if(i < events.length -1) {
z = events[i+1].start.clone().hour();
}
// first event or only event
if(i == 0) {
// check if removing 3h00 doesn't cross the 5am limit
if(y - 3 >= 5) {
hour = y - 3;
} else if(z-y >= 6) {
// check if there's enough time before next event
hour = y + 3;
}
}
// middle event
if(x && z) {
if (y-x >= 6) {
hour = y - 3;
} else if (z-y >= 6) {
hour = y + 3;
}
}
// last event (can also be first if only 1 element)
// with !hour we make sure that a "middle" event hour is not overriden if found above
if(!hour && i == events.length - 1 && i != 0) {
// check if adding 3h00 doesn't change day (23h00)
if(y + 3 <= 23) {
hour = y + 3;
} else if(y-x >= 6) {
// check if there's enough time after previous event
hour = y - 3;
}
}
}
return hour;
I'd be glad to accept an answer that improves on this algorithm.
Related
Wrote a simple little app to check what period it is a display it with Javascript. Works great for the most part - but at certain times it will display the next period instead of the current one.
How do I test it without waiting and manually checking?
I'd obviously like to figure out why it displays the wrong period
Edit: If the time is 15:06 (3:06PM) it will display the last else statement instead of the second to last one
Code:
var now = '';
//Set Periods
//Slot 1+2 are periods - slots 3+4 are passing times inbetween periods
var periods = [
['Before School', 5.00, 7.59],
['First', 8.00, 8.49, 8.50, 8.54],
['Second', 8.55, 9.44, 9.45, 9.49],
['Third', 9.50, 10.39, 10.40, 10.44],
['Fourth', 10.45, 11.34, 11.35, 11.39],
['Fifth', 11.40, 12.29, 12.30, 12.34],
['Sixth', 12.35, 13.24, 13.25, 13.29],
['Seventh', 13.30, 14.19, 14.20, 14.24],
['Eighth', 14.25, 15.15]
];
//Display Period
function displayPeriod() {
if (now >= periods[0][1] && now <= periods[0][2]) {
document.getElementById('period').innerHTML = ('School has not started yet');
} else if (now >= periods[1][1] && now <= periods[1][2]) {
document.getElementById('period').innerHTML = ('1st');
} else if (now >= periods[1][3] && now <= periods[1][4]) {
document.getElementById('period').innerHTML = ('1st Passing');
} else if (now >= periods[2][1] && now <= periods[2][2]) {
document.getElementById('period').innerHTML = ('2nd');
} else if (now >= periods[2][3] && now <= periods[2][4]) {
document.getElementById('period').innerHTML = ('2nd Passing');
} else if (now > periods[3][1] && now <= periods[3][2]) {
document.getElementById('period').innerHTML = ('3rd');
} else if (now >= periods[3][3] && now <= periods[3][4]) {
document.getElementById('period').innerHTML = ('3rd Passing');
} else if (now >= periods[4][1] && now <= periods[4][2]) {
document.getElementById('period').innerHTML = ('4th');
} else if (now >= periods[4][3] && now <= periods[4][4]) {
document.getElementById('period').innerHTML = ('4th Passing');
} else if (now >= periods[5][1] && now <= periods[5][2]) {
document.getElementById('period').innerHTML = ('5th');
} else if (now >= periods[5][3] && now <= periods[5][4]) {
document.getElementById('period').innerHTML = ('5th Passing');
} else if (now >= periods[6][1] && now <= periods[6][2]) {
document.getElementById('period').innerHTML = ('6th');
} else if (now >= periods[6][3] && now <= periods[6][4]) {
document.getElementById('period').innerHTML = ('6th Passing');
} else if (now >= periods[7][1] && now <= periods[7][2]) {
document.getElementById('period').innerHTML = ('7th');
} else if (now >= periods[7][3] && now <= periods[7][4]) {
document.getElementById('period').innerHTML = ('7th Passing');
} else if (now >= periods[8][1] && now <= periods[8][2]) {
document.getElementById('period').innerHTML = ('8th');
} else {
document.getElementById('period').innerHTML = ('School is done for the day.');
}
}
//Check Time
function startTime() {
var today = new Date();
now = today.getHours() + '.' + today.getMinutes();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
m = checkTime(m);
s = checkTime(s);
displayPeriod();
var t = setTimeout(startTime, 500);
}
function checkTime(i) {
if (i < 10) {
i = '0' + i
}; // add zero in front of numbers < 10
return i;
}
You can test the function by inputting the current time through startTime() function. You can comment out the setTimeout if you only want to test a specific function. You can check that the output for 15.06 is correct too.
var now = '';
//Set Periods
//Slot 1+2 are periods - slots 3+4 are passing times inbetween periods
var periods = [
['Before School', 5.00, 7.59],
['First', 8.00, 8.49, 8.50, 8.54],
['Second', 8.55, 9.44, 9.45, 9.49],
['Third', 9.50, 10.39, 10.40, 10.44],
['Fourth', 10.45, 11.34, 11.35, 11.39],
['Fifth', 11.40, 12.29, 12.30, 12.34],
['Sixth', 12.35, 13.24, 13.25, 13.29],
['Seventh', 13.30, 14.19, 14.20, 14.24],
['Eighth', 14.25, 15.15]
];
//Display Period
function displayPeriod() {
console.log(now)
if (now >= periods[0][1] && now <= periods[0][2]) {
console.log('School has not started yet');
} else if (now >= periods[1][1] && now <= periods[1][2]) {
console.log('1st');
} else if (now >= periods[1][3] && now <= periods[1][4]) {
console.log('1st Passing');
} else if (now >= periods[2][1] && now <= periods[2][2]) {
console.log('2nd');
} else if (now >= periods[2][3] && now <= periods[2][4]) {
console.log('2nd Passing');
} else if (now > periods[3][1] && now <= periods[3][2]) {
console.log('3rd');
} else if (now >= periods[3][3] && now <= periods[3][4]) {
console.log('3rd Passing');
} else if (now >= periods[4][1] && now <= periods[4][2]) {
console.log('4th');
} else if (now >= periods[4][3] && now <= periods[4][4]) {
console.log('4th Passing');
} else if (now >= periods[5][1] && now <= periods[5][2]) {
console.log('5th');
} else if (now >= periods[5][3] && now <= periods[5][4]) {
console.log('5th Passing');
} else if (now >= periods[6][1] && now <= periods[6][2]) {
console.log('6th');
} else if (now >= periods[6][3] && now <= periods[6][4]) {
console.log('6th Passing');
} else if (now >= periods[7][1] && now <= periods[7][2]) {
console.log('7th');
} else if (now >= periods[7][3] && now <= periods[7][4]) {
console.log('7th Passing');
} else if (now >= periods[8][1] && now <= periods[8][2]) {
console.log('8th');
} else {
console.log('School is done for the day.');
}
}
//Check Time
function startTime(hours, minutes, seconds) {
var today = new Date();
var h = hours != null ? hours : today.getHours(); // use current time if input is empty
var m = minutes != null ? minutes : today.getMinutes(); // use current time if input is empty
var s = seconds != null ? seconds : today.getSeconds(); // use current time if input is empty
m = checkTime(m);
s = checkTime(s);
now = h + '.' + m; // move it here to correspond with input
displayPeriod();
// var t = setTimeout(startTime, 500);
}
function checkTime(i) {
if (i < 10) {
i = '0' + i
}; // add zero in front of numbers < 10
return i;
}
startTime();
startTime(15, 6, 0);
You should check time (add zero in front of numbers < 10) before set now variable
function startTime() {
var today = new Date();
var h = checkTime(today.getHours());
var m = checkTime(today.getMinutes());
now = h + '.' + m;
displayPeriod();
var t = setTimeout(startTime, 500);
}
Where your problem is:
Your startTime function is setting now like this:
now = today.getHours() + '.' + today.getMinutes();
It's then calculating zero-padded hour and minute values, but these are not used!
So, instead of representing nine minutes past eight as "9.08", it is using "9.8".
How to test your code
You probably want to learn about unit testing, but that is too big a topic to go over here.
Some of the prinicpals of writing testable code can be applied here, though.
First, separate logic from updating UI (or DOM), by refactoring your DisplayPeriod function to return a string value instead of modifying the DOM:
function displayPeriod() {
if (now >= periods[0][1] && now <= periods[0][2]) {
return 'School has not started yet';
} else if (now >= periods[1][1] && now <= periods[1][2]) {
return '1st';
} else if (now >= periods[1][3] && now <= periods[1][4]) {
return '1st Passing';
} else if (now >= periods[2][1] && now <= periods[2][2]) {
return '2nd';
// (Snip)
} else {
return 'School is done for the day.';
}
}
This method would then be used by another method which updates the DOM.
Second, allow for injection of dependencies. E.g. You have an implicit dependency on the system clock via the Date() constructor. If you refactor StartTime to accept a date, then your test code can pass in whichever date values it needs to test different cases:
// Note that bugs in this method have not been fixed!
function startTime(today) {
now = today.getHours() + '.' + today.getMinutes();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
m = checkTime(m);
s = checkTime(s);
// Commented out, as interfers with testing (should be moved to DOM setting method).
// var t = setTimeout(startTime, 500);
}
Third, use a test framework to run various scenarios and check expected and actual results. Here's a poor man's test case and test execution script:
function TestCase(time, expectedResult) {
startTime(time)
var result = displayPeriod();
if (result == expectedResult) {
console.log("Passed for " + time)
} else {
console.log("Failed for " + time + "(" + result + ")");
}
}
for (minute = 0; minute < 50; minute++) {
time = new Date(2018, 11, 14, 8, minute);
TestCase(time, "1st");
}
I'm trying to compare an array of times with the current local time. But comparing the numbers fails for some values. As far as I could detect, it is not always failing the same time string. Im really out of ideas what the reason could be.
function lastPassedTimeIndex() {
const d = new Date();
const nowHr = d.getHours();
const nowMin = d.getMinutes();
let lastPassedTimeIndex = 0;
const currentTimes = ['05:20', '06:57', '12:46', '15:48', '18:30', '20:02'];
for (const time of currentTimes) {
const t = time.split(':');
const printHr = parseInt(t[0], 10);
const printMin = parseInt(t[1], 10);
if ((printHr < nowHr) && (printMin < nowMin)) {
console.log(time, 'previous from now');
lastPassedTimeIndex++;
}
else if ((printHr === nowHr) && (printMin < nowMin)) {
console.log(time, 'previous from now, but hour is correct');
lastPassedTimeIndex++;
}
else if ((printHr === nowHr) && (printMin >= nowMin)) {
console.log(time, 'is upcoming or now and hour is correct');
lastPassedTimeIndex++;
}
else if ((printHr > nowHr)) {
console.log(time, 'is upcoming, hour is larger');
}
else {
console.log('I have no idea!');
}
}
console.log('LastPassedTimeIndex ', lastPassedTimeIndex);
return lastPassedTimeIndex;
}
This is my console output:
> I have no idea!
> I have no idea!
> 12:46 is upcoming, hour is larger
> 15:48 is upcoming, hour is larger
> 18:30 is upcoming, hour is larger
> 20:02 is upcoming, hour is larger
> LastPassedTimeIndex 0
I only see one error, fixed this way:
const printHr = parseInt(t[0], 10);
const printMin = parseInt(t[1], 10);
if ((printHr < nowHr) /* Take out what was here */) {
console.log(time, 'previous from now');
lastPassedTimeIndex++;
}
The minutes have to be compared only when the hours are the same, or just compare as strings:
var time = new Date().toTimeString().slice(0, 5)
var times = ['05:20', '06:57', '12:46', '15:48', '18:30', '20:02']
console.log( time, times.findIndex(t => t >= time) - 1 )
I have four screens that I want to display in the following order.
Screen1(2 seconds) -> Screen2 (2 seconds) -> Screen3 (2 Seconds)
I also have a fourth screen which should only show when the time is between 05:55-06:05 and 17:55-18:05
In order to accomplish this my code looks like this till now:
function timecondition() {
var hours = new Date();
var minutes = new Date();
var h = hours.getHours();
var m = minutes.getMinutes();
var timecondition;
if((h == 5 && m >= 55) || (h == 6 && m <= 5) || (h == 17 && m >= 55) || (h == 18 && m <= 5)) {
timecondition = true;
}
else {
timecondition = false;
}
return timecondition;
}
$(document).ready(
function() {
setInterval(function() {
setTimeout(function() {
if(timecondition()) {
$('#show').load("http://localhost:8084/test/screen4");
}
else {
$('#show').load("http://localhost:8084/test/screen1");
}
}, 2000);
setTimeout(function() {
if(timecondition()) {
$('#show').load("http://localhost:8084/test/screen4");
}
else {
$('#show').load("http://localhost:8084/test/screen2");
}
}, 4000);
setTimeout(function() {
if(timecondition()) {
$('#show').load("http://localhost:8084/test/screen4");
}
else {
$('#show').load("http://localhost:8084/test/screen3");
}
}, 6000);
}, 6000);
}
);
Unfortunately it doesnt work like I want it to be.
When I start the webapplication at 05:54 the sequence(screen1->screen2->screen3)
But once the clock hits 05:55 it won't display the fourth screen, like it was in my intention.
When I start the application within the timecondition eg. at 05:56 it shows the fourth screen, but won't leave screen4 when the timecondition is not true anymore a few minutes later.
Is it because I need dynamic functions?
Couple of potential bugs there.
1. You are taking the time twice
Every time you call new Date() you are taking a snapshot of an instant. In this case they are only milliseconds away from each other, but it's a bug nonetheless.
var hours = new Date();
var minutes = new Date();
One object should be enough:
var now = new Date();
var h = now.getHours();
var m = now.getMinutes()
2. Your time condition is wrong
var timecondition;
if((h == 5 || h == 6 || h == 17 || h == 18) && (m >= 55 || m <= 05)) {
timecondition = true;
}
else {
timecondition = false;
}
return timecondition;
There is two problems with this:
a) It is hiding the function name from within. This is just a minor bug and doesn't affect the functionality here yet.
b) You are checking for hours and minutes independently. This IS a serious bug because it doesn't comply with your business logic.
That whole code above can be smarter rewritten as:
h = h % 12
return (h == 5 && m >= 55) || (h == 6 && m <= 5)
3. You reload the page every few seconds
The second argument to setInterval and setTimeout respectively is in milliseconds. So you are issuing a load every 2 seconds.
4. You are nesting timeouts within intervals
This basically means that every six seconds you are setting a timer for the next 2, 4 and 6 seconds. This is not really a bug, but unnecessarily complex. Why not set one interval for running every two seconds?
Here's some refactored and hopefully fixed code. Didn't try it out yet, though.
function slideshow() {
var screens = [
"http://localhost:8084/test/screen1",
"http://localhost:8084/test/screen2",
"http://localhost:8084/test/screen3"
];
var specialScreen = "http://localhost:8084/test/screen4";
// Contains the index of currently shown screen or -1
// when the special screen is shown
var currentScreen = 0;
// Cache the element here so we don't need to search for it every two seconds
var show = $('#show');
function timecondition() {
var now = new Date();
var h = now.getHours();
var m = now.getMinutes();
h = h % 12;
return (h == 5 && m >= 55) || (h == 6 && m <= 5);
}
function update() {
if (timecondition()) {
if (currentScreen != -1) {
show.load(specialScreen);
currentScreen = -1;
}
return;
}
currentScreen = (currentScreen + 1) % screens.length;
show.load(screens[currentScreen]);
}
setInterval(update, 2000);
}
$(document).ready(slideshow);
If you wanted different durations for the screens, you could do it roughly like this:
function slideshow() {
var screens = [
{url: "http://localhost:8084/test/screen1", t: 2000},
{url: "http://localhost:8084/test/screen2", t: 3000},
{url: "http://localhost:8084/test/screen3", t: 10000}
];
var specialScreen = "http://localhost:8084/test/screen4";
// Contains the index of currently shown screen or -1
// when the special screen is shown
var currentScreen = 0;
// Cache the element here so we don't need to search for it every two seconds
var show = $('#show');
function timecondition() {
var now = new Date();
var h = now.getHours();
var m = now.getMinutes();
h = h % 12;
return (h == 5 && m >= 55) || (h == 6 && m <= 5);
}
var step = 1000;
var screenTimer = 0;
function update() {
if (timecondition()) {
if (currentScreen != -1) {
show.load(specialScreen);
currentScreen = -1;
}
return;
}
if ((screenTimer += step) >= screeens[currentScreen].t) {
currentScreen = (currentScreen + 1) % screens.length;
show.load(screens[currentScreen].url);
screenTimer = 0;
}
}
setInterval(update, step);
}
$(document).ready(slideshow);
I need to do a 3 consecutive business day check against an array of dates in javascript. I have it working with any 3 days but I can't figure out for the life of me how I can make this work with the weekend breaking up the consecutive days.
NOTE - This requires moment() library (https://momentjs.com)
My code that works for 3 actual consecutive days:
var allDates = ["2017-03-07", "2017-03-09", "2017-03-10", "2017-03-13", "2017-03-15"];
var diff = 86400000;
var consecutive = 0;
allDates.sort(function(a,b){
return new Date(a) - new Date(b);
});
for (i = 2; i < allDates.length; i++) {
var d = moment(allDates[i], "YYYY-MM-DD").format('x');
var d1 = moment(allDates[i-1], "YYYY-MM-DD").format('x');
var d2 = moment(allDates[i-2], "YYYY-MM-DD").format('x');
if (d1 - d2 == diff && d - d2 == diff * 2) {
consecutive = 1;
break;
}
}
As you can see by the calendar above, I would like March 9th, 10th and 13th to act as 3 consecutive business days. Anyone have any feedback that can guide me onto a right path?
Thanks in advance
You can use the javascript Date object to figure out which days are weekends.
Here is the documentation
And a quick example:
var d1 = new Date("2017-03-07");
var d2 = new Date("2017-03-08");
d.getDay() // this will return 1, which corresponds with Monday. 2 is Tuesday, 3 is Wednesday, etc.
So a small function to tell if 2 dates are consecutive, even if separated by a weekend, could be:
var millisecondsInDay = 86400000;
function datesAreConsecutiveBusinessDays(date1, date2){
// If date1 is a Friday and date2 is a Monday
if (date1.getDay() === 5 && date2.getDay() === 1){
// And the dates are 2 days apart
date2.valeOf() - date1.valueOf() === millisecondsInDay * 2
return true;
} else if (date2.valeOf() - date1.valueOf() === millisecondsInDay){
return true;
} else {
return false;
}
}
So with this method, you go through your list of dates and call it on every two that are next to eachother.
var consecutive = 0;
var allDates = ["2017-03-07", "2017-03-09", "2017-03-10", "2017-03-13", "2017-03-15"];
for (var i = 0; i < allDates.length - 1; i++){
if (datesAreConsecutiveBusinessDays(new Date(allDates[i]), new Date(allDates[i+1])){
consecutive++;
}
// If you want to start over if you hit a nonconsecutive date, add this else:
else {
consecutive = 0; // this will start the counter over
}
}
You might need to tweak the solution a bit depending on how consecutive is calculated, but this should be enough to get you started.
This can be solved by writing a function which determines if any 2 momentjs instances are either 1 day different, or if one is friday and the other is monday (but must only be 3 days apart). Simply, this does it:
function isConsecutive(a,b){
return b.diff(a,"days") == 1
|| (a.weekday() == 5 && b.weekday() == 1 && b.diff(a,"days") == 3);
}
You can then take your array of dates, turn them all to momentJS instances, order them and iterate through calling the above method for each pair. Keep a running total of the count:
function countConsecutiveDays(arr){
var momentDates = arr.map(function(d){
return moment(d, "YYYY-MM-DD") ;
}).sort(function(a,b){return a.diff(b);})
var count = 0;
for(var i=1;i<momentDates.length;i++){
if(isConsecutive(momentDates[i-1],momentDates[i]))
count++;
}
return count+1;
}
A working example is below
function countConsecutiveDays(arr){
var momentDates = arr.map(function(d){
return moment(d, "YYYY-MM-DD") ;
}).sort(function(a,b){return a.diff(b);})
var count = 0;
for(var i=1;i<momentDates.length;i++){
if(isConsecutive(momentDates[i-1],momentDates[i]))
count++;
}
return count+1;
}
function isConsecutive(a,b){
return b.diff(a,"days") == 1
|| (a.weekday() == 5 && b.weekday() == 1 && b.diff(a,"days") == 3);
}
console.log(countConsecutiveDays( ["2017-03-07", "2017-03-09", "2017-03-10", "2017-03-13", "2017-03-15"]));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.js"></script>
This seems to be working from all my tests so far...unless someone can point out an issue or bug.
NOTE - This requires moment() library (https://momentjs.com)
var allDates = ["2017-03-07", "2017-03-09", "2017-03-10", "2017-03-13", "2017-03-15"];
var consecutive = 0;
allDates.sort(function(a,b){
return new Date(a) - new Date(b);
});
for (i = 2; i < allDates.length; i++) {
var d = moment(allDates[i], "YYYY-MM-DD");
var d1 = moment(allDates[i-1], "YYYY-MM-DD");
var d2 = moment(allDates[i-2], "YYYY-MM-DD");
if (d1.diff(d2,"days") == 1 && d.diff(d2,"days") == 2 ||
d2.weekday() == 5 && d1.weekday() == 1 && d1.diff(d2,"days") == 3 && d.diff(d1,"days") == 1 ||
d1.weekday() == 5 && d.weekday() == 1 && d.diff(d1,"days") == 3 && d1.diff(d2,"days") == 1) {
consecutive = 1;
break;
}
}
console.log('dates are consecutive: ' + consecutive)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.js"></script>
First - thanks in advance for your help.
I have a image based slide show, that calls #photo1, 2, 3. Using javascript to change the image (actually the image folder, all images have the same name, so just changing root folder) based on various time blocks throughout the day. (9am-11am, 11am-3pm, 3-6pm, 6pm-9am). In case it matters, I am storing the images on dropbox (so my buddy can change them at will, the links provided are old and not currently working).
It all seems to be working, accept for approx the first 30 minutes after the change time, it goes blank. Then works fine again.
Thoughts? I am not great with javascript, so if I am going about this all wrong, I am open to new approaches.
Javascript code:
$(document).ready(function(){
var d = new Date();
var n = d.getHours();
// If time is after 9AM or before 11AM
if (n > 9 && n < 11) {
$("img#photo1").attr("src","https://dl.dropboxusercontent.com/s/324....67l/ad1.jpg?dl=0");
$("img#photo2").attr("src","https://dl.dropboxusercontent.com/s/5i9f....m10z/ad2.jpg?dl=0");
$("img#photo3").attr("src","https://dl.dropboxusercontent.com/s/n7....66/ad3.jpg?dl=0");
}
else if (n > 11 && n < 15) {
$("img#photo1").attr("src","https://dl.dropboxusercontent.com/s/31p....rw3r/ad1.jpg?dl=0");
$("img#photo2").attr("src","https://dl.dropboxusercontent.com/s/h3m....tsqy/ad2.jpg?dl=0");
$("img#photo3").attr("src","https://dl.dropboxusercontent.com/s/zr9....kzja/ad3.jpg?dl=0");
}
else if (n > 15 && n < 18) {
$("img#photo1").attr("src","https://dl.dropboxusercontent.com/s/5li....y2w/ad1.jpg?dl=0");
$("img#photo2").attr("src","https://dl.dropboxusercontent.com/s/no....twr2/ad2.jpg?dl=0");
$("img#photo3").attr("src","https://dl.dropboxusercontent.com/s/ojjn....i1g/ad3.jpg?dl=0");
}
else if (n > 18 || n < 9) {
$("img#photo1").attr("src","https://dl.dropboxusercontent.com/s/kn3ch....s7g0/ad1.jpg?dl=0");
$("img#photo2").attr("src","https://dl.dropboxusercontent.com/s/dhxi5....04/ad2.jpg?dl=0");
$("img#photo3").attr("src","https://dl.dropboxusercontent.com/s/mb51....336/ad3.jpg?dl=0");
}
// runs the code every hour, probably there is a much better way to do this
setTimeout(function(){window.location.reload();}, 3600000)
});
When the hour is 9, 11, 15 or 18, none of your conditions will match, and nothing will be displayed. Change the conditions to:
if (n >= 9 && n < 11) {
// ...
}
else if (n >= 11 && n < 15) {
// ...
}
else if (n >= 15 && n < 18) {
// ...
}
else if (n >= 18 || n < 9) {
// ...
}
You've excluded 9, 11, 15 and 18; the if statements selects for greater than or less than. You'll get undefined for any of those numbers.