Run code once a day - javascript

I was just wondering if it is possible to have a javascript for loop that only iterates through the loop once a day i.e. when the date changes?
for(i=0; i < myArray.length; i++){
alert(myArray[i]);
}
So in the above loop, let it run, and freeze it or something only till the data changes, and the do another iteration, and just keep on doing that.. You know what I mean.
Thanks in advance!

Using localStorage is the best way to go when you don't have a server (because a user can change the computer's time and break your logic, and using a server it's harder to hack this)
Method below is more bulletproof:
// checks if one day has passed.
function hasOneDayPassed()
// get today's date. eg: "7/37/2007"
var date = new Date().toLocaleDateString();
// if there's a date in localstorage and it's equal to the above:
// inferring a day has yet to pass since both dates are equal.
if( localStorage.yourapp_date == date )
return false;
// this portion of logic occurs when a day has passed
localStorage.yourapp_date = date;
return true;
}
// some function which should run once a day
function runOncePerDay(){
if( !hasOneDayPassed() ) return false;
// your code below
alert('Good morning!');
}
runOncePerDay(); // run the code
runOncePerDay(); // does not run the code

If you want something to happen at predefined intervals, you can set a timeout/interval:
http://www.w3schools.com/js/js_timing.asp
For example:
var dayInMilliseconds = 1000 * 60 * 60 * 24;
setInterval(function() { alert("foo"); },dayInMilliseconds );
edit: since you mentioned that the code will be running in a browser, this assumes the browser is running for at least 24 hrs and will not work otherwise.

the best way to achieve it is by creating a cookie that lasts for1 day..
Even if after the refresh of the web page or browser gets closed that countdown will still continue..
setcookie($cookie_name, $cookie_value, time() + 86400, "/");
This means 86400 = 1 day
Hope it helps

Related

Discord.js Set Interval function not activating. Need confirmation of cause

I am currently having an issue with the setinterval function and was wondering if anyone could help. So oddly enough, it works for short intervals like 10 or 20 seconds but when I scale it to a day or half a day it fails to run. I'm on version 11.5.1 of discord.js
bot.setInterval(function(){
var Holiday = new Date();
var month = Holiday.getMonth()+1;
var day = Holiday.getDate();
var check = month+'/'+day;
var greeting = "";
for(var i = 0; i < Events.length; i++){
if(check == Object.keys(Events[i]) && check != "12/25"){
greeting = "Happy "+Object.values(Events[i]);
}
if(check == "12/25"){
greeting = "Merry Christmas";
}
}
for(var j = 0; j < c.length;j++){
var channel = bot.channels.get(c[j]);
if(greeting != ""){
channel.sendMessage(greeting);
}
//channel.sendMessage('test');
}
}, 3600000,)
This is the function in the ready event. Events is a json file with an array of key value pairs. c is an array with channel ids. so in the json file I have a test date that when I ran for the current day it would work, but when I change the day to the next and then wait for that time to come, nothing happens but the time should have passed and the variables should have all been reset so any ideas? Also, I have the bot hosted on glitch sending itself ping requests as well as using uptime robot which has indicated there has not been a down for 60 hours. The only reason I could think of for the cause is that maybe glitch puts the bot to sleep for a split second and it causes the interval to constantly reset, but then that would mean the pings and uptime robot are having no effect. Also, if anyone has a clever work around I would be grateful. The best I could do was just have a command that does this.
maybe because you didn't break function at the end like this
}
//channel.sendMessage('test');
}
}, 3600000);
and maybe that comma making the value act as an integer and more value going to be put in there.
Since I've updated to the new version of the library things have changed. However, this was long ago and I was hosting on glitch at the time, and that ended up being the problem. Glitch will still put to sleep the bot even if you are pinging it with uptime robot as they prevent ping spam.

How can I check if 2 hours has passed?

I want to check if 2hours passed then do some steps. This is what I've tried so far
var d = new Date();
var time = d.getHours() + d.getMinutes();
if(time >= 120) {
// Do something
}
You can use setTimeout function to do stuffs in 2 hours. To cancel the timeout task, simply use clearTimeout to stop it.
var timeoutId = setTimeout( function(){
alert( '2 hours passed' );
}, 2*60*60*1000 );
// clearTimeout( timeoutId );
I like momentjs
let twoHoursLater = moment().add({hours: 2})
after some time passes, this check will return true when 2 hours passes
moment().isAfter(twoHoursLater)
-> true
Oh, and a plugin "timer" based on moment, here
npm install moment-timer
then in javascript, use the duration and timer, like so
let timer = new moment.duration(2, 'hours').timer(callback);
timer.start();
function callback() {
/* magic happens */
}
Another simple way is to just use javascript's native timeout, in this example, a callback is invoked after 2 hours.
setTimeout(callback, 2 * 60 * 60 * 1000)
Your approach is not clear. #Thum Choon Tat answer is fine if you just want to do stuff without page refresh.Every page refresh will calculate the time from 0 second.If You want to check weather 2 hours passed or not ignoring page refresh, you have to set a reference time from which you will calculate how much time have been passed. You can use https://plugins.jquery.com/cookie/
This is Jquery Cookie to set reference time. then get current time as you are doing. now compare this current time with your reference time.

comparing time not working javascript

I am trying to compare the time now and a time in a future date. When these times are the same I want to show a message. However, the code below is not working. I have been checking the console and now.getTime() is never the same as end.getTime(), presumably as they are in ms?
Does anyone know how to overcome this? Following this answer here I believe it should work.
function compareTimes() {
var end = new Date("August 31, 2016 11:04:18");
var now = new Date();
if (now.getTime() == end.getTime()) {
clearInterval(timer);
document.getElementById('countup').innerHTML = 'EXPIRED!';
return;
}
}
setInterval(compareTimes, 1000);
setInterval will execute the function compareTimes every second and your function will compare the times at that very instant. It is highly unlikely that both the times will be same, hence you won't be able to set your div to EXPIRED . In order to overcome this i suggest you check if the time is greater than the current time i.e if (now.getTime() > end.getTime()) then set the state as EXPIRED in your div.

Decrement a variable once a day - Javascript

I'm trying to decrement a variable once a day. I have written the following code for that.
var counter = 10; //any value
setInterval(function() {
counter = counter - 1;
}, 86400000);
Is there a better or efficient way to achieve the same thing ?
P.S : - I do not wish to use any libraries.
The only thing I see you miss is to set the initial value of counter variable.
I would write:
var counter = 1000; // or any useful value
setInterval(function() {
--counter;
}, 24 * 60 * 60 * 1000); // this is more self-explanatory than 86400000, and, being evaluated just once, it will have a tiny effect on the performace of the script
I don't see any problem in the way you write it. You use interval, ok, but this is not the worst evil you may do to set up the variable value.
You may think of another solution with a function which returns you the current counter.
var initialValue = 20000;
function getCounter() {
return initialValue - Math.floor(Date.now() / 1000 / 60 / 60 / 24);
}
console.log(getCounter());
The difference is that it takes the current day number starting from the UNIX time beginning. Every day the day number will be increased, so the result of the function will be decreased by 1.
But still I don't see how this solution can be better than yours.
I'm not totally sure why, but using setInterval like this makes me uncomfortable.
If I were to require this, I would use something like this approach:
var counter = 10;
var timeout = new Date();
setInterval(function(){
if(new Date() >= timeout)
{
--counter; // the action to perform
timeout = new Date(timeout.getTime() + 86400000); // update the timeout to the next time you want the action performed
}
console.log(counter);
},1000); // every second is probably way more frequent than necessary for this scenario but I think is a decent default in general
One thing that this allows is to, for example, set the next timeout to midnight of tomorrow rather than being locked in to "X seconds since the previous execution". The key is the inversion of control - the action itself can now dictate when it should next run.
Though I would probably abstract away the details behind an interface accepting a start, interval, and action.
The biggest problem in my eyes is that you have to keep this one JS process running consistently for days at a time to have it do what you need. The world is not so perfect that things don't need an occasional reboot...including the average JS process.
Personally I would store a timestamp of my starting point, then (whenever I need to know how much time has elapsed) grab a new timestamp and use it to calculate how many days it has been. That way even if something interrupts my process I can still be right where I started.
Maybe use window.localStorage to save the last time, and if it is greater than 60*60*24 (seconds in a day) set the last time to this morning/now/1:00 and then decrease the value and save it.
Example:
var d = new Date();
var mins = -(1+d.getHours())*60+d.getMinutes();
var secs = mins*60+d.getSeconds(); // total seconds passed today from 1:00
var now = d.getCurrentTime():
var lastCheck = localStorage.getItem("lastCheck");
if (!lastCheck)
{
localStorage.saveItem("lastCheck",now-secs); // beginning of today
}
var dayPassed = now - lastCheck > 24*60*60; // change to see if a day has passed
if (dayPassed)
{
// save seconds
localStorage.setItem("counter",localStorage.getItem("counter")-1);
localStorage.saveItem("lastCheck",now-secs); // beginning of today
}
It makes more sense to me to check how many days have passed since a specific date and decrement that number of days from the counter. Mostly just because I wouldn't expect anybody to leave the same page open without the need or want to reload for days on end. I would do something like this:
counter = 365; // original counter
var start = new Date(2016, 03, 20); // original date
var now = new Date();
var days = Math.floor(Math.abs(start.getTime()-now.getTime())/(24*60*60*1000))
counter -= days;
That way every time you visited the page, it would be decremented correctly. Note that this ignores any issues with leap days or time zones. The example above would have a counter of 360 for me. And then if you did expect it to be open for days, reload it automatically with:
self.setTimeout(function(){document.location.reload()}, 86400000);

using if else statements with a timer

Im trying to set up a series of if else statements using a timer. Ideally, these if else statements would display images according to real time. However, if there is a way to set up my own timer and have the images display using if else statements that would also work. Here's what I'm thinking;
if (time < 7:00) {
document.getElementById("whatever").style.display="block";
}
Please assist if anyone knows the best possible solution for this particular problem. THANK YOU!!
If you just want a condition that becomes truthy when it's earlier than 7pm:
if (new Date().getHours() < 19) { }
The getHours() method returns the hour of the day between 0 and 23.
In a timer function it would look like this:
function doMagicStuff()
{
var now = new Date();
if (now.getHours() < 19) {
}
// other conditions based on time
}
// let it run approximately every second; doesn't have to be very accurate
setInterval(doMagicStuff, 1000);

Categories