I wonder how can detect or know when new day is coming by using jquery or others jquery library.
For examples:
Assume, right now is 2016/06/23 23:59:50. And when second come to 2016/06/24 00:00:00, jquery can detect an event.
I know we can use setTimeOut or setInterval and check every seconds when new day is coming.
But i don't want to use these methods above, what methods of jquery do we detect ?
There's no automatic event that's triggered when the date changes. What you can do is calculate the time until the date changes, and use setTimeout to run a function when that happens.
var now = new Date;
var midnight = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1);
setTimeout(function() {
alert("It's tomorrow!");
}, midnight.getTime() - now.getTime());
The arguments to new Date() are the components of the date and time. Leaving out the time arguments defaults them all to 0. So adding 1 to the date and omitting the time will return the time of the next midnight.
You could write a little JavaScript class that continuously samples the time and fires an event when it happens. You listed jQuery, so let's use that to handle the events.
First, let's make the class which samples the time:
function DayChecker() {
var self = this;
// Get a copy of now to compare against
self.lastDate = new Date();
// A function that compares now to the lastDate, and fires the event
// if different, and resets the lastDate
self.sample = function() {
var tempDate = new Date();
// Compare the day component of the last sampled time to the
// current time
if (self.lastDate.getDay() != tempDate.getDay()) {
// It changed, so fire the event!
$(self).triggerHandler('daychange');
};
// Update the last sampled date so this can run forever and
// trigger on every day change
self.lastDate = tempDate;
}
// for illustration, a function that force changes the last date
// to trigger the event
self.forceChange = function() {
// Add 1 day to the last sample time to trip the event
self.lastDate.setTime(self.lastDate.getTime() + (1 * 86400000));
};
// Now start sampling every second (or whatever accuracy you need)
setInterval(self.sample, 1000);
};
Now we create a new instance of this helper class:
var dayChecker = new DayChecker();
And listen for the event I called "daychange":
$(dayChecker).on('daychange', function() {
alert('new day!');
});
And finally, run the function that changes the date for testing purposes after a few seconds:
setTimeout(function() {
// Testing only!
dayChecker.forceChange();
}, 5000);
You should see the alert after five seconds.
A jsFiddle
Related
So I'm creating a clock for my website, and I have thought of 2 approaches to it..
1)
var today = new Date();
this.start = function() {
this.update();
setInterval(this.update,1000);
}
this.update = function() {
today.setSeconds(today.getSeconds() + 1);
}
or
2)
var today = new Date();
this.start = function() {
this.update();
setInterval(this.update,1000);
}
this.update = function() {
today = new Date();
}
Which would be better? Generating a new date every second or just updating? (or perhaps a third approach)
It's much better for you to use new Date() for each loop because the interval used on setInterval will not be 100% constant.
new Date() will be accurate regardless of setInterval variances
Here's a snippet from an answer I gave a couple days ago. It explains the issue with using setInterval with fixed-value incrementing (or decrementing).
Beware of creating timers that increment with a fixed value
In your code, you have
setTimeout(() => this.count--, 1000);
The intention is for you to decrement your count property once every second, but this is not the behavior you will be guaranteed.
Check out this little script
var state = {now: Date.now()};
function delta(now) {
let delta = now - state.now;
state.now = now;
return delta;
}
setInterval(() => console.log(delta(Date.now())), 1000);
// Output
1002
1000
1004
1002
1002
1001
1002
1000
We used setInterval(fn, 1000) but the actual interval varies a couple milliseconds each time.
The problem is exaggerated if you do things like switch your browser's focus to a different tab, open a new tab, etc. Look at these more sporadic numbers
1005 // close to 1000 ms
1005 // ...
1004 // a little variance here
1004 // ...
1834 // switched focus to previous browser tab
1231 // let timer tab run in background for a couple seconds
1082 // ...
1330 // ...
1240 // ...
2014 // switched back to timer tab
1044 // switched to previous tab
2461 // rapidly switched to many tabs below
1998 // ...
2000 // look at these numbers...
1992 // not even close to the 1000 ms that we set for the interval
2021 // ...
1989 // switched back to this tab
1040 // ...
1003 // numbers appear to stabilize while this tab is in focus
1004 // ...
1005 // ...
So, this means you can't rely upon your setTimeout (or setInterval) function getting run once per 1000 ms. count will be decremented with much variance depending on a wide variety of factors.
To work around this, you need to use a delta. That means before each "tick" of your timer, you need to take a timestamp using Date.now. On the next tick, take a new timestamp and subtract your previous timestamp from the new one. That is your delta. Using this value, add it to the Timer's total ms to get the precise number of milliseconds the timer has been running for.
I want to reset a variable during midnight. Every night.
I'm trying to build this function with Moment.js for Node but I can't seem to get the recurring part to work properly.
This is what I got so far.
// Calculate time to midnight
function timeToMidnight(){
var midnight = new Date();
midnight.setHours(0,0,0,0);
var now = new Date();
var msToMidnight = midnight - now;
console.log(' it is ' + msToMidnight + 'ms until midnight');
return msToMidnight;
};
// Reset counter at midnight
setTimeout(function(){
console.log("midnight, do something");
}, timeToMidnight());
How can I best make it recurring at midnight, every night?
Thanks in advance.
If you're using moment, consider instead this implementation
var moment = require('moment');
function timeToMidnight() {
var now = new Date();
var end = moment().endOf("day");
return end - now + 1000;
}
Like your function, this takes now milliseconds and calculates the number of milliseconds until midnight, but this is supported directly when using moment, which is nice. Add 1 extra second (1000 milliseconds) to get to the next day.
A typical pattern is for a function to call itself after a timeout.
function roundMidnight() {
console.log('at midnight');
setTimeout(roundMidnight,timeToMidnight());
}
setTimeout(roundMidnight,timeToMidnight());
Pretty generic, in fact depending on the value returned, you could schedule anything anytime, pretty useful, seem like someone must have thought of that.
node-schedule
A cron-like and not-cron-like job scheduler for Node.
And they did. Maybe what you really want is node-schedule. It looks like it's not really actively developed now, though.
So I've got this JavaScript clock I'm working on and I want it to be perfectly synced with the clients' system clock. I know how to get the current time using a Date object and I know how to run the update function every 60000 milliseconds (1 minute). The thing is that the client might load the page when half a minute has already passed, making the clock lag behind with 30 seconds. Is there any way to just run the update function when the minute-variable actually changes? (I only want minute-precision.)
How I get the current time:
var time = new Date();
var currentHour = time.getHours();
var currentMinute = time.getMinutes();
How I run the update function every 60000 ms:
setInterval(update,60000); //"update" is the function that is run
When the user logs in, get the current time and seconds of the minute, subtract 60 to get the remaining seconds, then multiply to set the timer
var time = new Date(),
secondsRemaining = (60 - time.getSeconds()) * 1000;
setTimeout(function() {
setInterval(update, 60000);
}, secondsRemaining);
First, you have to understand that timers in javascript are not guaranteed to be called on time so therefore you cannot be perfectly synced at all times - javascript just isn't a real-time language like that. It is single threaded so a timer event has to wait for other javascript that might be executing at the time to finish before a timer can be executed. So, you must have a design that still does as best as possible even if the timer is delayed (called later than it's supposed to be).
If you wanted to try to stay as close to aligned and do the fewest screen updates and be the most friendly to mobile battery life, I'd suggest this self-aligning code which realigns itself on each tick based on the time remaining until the next minute change:
function runClock() {
var now = new Date();
var timeToNextTick = (60 - now.getSeconds()) * 1000 - now.getMilliseconds();
setTimeout(function() {
update();
runClock();
}, timeToNextTick);
}
// display the initial clock
update();
// start the running clock display that will update right on the minute change
runClock();
This has the advantage that it only calls the update once on the next minute boundary.
Working demo: http://jsfiddle.net/jfriend00/u7Hc5/
var time = new Date();
var currentHour = time.getHours();
var currentMinute = time.getMinutes();
var currentSecond = time.getSeconds();
var updateinterval = setInterval(startTimer,(60-currentSecond)*1000);
function startTimer(){
clearInterval(updateinterval);
setInterval(update,60000);
}
function update(){
var time = new Date();
console.log(time.getSeconds());
}
I would set an interval to run each second, then check if time.getSeconds() == 0. This way you could execute an action whenever a new minute starts, based on the client time.
I need to create a special kind of script.
I want to show a message at certain times of the day. I've tested the code in Firebug Console and it works. The code is:
//Getting the hour minute and seconds of current time
var nowHours = new Date().getHours() + '';
var nowMinutes = new Date().getMinutes() + '';
var nowSeconds = new Date().getSeconds() + '';
var this_event = nowHours + nowMinutes + nowSeconds;
//172735 = 4PM 25 Minutes 30 Seconds. Just checked if now is the time
if (this_event == "162530") {
window.alert("Its Time!");
}
I feel that the Script is not running every second. For this to work effectively, the script has to be able to check the hour minutes and second "Every Second". I'm not worried about the performance, I just have to be accurate about the timing (to the second).
How do I do this?
Of course the script isn't running each second, GM-scripts run once when the document has been loaded.
Calculate the difference between the current time and the target-time and use a timeout based on the difference:
var now=new Date(),
then=new Date(),
diff;
then.setHours(16);
then.setMinutes(15);
then.setSeconds(30);
diff=then.getTime()-now.getTime();
//when time already has been reached
if(diff<=0){
window.alert('you\'re late');
}
//start a timer
else{
window.setTimeout(function(){window.alert('it\'s time');},diff);
}
Javascript doesn't guarantee your timeouts and other such events fire exactly on-time.
You should compare two Date objects using >= and remove the timeout or what ever other method you're using for tracking the time inside the matching if (and then reset it if necessary).
For more details see: https://stackoverflow.com/a/19252674/1470607
Alternatively you can use string comparison (but with caveats): https://stackoverflow.com/a/6212411/1470607
I have a scenario where one client PC will be driving multiple LCD displays, each showing a single browser window. These browser windows show different data which is on an animated cycle, using jquery.
I need to ensure that both browsers can be synched to rotate at exactly the same time, otherwise they'll animate at different times.
So my question is - can I trigger jquery to alternate the content based on the local PC clock?
eg each time the clock seconds == 0, show version 1, each time clock seconds == 30, show version 2 etc?
This is (in my experience) the most precise way of getting timers to trigger as closely as possible to a clock time:
// get current time in msecs to nearest 30 seconds
var msecs = new Date().getTime() % 30000;
// wait until the timeout
setTimeout(callback, 30000 - msecs);
Then, in the callback, once everything is done, do the same again to trigger the next event.
Using setInterval causes other problems, including clock drift. The calculation based on the current time accounts for the time executing the callback itself.
You'll still also need to use Date().getTime() as well to figure out which frame of your animation to show.
The whole thing would look something like this:
function redraw() {
var interval = 30000;
// work out current frame number
var now = new Date().getTime();
var frame = Math.floor(now / interval) % 2; // 0 or 1
// do your stuff here
.. some time passes
// retrigger
now = new Date().getTime();
setTimeout(redraw, interval - (now % interval));
}
redraw();
working demo at http://jsfiddle.net/alnitak/JPu4R/
The answer is: yes you can.
Use Date.getTime() to monitor time
Trigger your js function every 30 seconds
You could do something like this.
This way, no matter when you launched the different browsers, their rotations would be in sync.
var t=setInterval("check()",1000);
function check(){
var d = new Date();
if(d.getSeconds() == 0)
{
alert('do something');
} else if (d.getSeconds() == 30)
{
alert('do something else');
}
}
Why not launch one window from the other - that way the parent window will have complete control over when the animation starts, because they are in the SAME PROCESS. No clocks required.