I've 2 date variables in my script, One representing the current time and the other 2 minutes later. My aim is to check both values every minute and trigger a function when current is more or equal than the latter.
Here's my code and for some reason it doesn't execute the doing() function
var current = new Date(Date.now());
var endtime = new Date(Date.now() + 2 * 60 * 1000);
hours = ('0' + endtime.getHours()).slice(-2);
mins = ('0' + endtime.getMinutes()).slice(-2);
secs = ('0' + endtime.getSeconds()).slice(-2);
var gametime = hours + ":" + mins + ":" + secs;
$('#endtime').html(gametime);
var i = setInterval(function () { myFunction(); }, 60000);
function myFunction() {
if (new Date(current) > new Date(endtime)) {
doing();
}
}
function doing() {
var body = $('#alert');
var colors = ['white', 'transparent'];
var currentIndex = 0;
setInterval(function () { light(); }, 400);
function light() {
body.css({
backgroundColor: colors[currentIndex]
});
if (!colors[currentIndex]) {
currentIndex = 0;
} else {
currentIndex++;
}
}
alert("Time's up!");
clearInterval(i);
}
Well, you set current and endtime but neither ever changes, so every time myFunction gets called, the condition evaluates to false and so doing is never called.
I would add an else, that advances current, i.e.:
function myFunction() {
if (new Date(current) > new Date(endtime)) {
doing();
} else {
current = new Date(Date.now())
}
}
This way, eventually, current will become greater than endtime.
Thanks to Konrad Linkowski who told me to update the variables, I updated "Current" time variable inside the interval which solved the issue.
Related
I have the following code and cannot get the chat timestamp to update without refresh. I am new to javascript.
function timeSince(date) {
var seconds = Math.floor((new Date() - date) / 1000);
var interval = seconds / 31536000;
if (interval > 1) {
return Math.floor(interval) + " years";
}
interval = seconds / 2592000;
if (interval > 1) {
return Math.floor(interval) + " months";
}
interval = seconds / 86400;
if (interval > 1) {
return Math.floor(interval) + " days";
}
interval = seconds / 3600;
if (interval > 1) {
return Math.floor(interval) + " hours";
}
interval = seconds / 60;
if (interval > 1) {
return Math.floor(interval) + " minutes";
}
return Math.floor(seconds) + " seconds";
}
setInterval(timeSince, 1000);
var aDay = 24*60*60*1000;
console.log(timeSince(new Date(Date.now()-aDay)));
console.log(timeSince(new Date(Date.now()-aDay*2)));
const dates = new Date(message.timestamp)
if (message.user === currentUser) position = 'right';
const messageItem = `
<div class="message ${position}">
<span class="small">${timeSince(dates)}</span><br>
I tried: setInterval(timeSince, 1000); and setInterval(timeSince(), 1000); and setInterval(timeSince(date, 1000); and tried each in different place within the function, can't get to work.
timeSince just returns your formatted string with the duration. Setting an interval on this function will do practically nothing. You have to use the return value.
setInterval(function(){
var time = timeSince(message.timestamp);
//You can use a better selector here,
//but without more information, this is the best I can do.
document.getElementsByClassName("small")[0].innerHTML = time;
}, 1000);
found a half solution. I had to insert the setInterval under the function that calls the function under which sits the timesince function. Now the whole thing updates after the interval i set and not just the time, but setting an update interval of 1 minute makes it fine with me.
Apparently since I have several functions under one, the setInterval doesn't work, or didn't work in my case.
draw message is the function under which the timeSince function resides
Maybe coz i didn't provide this info here before i didn't get the right help
Solution:
this:
function getConversation(recipient) {
setInterval(function(){
$.getJSON(`/api/v1/message/?target=${recipient}`, function (data) {
messageList.children('.message').remove();
for (let i = data['results'].length - 1; i >= 0; i--) {
drawMessage(data['results'][i]);
}
messageList.animate({scrollTop: messageList.prop('scrollHeight')});
});
}, 60000);}
or this:
function getConversation(recipient) {
$.getJSON(`/api/v1/message/?target=${recipient}`, function (data) {
messageList.children('.message').remove();
for (let i = data['results'].length - 1; i >= 0; i--) {
drawMessage(data['results'][i]);
}
**setInterval(getConversation(recipient), 1000);**
messageList.animate({scrollTop: messageList.prop('scrollHeight')});
});
}
Thank you David for your help
I'm trying to create a function that can return a value (the user's current time in seconds) to another variable that can be used elsewhere in my code. The function returns the correct value, but I can't figure out how to make it repeat using setInterval or setTimeout.
var currenttime = clock();
function clock() {
var now = new Date();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
var time = (hour * 3600) + (minute * 60) + second;
return time;
}
console.log(currenttime)
I want the variable currenttime to be updated every second, but changing the line to
var currenttime = setInterval(clock, 1000);
returns an incorrect value. Alternatively I've also tried to make the clock function repeat,
but I'm not sure how to do this as I'm using a return statement so the function ends before it can be repeated.
Does anyone know what I'm doing wrong?
Assign to currentTime every time clock runs, but don't return the time - since this'll be in an interval, the return value is ignored:
let currentTime;
function clock() {
var now = new Date();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
currentTime = (hour * 3600) + (minute * 60) + second;
}
setInterval(clock, 1000);
setTimeout(() => console.log(currentTime), 2000);
setTimeout(() => console.log(currentTime), 6000);
This is a bit weird, though - variable assignment alone doesn't have side effects (in almost all cases). It would make more sense for whatever uses the currentTime variable to call clock to get the current number of seconds, eg:
function clock() {
var now = new Date();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
return (hour * 3600) + (minute * 60) + second;
}
document.querySelector('button').addEventListener('click', () => {
document.querySelector('div').textContent = clock();
});
<button>Get seconds</button>
<div id="time"></div>
The function called by setInterval should call clock and display the time.
setInterval(function(){ console.log(clock()); }, 1000);
setInterval return only an ID value that can be used in clearInterval(ID) to stop setInterval loop.
So, you can do that:
function clock()
{
let [h,m,s] = (new Date().toTimeString()).match(/\d{2}/g)
return (h*3600) + (m*60) + +s
}
var currenttime = clock();
setInterval(() => { currenttime = clock() }, 1000);
I’m looking for a way to tweak a current script of mine that loads a page into a div every minute. I want it to wait 5 minutes at a specific time, then go back to executing every minute. Here’s what I have so far.
var starttime = 10:30:00 PM;
var endtime = 10:35:00 PM;
var myVar = setInterval(function(){ myTimer() }, 1000);
function myTimer() {
var d = new Date();
document.getElementById("currenttime").innerHTML = d.toLocaleTimeString();
if ( d.toLocaleTimeString() > starttime &&
d.toLocaleTimeString() < endtime ) {
setInterval(function() {
}, 300000);
$("#ticketload").load("loadlasttenminutesmodified.php");
} else {
setInterval(function() {
}, 60000);
$("#ticketload").load("loadlasttenminutesmodified.php");
}
};
Any help is appreciated, thanks.
var starttime = '10:30:00 PM',
endtime = '10:35:00 PM';
var myVar = setInterval(myTimer, 1000);
// Use this function instead of toLocaleTimeString,
// since inconsistencies may arise with that one, depending on country.
function getTimeFormatted(date) {
var hours = date.getHours(),
minutes = date.getMinutes(),
seconds = date.getSeconds(),
ampm = hours >= 12 ? 'PM' : 'AM';
hours = hours % 12;
hours = hours ? hours : 12;
minutes = minutes < 10 ? '0' + minutes : minutes;
seconds = seconds < 10 ? '0' + seconds : seconds;
return hours + ':' + minutes + ':' + seconds + ' ' + ampm;
}
function myTimer() {
var d = getTimeFormatted(new Date());
document.getElementById("currenttime").innerHTML = d;
// Simply return (exit) the function when current time is
// between both of those dates.
// Your function will not go further than this.
// And it will effectively do nothing other than update the innerHTML
// for about five minutes.
if (d > starttime && d < endtime) return;
// Do the stuff that is supposed to run every minute.
// I assume this is, but place whatever else you want in here.
$("#ticketload").load("loadlasttenminutesmodified.php");
}
You can just exit out of the interval with return when the time criteria is met, before executing the rest of the code that is supposed to run every minute.
I made some changes to your code:
You missed quotes in your starttime and endtime variables
Replaced toLocaleTimeString with a new function. Thanks to #SpiderPig for pointing out why toLocaleTimeString isn't reliable.
You can specify the function directly in the myVar interval, instead of executing the myTimer function inside of an anonymous function.
Format the current day into AM/PM once, since that's all that is needed.
return when the time criteria is met and before executing the rest of the code inside of the interval.
I don't know what those empty setIntervals were in there for, so I removed them. I guess this is just example code, judging from the variable names you gave.
Try
var startTime = "22:30:00",
endTime = "22:35:00",
currentTime = $("#currenttime"),
ticketLoad = $("#ticketload"),
delay = 60000,
extendedDelay = delay * 5,
timeout = null,
timer = function timer(delay) {
var cycle = function cycle(delay, reset) {
// clear `queue` if within `startTime` , `endTime` range,
// `reset` set to `true`
if (reset) {
this.queue("timer", []);
};
// `cycle` delay `60000`
this.html("currenttime called at:" + new Date().toLocaleString())
// set `cycle` delay to `300000`
// if within `startTime` , `endTime` range,
// `reset` set to `true`
var _delay = !reset ? delay : extendedDelay;
.delay(_delay, "timer")
.queue("timer", function() {
console.log(new Date().toLocaleString());
// continue cycle
timer.call($(this), _delay);
}).dequeue("timer");
// do ajax stuff
ticketLoad.load("loadlasttenminutesmodified.php")
.fail(function(jqxhr, textStatus, errorThrown) {
console.log(errorThrown);
// clear `queue` on `error`
currentTime.queue("timer", [])
});
};
// if within `startTime` , `endTime` range
// clear `queue` , set `cycle` delay to `300000`
if (String(new Date()).split(" ")[4] > startTime
&& String(new Date()).split(" ")[4] < endTime) {
cycle.call(this, delay, true);
timeout = setInterval(function() {
if (String(new Date()).split(" ")[4] >= endTime) {
clearInterval(timeout);
timeout = null;
this.queue("timer", []);
cycle.call(this, delay)
}
}.bind(this), 7500)
} else {
if (String(new Date()).split(" ")[4] >= endTime) {
this.queue("timer", []);
cycle.call($(this), delay)
} else {
cycle.call($(this), delay)
}
};
};
timer.call(currentTime, delay);
$(function() {
var startTime = "22:30:00",
endTime = "22:35:00",
currentTime = $("#currenttime"),
ticketLoad = $("#ticketload"),
delay = 60000,
extendedDelay = delay * 5,
timeout = null,
timer = function timer(delay, reset) {
var cycle = function cycle(delay, reset) {
if (reset) {
this.queue("timer", [])
};
var _delay = !reset ? delay : extendedDelay;
this.html("currenttime called at:" + new Date().toLocaleString())
.delay(_delay, "timer")
.queue("timer", function() {
console.log(new Date().toLocaleString());
timer.call($(this), _delay)
}).dequeue("timer");
$.when(ticketLoad)
.always(function(data) {
this.html("ticketLoad called at:" + new Date().toLocaleString())
})
};
if (String(new Date()).split(" ")[4] > startTime
&& String(new Date()).split(" ")[4] < endTime) {
cycle.call(this, delay, true);
timeout = setInterval(function() {
if (String(new Date()).split(" ")[4] >= endTime) {
clearInterval(timeout);
timeout = null;
this.queue("timer", []);
cycle.call(this, delay)
}
// check if beyond `endTime` ,
// reset `cycle`
// adjust interval duration here
// for greater, less frequency of checks
}.bind(this), 7500)
} else {
if (String(new Date()).split(" ")[4] >= endTime) {
this.queue("timer", []);
cycle.call($(this), delay)
} else {
cycle.call($(this), delay)
}
};
};
timer.call(currentTime, delay)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id="currenttime"></div>
<div id="ticketload"></div>
Date.prototype.setMyTime = function (time) {
arrTime = time.split(":");
this.setHours(arrTime[0],arrTime[1],arrTime[2]);
return this;
}
var d = new Date();
var starttime = d.setMyTime('22:30:00');
var endtime = d.setMyTime('22:35:00');
var intervalId, loading = false;
var myVar = setInterval(function(){ myTimer() }, 1000);
function myTimer() {
var d = new Date();
document.getElementById("currenttime").innerHTML = d.toLocaleTimeString();
if(d.getTime() > starttime.getTime() && d.getTime() < endtime.getTime()) {
clearInterval(intervalId);
loading = false;
} else {
if (loading === false) {
intervalId = setInterval(function(){ $("#ticketload").load("loadlasttenminutesmodified.php"); }, 60000);
loading = true;
}
}
}
I decided to take a different approach. Set the interval to one minute and have and if statement inside that. Also, I needed to convert the time format into the same format as my variables.
<script type="text/javascript">
starttime = '10:30:00 PM';
endtime = '10:35:00 PM';
var myVar = setInterval(function(){ myTimer() }, 60000);
function myTimer() {
var timenow = new Date();
timeconvert = timenow.toLocaleTimeString()
if (timeconvert > starttime && timeconvert < endtime)
{
//alert("Time is 5 minutes");
}
else
{
//alert("Time is 60 seconds");
$("#ticketload").load("loadlasttenminutesmodified.php");
}
};
</script>
This has been working great all week.
I have a page where I want to have "age counters" for bids put in by users. The number of users will vary from situation to situation, so that needs to be taken into consideration. I wrote this:
function timer(i) {
// this selects a 'hh:mm:ss' timestamp
if ($("#time_0" + i).text() !== "") {
var now = new Date();
var date = now.toDateString();
var tStamp = new Date(date + "," + $("#time_0" + i).text());
var diff = now - tStamp;
var mins = Math.floor(diff / (1000 * 60));
var secs = Math.floor((diff / 1000) % 60);
if (mins < 10) {
mins = "0" + mins;
}
if (secs < 10) {
secs = "0" + secs;
} else if (secs == 60) {
secs = "00";
}
$("#user" + i + "-t").text(mins + ':' + secs);
}
}
$(document).ready(function() {
//
var ids = [];
$("td[id^='time_0']").each(function() {
var i = ($(this).attr("id")).slice(-1);
ids.push(i);
});
for (i in ids) { // in my example ids = [1,2,3]
setInterval(function() {timer(i);}, 1000);
}
});
The timer itself functions just as I want it to, but only for user #2 (the middle one). I thought that if I encountered this problem, it would be either the first or last user in the list that had a working timer, but I'm getting blank cells for users #1 and #3.
Does anyone have any ideas as to how I can fix this? Thank you for your time.
==Edit==
I made a bare-bones jsfiddle
In your version loop never went past first reference, which was timer(0), because you called your function with timer(i), which was calling the first key in the array ids. When you have setInterval in a loop it will keep looping the first setInterval until that is terminated. By putting that i in an anonymous function, each setInterval gets fired.
$(document).ready(function () {
var ids = [];
$("td[id^='time_0']").each(function () {
var i = $(this).attr("id").slice(-1);
ids.push(i);
});
for (i in ids) {
(function(i) { // i needs to be stored into a anonymous function otherwise it gets overwritten
setInterval(function() {
timer(ids[i]); // calling just timer(i) would use array keys, not the actual values - ids[i] means: "give me the value of the key of i"
}, 1000)
})(i);
}
});
Made changes to your Fiddle
I am using the following script below, and what I am trying to do is to set a custom time to the script and for it to auto update without the need to re-set the time each time. (I only want to set the time once and want my script to keep track of the time and display it)
When I run the script it displays: NaN:NaN:NaN AM
My Code is as follows:
<div id="js_clock"> display clock here </div>
<script language="javascript">
function js_clock(clock_time)
{
var clock_hours = clock_time.getHours();
var clock_minutes = clock_time.getMinutes();
var clock_seconds = clock_time.getSeconds();
var clock_suffix = "AM";
if (clock_hours > 11){
clock_suffix = "PM";
clock_hours = clock_hours - 12;
}
if (clock_hours == 0){
clock_hours = 12;
}
if (clock_hours < 10){
clock_hours = "0" + clock_hours;
}
if (clock_minutes < 10){
clock_minutes = "0" + clock_minutes;
}
if (clock_seconds < 10){
clock_seconds = "0" + clock_seconds;
}
var clock_div = document.getElementById('js_clock');
clock_div.innerHTML = clock_hours + ":" + clock_minutes + ":" + clock_seconds + " " + clock_suffix;
setTimeout("js_clock()", 1000);
}
var serverTime = new Date("09:20:50");
js_clock(serverTime);
</script>
You have a problem creating the date, new Date("09:20:50"); returns Invalid Date.
if you want to set hours minutes and seconds use
new Date(year, month, day [, hour, minute, second, millisecond ])
or take a look here.
Also you forgot to pass a date to the setTimeout, try:
setTimeout(function() {
js_clock(new Date(/*pass hours minutes and seconds here*/))
}, 1000);
I think you've forgotten passing an argument to js_clock(). Maybe you shoud do:
setTimeout(
function() {
//Call the function again updating seconds by 1
js_clock(
new Date(
clock_time.getFullYear(),
clock_time.getMonth(),
clock_time.getDate(),
clock_time.getHours(),
clock_time.getMinutes(),
clock_time.getSeconds() + 1
)
);
},
1000
);
EDIT:
I missed the point this can be done with a single function call:
setTimeout(
function() {
js_clock(new Date(+clock_time + 1000));
},
1000
);
The +clock_time statement converts the Date object to milliseconds from the UNIX Epoch, so updating the time is as simple as summing 1000 milliseconds.
Thanks to user RobG ;-)
Your code has some serious flaws, such as the following.
setTimeout doesn't run at exactly the interval set, but as soon as it can afterward so this clock will slowly drift, sometimes by a lot.
Passing a string to Date and expecting it to be correctly parsed is problematic. In ECMA-262 ed 3 it was entirely implementation dependent, in ES5 the string is required to be a custom version of the ISO8601 long format (but note that not all browsers in use support ES5).
Lastly, if the client is busy, the function may not run for several seconds so the clock needs to be based on the client clock, then ajusted for the time difference.
The following function does all the above.
<script type="text/javascript">
var customClock = (function() {
var timeDiff;
var timeout;
function addZ(n) {
return (n < 10? '0' : '') + n;
}
function formatTime(d) {
return addZ(d.getHours()) + ':' +
addZ(d.getMinutes()) + ':' +
addZ(d.getSeconds());
}
return function (s) {
var now = new Date();
var then;
// Set lag to just after next full second
var lag = 1015 - now.getMilliseconds();
// Get the time difference if first run
if (s) {
s = s.split(':');
then = new Date(now);
then.setHours(+s[0], +s[1], +s[2], 0);
timeDiff = now - then;
}
now = new Date(now - timeDiff);
document.getElementById('clock').innerHTML = formatTime(now);
timeout = setTimeout(customClock, lag);
}
}());
window.onload = function() {
customClock('09:20:50');
}
</script>
<div id="clock"></div>
WAIT! just realised, this is still not showing the correct time. The error is gone, but the time isn't what you are looking for.
window.js_clock = function js_clock(clock_time) {
var clock_hours = clock_time.getHours();
var clock_minutes = clock_time.getMinutes();
var clock_seconds = clock_time.getSeconds();
var clock_suffix = "AM";
if (clock_hours > 11) {
clock_suffix = "PM";
clock_hours = clock_hours - 12;
}
if (clock_hours === 0) {
clock_hours = 12;
}
if (clock_hours < 10) {
clock_hours = "0" + clock_hours;
}
if (clock_minutes < 10) {
clock_minutes = "0" + clock_minutes;
}
if (clock_seconds < 10) {
clock_seconds = "0" + clock_seconds;
}
var clock_div = document.getElementById('js_clock');
clock_div.innerHTML = clock_hours + ":" + clock_minutes + ":" + clock_seconds + " " + clock_suffix;
setTimeout("js_clock(new Date())", 1000);
}
var serverTime = new Date("09:20:50");
window.js_clock(serverTime);