Run javascript for X amount of minutes - javascript

i am trying to create a program that will run for X amount of minutes.
minutes was always set to 1 in testing
var minutes = $('#minutes').val();
var runtime = minutes*60; // gets the seconds
var secondsEpoch = new Date() / 1000; // Epoch time
var End = secondsEpoch + runtime; // add the minutes to the current epoch
if (secondsEpoch < End) {
window.setInterval(RunClock, 1000/10);
} else {
clearInterval(RunClock);
}
function RunClock() {
console.log(new Date() / 1000);
//my code
}
The script runs for infinity and i'm confused on why ???
When alerting variable secondsEpoch and End i always end up with a time difference of 1 minute?
Alerted the start and finish times and got
Start 1395022190.621
Finish 1395022250.621
Total difference of 60 which = 1 minute
but the console log at this minute is
1395022456.657
which is obviously greater than
1395022250.621
and the scrip is still running and not stopping

You are not clearing your interval correctly. This way it will work:
var interval;
if (secondsEpoch < End) {
interval = setInterval(RunClock, 1000/10);
} else {
clearInterval(interval);
}

Related

How can I send messages at regular intervals? [duplicate]

I am trying to update information from a weather service on my page. The info should be updated every hour on the hour. How exactly do I go about calling a function on the hour every hour?
I kind of had an idea but I'm not sure of how to actually refine it so it works...
What I had in mind was something like creating an if statement, such as: (pseudo code)
//get the mins of the current time
var mins = datetime.mins();
if(mins == "00"){
function();
}
You want to check out setInterval: https://developer.mozilla.org/en-US/docs/Web/API/Window.setInterval
It's a little hard to tell what you're trying to call with your code, but it would be something in the form of:
function callEveryHour() {
setInterval(yourFunction, 1000 * 60 * 60);
}
If you want it every hour, try something like:
var nextDate = new Date();
if (nextDate.getMinutes() === 0) { // You can check for seconds here too
callEveryHour()
} else {
nextDate.setHours(nextDate.getHours() + 1);
nextDate.setMinutes(0);
nextDate.setSeconds(0);// I wouldn't do milliseconds too ;)
var difference = nextDate - new Date();
setTimeout(callEveryHour, difference);
}
Now, this implementation checks the time once, sets the delay (or calls the function immediately), and then relies on setInterval to keep track after that. An alternative approach may be to poll the time every x many seconds/minutes, and fire it .getMinutes() == 0 instead (similar to the first part of the if-statement), which may sacrifice (marginal) performance for (marginal) accuracy. Depending on your exact needs, I would play around with both solutions.
Here is what should work (JSFiddle):
function tick() {
//get the mins of the current time
var mins = new Date().getMinutes();
if (mins == "00") {
alert('Do stuff');
}
console.log('Tick ' + mins);
}
setInterval(tick, 1000);
What you probably want is something like that:
var now = new Date();
var delay = 60 * 60 * 1000; // 1 hour in msec
var start = delay - (now.getMinutes() * 60 + now.getSeconds()) * 1000 + now.getMilliseconds();
setTimeout(function doSomething() {
// do the operation
// ... your code here...
// schedule the next tick
setTimeout(doSomething, delay);
}, start);
So basically the first time the user get the access, you need to know what is the delay in millisecond to the next "hour". So, if the user access to the page at 8:54 (with 56 seconds and 123 milliseconds), you have to schedule the first execution after around 3 minutes: after the first one is done, you can call it every "hour" (60 * 60 * 1000).
Repeat at specific minute past the hour
This counter is a little bit more versatile; it allows to perform a task repeatedly always at the same minute past the hour (e.g. 37 minutes past the hour), and this with up to millisecond precision.
The precision of this timer is derived from its recursion.
At every recursion, the millisecond time to the next minute gets recalculated. This prevents time lag over long periods.
The % sign refers to the modulo operator.
function minuteCount(minutesAfterHour) {
const now = new Date();
const hours = now.getHours();
const minutes = now.getMinutes();
const seconds = now.getSeconds();
const milliseconds = now.getMilliseconds();
waitUntilNextMinute = setTimeout(minuteCount, 60000 - seconds * 1000 - milliseconds);
if(minutes % 60 === minutesAfterHour) {
doSomethingHourly();
}
}
minuteCount(37);
Finally, timers are best kept away from the main thread. They are best run from within a web worker, as explained here.
This works perfectly with unfocused tabs in desktop browsers.
However, dedicated web workers on Chrome for Android are put to sleep about 5 minutes after moving the main client to the background.
EDIT: Oops, I didn't see the " o' clock" things, so I edit my answer :
var last_execution = new Date().getTime();
function doSomething(force){
var current_time = new Date().getTime();
if (force || (current_time.getMinutes() == 0)
{
last_execution = current_time;
// something
// ...
}
setTimeout(doSomething(false), 1000);
}
// force the first time
doSomething(true);
// ... call your func now
let intervalId;
let timeoutId = setTimeout(() => {
// ... call your func on end of current hour
intervalId = setInterval(() => {
// ... call your func on end of each next hours
}, 3600000);
}, ((60 − moment().minutes()) × 60 × 1000) - (moment().second() * 1000));
Here is my pair of setIntervalWithDelay and clearIntervalWithDelay that one can use like this:
let descriptor = setIntervalWithDelay(callback, 60 * 60 * 1000, nextHourDelay)
And when you are done with it:
clearIntervalWithDelay(descriptor)
Here is my implementation of the functions:
const setIntervalWithDelay = (callback, interval, delay = 0) => {
let descriptor = {}
descriptor.timeoutId = setTimeout(() => {
if(!descriptor.timeoutId){
return
}
descriptor.timeoutId = null
callback()
descriptor.intervalId = setInterval(callback, interval)
}, delay)
return descriptor
}
export const clearIntervalWithDelay = (descriptor) => {
if(!isObject(descriptor) || (!descriptor.timeoutId && !descriptor.intervalId)){
console.warn("clearIntervalWithDelay: Incorrect descriptor. Please pass an object returned by setIntervalWithDelay. Skipping this call.")
return
}
if(descriptor.timeoutId){
clearTimeout(descriptor.timeoutId)
descriptor.timeoutId = null
console.log("clearIntervalWithDelay: stopped during delay.")
}
if(descriptor.intervalId){
clearInterval(descriptor.intervalId)
descriptor.intervalId = null
console.log("clearIntervalWithDelay: stopped during interval repeat.")
}
}
One example of using dayjs to get the delay for the next hour:
let nextHour = dayjs().second(0).millisecond(0).add(1, "hour")
let nextHourDelay = nextHour.diff(dayjs())

How can I make 2 counters running back to back with javascript?

The following function naturally enters the same loop over and over again. What I want to do is start counting down from 25 seconds, when it's finished, start counting down from 10 seconds, then go back to 25 seconds. But because of the condition I wrote in the else part, it always counts backwards from 10 seconds. How can I fix this?
var interval = 25000;
var interval1 = 10000;
function millisToMinutesAndSeconds(millis) {
var seconds = ((millis % 60000) / 1000).toFixed(0);
return (seconds < 10 ? "0" : "") + seconds;
}
function tensecond() {
localStorage.endTime = +new Date() + interval1;
}
function reset() {
localStorage.endTime = +new Date() + interval;
}
setInterval(function () {
var remaining = localStorage.endTime - new Date();
if (remaining >= 0) {
document.getElementById("timer").innerText =
millisToMinutesAndSeconds(remaining);
} else {
tensecond();
}
}, 100);
Some comments:
Don't use the localStorage object to store your own properties. This has nothing to do with the purpose of localStorage. Just use a global variable (if you need local storage, then use its getItem and setItem methods)
Don't use toFixed(0) to round a number to an integer. Moreover, the comparison of that string with 10 will make a character-based comparison, not a numerical comparison. Instead use Math.round, or more appropriate here: Math.floor.
Don't use new Date() when you want a number of milliseconds instead of a Date object. Use Date.now() instead.
Don't do arithmetic on values that are not initialised. Initialise endTime before starting any logic on it. So call reset() before calling setInterval()
As to your question:
One way to get this to work is to make a cycle that covers both intervals added together. Then at each tick check whether the remaining time falls inside the first or second interval. Adjust the displayed remaining time accordingly.
Here is how that looks:
var interval = 25000;
var interval1 = 10000;
var endTime;
function millisToMinutesAndSeconds(millis) {
// Use floor instead of toFixed
var seconds = Math.floor((millis % 60000) / 1000);
return (seconds < 10 ? "0" : "") + seconds;
}
function reset() {
// Use Date.now() instead of +new Date()
// And create a cycle length that covers both intervals
endTime = Date.now() + interval + interval1;
}
reset();
setInterval(function () {
var remaining = endTime - Date.now();
if (remaining >= 0) {
// Adjust the time to display
// depending on where in the total interval we are:
if (remaining >= interval1) remaining -= interval1;
document.getElementById("timer").innerText =
millisToMinutesAndSeconds(remaining);
} else {
reset()
}
}, 100);
<div id="timer"></div>
There's no need to incorporate specific datetimes or local storage if you just need an alternating countdown timer. A simpler technique is to just keep track of the number of remaining seconds and do updates after a repeated 1s delay, subtracting a second from the total each time.
Here's an example of that (and it also displays each second rounded up instead of rounded down — so it starts with 25 (or 10) and resets at the exact moment that 0 is reached rather than displaying 0 for an entire second):
const timerElement = document.getElementById('timer');
function updateTimerElement (seconds) {
timerElement.textContent = String(seconds).padStart(2, '0');
}
function delay (ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function countdown (seconds) {
while (seconds > 0) {
updateTimerElement(seconds);
await delay(1e3); // 1e3 is 1000 (1s)
seconds -= 1;
}
// You might want to update the timer one final time in order to show 0
// if you ever stop looping the countdowns:
// updateTimerElement(seconds);
}
async function main () {
// Store the total number of seconds for each countdown in order:
const secondsList = [25, 10];
// Keep track of the current one:
let listIndex = 0;
while (true) {
// Get the current number of seconds from the list:
const seconds = secondsList[listIndex];
// Run the countdown timer:
await countdown(seconds);
// Update the index to the next number of seconds in the list:
listIndex = (listIndex + 1) % secondsList.length;
}
}
main();
body { font-family: sans-serif; font-size: 4rem; }
<div id="timer"></div>
Finally, take care to note that JavaScript timers are not precise timing tools. See more info at: Reasons for delays longer than specified - setTimeout() - Web APIs | MDN
These are the facts:
The first time the (anonymous) interval function runs, localStorage.endTime isn't initialized, so has value undefined.
Any arithmetic operations on undefined result in NaN1, 2, 3, so remaining is initialized to NaN.
Any comparisons to NaN (other than != and !==) are false4, 5, 6, so the first time the interval function runs, it calls tensecond.
Thereafter, the interval function counts down. When the timer runs out, it again calls tensecond.
Short version: reset is never called.
ECMAScript, 13th Ed references
§ 13.15.3 ApplyStringOrNumericBinaryOperator
§ 7.1.4 ToNumber
§ 6.1.6.1.7 Number::add ( x, y )
§ 13.11.1 Runtime Semantics: Evaluation
§ 7.2.15 IsLooselyEqual ( x, y )
6.1.6.1.13 Number::equal

JQuery run every 5 minutes past the hour 5,10,15...55

I'm looking to run a function every 5 minutes past the hour i.e. 08:05, 08:10, 08:15 etc..all day
how do I adapt:
setTimeout(function(){
xxxxxxx()
}, 300000);
to detect the current time - if a multiple of 5 then run xxxxxx() function?
Using setInterval to call the function every second.
Then using a filter by current time having a minute divisible by 5 and seconds zero.
var timer = 0;
timer = setInterval(function(){
var currentdate = new Date();
if(currentdate.getMinutes() % 5 == 0 && currentdate.getSeconds() == 0) {
console.log("Alarm");
}
}, 1000);
//to stop: clearInterval(timer);
It is fairly straight forward:
Wait until you reach 5 minute boundary using setTimeout()
Use setInterval() to call the function every 5 minute
function dosomething() {
console.log("dosomething() called at " + new Date().toISOString());
}
var FIVEMINUTES = 5 * 60 * 1000;
var timeSincePrev = new Date() % FIVEMINUTES;
var timeUntilNext = timeSincePrev === 0 ? 0 : (FIVEMINUTES - timeSincePrev);
setTimeout(function() {
dosomething(); // execute now
setInterval(dosomething, FIVEMINUTES); // and after every 5 minutes
}, timeUntilNext);

How do I create a function that executes if the time is equal to x?

I was creating a webpage and I would like to receive assistance in that. I need a text to popup when the UTCHours and UTCMinutes are equal to specific values. I want something like this. This is like the model , not actual code.
h = utcTime
m = utcminutes
if (h=x and m=y)
{
function myFunction();
}
Surely I wont do everything for you, but here you go. A base to start from.
// The button functionality
const $ = (x) => document.getElementById(x);
$('start').addEventListener('click', ()=>{
startTime();
});
$('stop').addEventListener('click', ()=>{
stopTime();
});
// The timer
// set variables
let date,
start,
stop;
function startTime() {
date = new Date(); // get current date.
start = date.getTime(); // get time from current date
// Just output
document.getElementById("showStart").innerHTML = start;
}
function stopTime() {
date = new Date(); // get current date.
stop = date.getTime(); // get time from current date
// just output
document.getElementById("showStop").innerHTML = stop;
document.getElementById("difference").innerHTML = stop-start;
}
jsfiddle
I was bored so here you go.
// The button functionality
const $ = (x) => document.getElementById(x);
$('setAlert').addEventListener('click', ()=>{
setAlert(3); // alert in x seconds.
});
// set variables
let date,
target,
stop,
interval = 1; // integer.
function setAlert(time) {
date = new Date(); // get current date.
target = date.getTime() + ( (time * 1000) - ((interval * 1000) +1000) ); // sets the time it should alert.
/*
* time -1 because it's a 1s interval, that means when it reaches x = y it will alert 1s later by the next "check". This why you need to subtract 1s.
* (time-1)*1000 is because the getTime returns time in ms not in seconds. You would need to make it setAlert(3000),
* i made it bit easier by multiplying the value by 1000 = ms.
*/
// The loop that checks time
setInterval(function(){ // This function makes the "checking each X ms"
if(stop !== target){ // Check if time was reached.
stopTime(); // Check time
}else{
alert("TIME IS OVER"); // When time is reached do this.
}
}, interval*1000); // Refreshes the time each second.
// Just output
document.getElementById("showTarget").innerHTML = target+(interval*1000); // Because the target time has "minus" in it (line 16) it needs to be added to show the real target time.
}
function stopTime() {
date = new Date(); // get current date.
stop = date.getTime(); // get time from current date
// just output
document.getElementById("showStop").innerHTML = stop;
// document.getElementById("difference").innerHTML = stop-target;
}
jsfiddle v2
function displayAlert(hour,minute){
//create a new Date Object(Current Date and Time)
var date = new Date();
// getUTCHours getUTCMinutes are inbuilt methods
// for getting UTC hour and minute by comparing it with timezone
var utcHour = date.getUTCHours();
var utcMinutes = date.getUTCMinutes();
//display alert when utc hour and minute matches sired time
if(utcHour == hour && utcMinutes == minute){
alert(utcHour + " : " + utcMinutes)
}
}
displayAlert(18,31)
setInterval(function(){
now = new Date();
hours = now.getUTCHours();
mins = now.getUTCMinutes();
executeFunctionIfEqualToDefined(hours, mins);
},60000); // this block will run every 60000 milli seconds i.e 60 seconds =1 min
function executeFunctionIfEqualToDefined(hours, mins){
if(hours === x && mins === y){
//execute your code here
}
}

Unix timestamp to seconds in javascript

I'm trying to do a program which executes after 15 minutes of being in the page. My problem is how to get the exact number to add on the timestamp which is stored in a cookie.
I need a function to convert seconds into timestamps or anything that can make the action execute after 15 minutes. I don't really know how much time is 1792939 which I place in the code below.
setInterval("timer()",1000);
$.cookie("tymz", time);
function timer(){
var d = new Date();
var time = d.getTime();
var x = Number($.cookie("tymz")) + 1792939;
//alert('Cookie time: ' + x + '\nTime: ' + time);
if(time > x){
alert('times up');
}else{
//alert('not yet\n' + 'times up: ' + x + '\ntime: ' + time);
}
}
How about using setTimeout(..)?
<script type="text/javascript">
function myFunc()
{
alert("I will show up 15 minutes after this pages loads!");
}
setTimeout("myFunc()",60*15*1000);
</script>
Check this: http://www.w3schools.com/js/js_timing.asp
unix timestamp are second from epoch (1/1/1970) so if you want to execute some code after 15 minutes just record the time when the page is loaded then every second calculate how many seconds are passed from page load. When the difference between current time and page load time is greater than 15*60*1000 you can execute your code.
var pageLoad = new Date().getTime();
function tick(){
var now = new Date().getTime();
if((now - pageLoad) > 15*60*1000) executeYourCode();
}
setInterval("tick()",1000);
Remeber that javascript return time in millisecond
Hope this helps
If the number is seconds since 1/1/1970 00:00:00, then you can convert '1792939' to a javascript date by multiplying by 1,000 and passing to Date:
var d = new Date(1792939 * 1000) // Thu Jan 22 1970 04:02:19
Currently it is about 1311428869 seconds since 1/1/1970. So if you have a value for seconds, then you can use setInterval to run a function 15 minutes after that:
var seconds = ?? // set somehow
var start = new Date(seconds * 1000);
var now = new Date();
var limit = 15 * 60 * 1000;
var lag = now - start + limit;
// Only set timeout if start was less than 15 minutes ago
if ( lag > 0 ) {
setTimeout( someFn, lag);
}
Provided the current time is less than 15 minutes from the start time, the function will run at approximately 15 minutes after the start time. If the system is busy when the time expires, the function should be run as soon as possible afterward (usually within a few ms, but maybe more).
works without server or cookie (and all browser after IE7)
Looks like you use jQuery, so you might as well use jQuery.now() insted
var firstVisit = localStorage['firstVisit'] = localStorage['firstVisit'] || $.now();
function myFunc(){
alert("I will show up 15 minutes after this pages loads!");
}
setTimeout(myFunc, parseInt(firstVisit) - $.now() + 1000 * 60 * 15);

Categories

Resources