Is it possible to call setInterval based on time based? - javascript

I am displaying live news in my website and for that to get the latest data i am using setInterval for every 9 minutes as shown below
$(document).ready(function() {
displaylivenews();
setInterval(displaylivenews, 540000);
});
function displaylivenews() {
alert('calling ajax to getting latest data ');
}
All this works fine , my question is that , if the time is in between 7 Am to 9 AM , i want to call it more frequently that is for every 5 minutes ??
Is it possible to call setInterval based on time based ??
http://jsfiddle.net/mwv6r0df/

Answering your question, you can do the following:
function getRefreshPeriod()
{
var hour = new Date().getHours();
return (hour >= 7 && hour < 9) ? 300000 : 540000;
}
function displaylivenews() {
alert('calling ajax to getting latest data ');
setTimeout(displaylivenews, getRefreshPeriod());
}
setTimeout(displaylivenews, getRefreshPeriod());
I used setTimeout in order to correctly handle "border" cases.
For example, if a user opens a page at 08:46 AM, he will get updates at 08:51 (5 minutes later), 08:56, 09:01, 09:10 (9 minutes later, because it is not a "prime time" anymore).
However, keep in mind that setInterval and setTimeout do not guarantee to be precise. It is a better idea to calculate the time of next updating, and rely on it.
Another important note: new Date() will return the client's local time. So, actually, news will be updated more frequently between 7AM and 9AM of local time. If you have users from different time zones and want them to receive news more frequently between 7AM and 9AM in your time zone, then you may want to use getUTCHours.
For example, I am located in GMT+6 time zone, and if I had this website, it would be:
var hour = new Date().getUTCHours();
return (hour >= 1 && hour < 3) ? 300000 : 540000;
because 1AM and 3AM UTC are 7 AM and 9AM in UTC+6.

Related

Modify partially-functional code to delete cell contents based in the time input of a certain cell

I've got a current project which takes the time of a cell (in this case, C5), and if the current time is greater than the time input in cell C5, it deletes a range of cells. I'm using this as a rudimentary "auto clock-out" system that removes someone after their finish time, which is input in C5, has elapsed.
Here is the current code:
function CO1() {
var s = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('Timestamps');
var curTime = new Date()
var expTime = s.getRange("C5").getDisplayValue().split(":")
Logger.log(curTime.getHours() +":"+curTime.getMinutes())
Logger.log(expTime[0]+":"+expTime[1])
if (curTime.getHours() >= expTime[0] && curTime.getMinutes() >= expTime[1]){
Logger.log("Clear")
s.getRange('C3').clearContent(),s.getRange('C4').clearContent(),s.getRange('C5').clearContent(),s.getRange('E6').clearContent(),s.getRange('E7').clearContent();
}
}
This worked while operating between normal hours (09:00 - 17:00), but now, during quarantine, we're operating strange hours. Some of the finish times now end up into the early hours (such as 20:00 - 04:00). At midnight, it treats the time as being expired, and deletes all of the cell data.
Is there any way to mitigate this from happening, please?
Thanks!
How about:
if (curTime.getHours() >= 9 && curTime.getHours()<17){

Create a scheduled Greasemonkey script

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

How to reduce a store quantity count daily once using jQuery

I want to develop a script, which will reduce a numeric value -3 once a day, this script is for my store
<script type="text/javascript">
$(document).ready(function() {
var store_count = 952;
var Date_val = new Date();
//Daily once I need to reduce my store_count -3
if(Date_val == 'Here i have to check the condition for allowing this happen daily once') {
store_count = store_count-3;
$('#deducted_store_count').text(store_count);
}
});
</script>
<div id="deducted_store_count">952</div>
I am not storing this value in Database. Just I want to place this value in a div. As like I mentioned above.
I don't want to subtract the date as someone has flagged this question for subtraction of date, my question is different.
if my store count is 952 today, tomorrow it have to reduce to 949 and -3 for a each and every day.
OK. I'm going to tell you how, then I'm going to question very hard, "Why?"
Here's how:
var store_count = 952;
// 24 hours, 60 minutes per hour, 60 seconds per minute, 1000 milliseconds per second
var delay = 24 * 60 * 60 * 1000;
window.setInterval(
function () {
store_count = store_count - 3;
$('#deducted_store_count').text(store_count);
}, delay);
So here's my question, what are you thinking you're accomplishing here? Going down three per day, the store count would finally be down to zero after 317 days. How is this program going to run in any browser or Node.js server with an in-memory variable like store_count undisturbed for that length of time without any chance of a power outage or somebody closing down the software?
Data which is slowly going to be decremented or otherwise manipulated over a long period (anything over a few minutes) is usually stored in some kind of long term storage like a database, a file, localStorage in the browser, etc. Something that is persistent and can be guaranteed to still exist if something happens to the environment. But you're asking this question like you think "store_count" is going to be around to celebrate its next birthday.
Are you sure this data shouldn't be in MongoDB or something somewhere?

can setInterval drift over time?

I have 2 node.js webservers. I cache data inside webservers. I sync the cache load/clear based on system time. I have done time sync of all my hosts.
Now I clear cache every 15 mins using following code:
millisTillNexthour = "Calculate millis remaining until next hour"
setTimeout(function() {
setInterval(function() {
cache.clear();
}, 60000*15);
}, millisTillNexthour);
My expectation is even if this process runs for ever, cache will be cleared every 15th minute of each hour of the day.
My question is: can setInterval drift over time?
For eg: right now it clears cache at 10:00 10:15 10:30 10:45 11:00 ......
Can it happen that instead of 10:15 system time, setInterval gets executed at 10:20 system time when it was supposed to clear cache at 10:15??
I am not sure how this works. Please shed some light. I hope I explained my question well.
I'm probably more than a bit late to the party here, but this is how I solved this particular time-slipping problem just now, using a recursively called setTimeout() function instead of using setInterval().
var interval = 5000;
var adjustedInterval = interval;
var expectedCycleTime = 0;
function runAtInterval(){
// get timestamp at very start of function call
var now = Date.now();
// log with time to show interval
console.log(new Date().toISOString().replace(/T/, ' ').replace(/Z/, '') + " runAtInterval()");
// set next expectedCycleTime and adjustedInterval
if (expectedCycleTime == 0){
expectedCycleTime = now + interval;
}
else {
adjustedInterval = interval - (now - expectedCycleTime);
expectedCycleTime += interval;
}
// function calls itself after delay of adjustedInterval
setTimeout(function () {
runAtInterval();
}, adjustedInterval);
}
On each iteration, the function checks the actual execution time against the previously calculated expected time, and then deducts the difference from 'interval' to produce 'adjustedInterval'. This difference may be positive or negative, and the results show that actual execution times tend to oscillate around the 'true' value +/- ~5ms.
Either way, if you've got a task that is executing once a minute, and you run it for an entire day, using this function you can expect that - for the entire day - every single hour will have had 60 iterations happen. You won't have that occasional hour where you only got 59 results because eventually an entire minute had slipped.
setInterval is definitely drifting (although I agree that it should not be). I'm running a Node.js server with an interval of 30 seconds. On each tick, a few async web requests are made which from beginning to end take roughly 1 second. No other user-level/application processing happens in the intervening 29 seconds.
However, I notice from my server logs that over the course of 30 minutes, a drift of 100ms occurs. Of course, the underlying operating system is not to blame for the drift and it can only be some defect of Node.js's design or implementation.
I am very disappointed to notice that there is a bug in the NodeJS implementation of setInterval. Please take a look at here:
https://github.com/nodejs/node/issues/7346#issuecomment-300432730
You can use Date() object to set specific time and then add a certain number of milliseconds to the date.
It definitly can because of how Javascript works (See Event Loop)
Javascript event loop executes the setInterval queue when other queued events are finished. These events will take some time and it will effect your setInterval function's execute time and it will eventually drift away as time passes.
setInterval should not drift in a perfect world. It might be delayed due to other things taking up system resources. If you need a more precise solution to what you have, use the clock() function to " calibrate " your nodes.

Displaying another computer's time on a web page using Javascript? [duplicate]

This question already has answers here:
Clock on webpage using server and system time?
(8 answers)
Closed 9 years ago.
I am working on a very time-sensitive web application. One of the business rules given to me is that the application's behavior must always depend on the time on the web server, regardless of what time is on the client's clock. To make this clear to the user, I was asked to display the server's time in the web application.
To this end, I wrote the following Javascript code:
clock = (function () {
var hours, minutes, seconds;
function setupClock(updateDisplayCallback) {
getTimeAsync(getTimeCallback);
function getTimeCallback(p_hours, p_minutes, p_seconds) {
hours = p_hours;
minutes = p_minutes;
seconds = p_seconds;
setInterval(incrementSecondsAndDisplay, 1000);
}
function incrementSecondsAndDisplay() {
seconds++;
if (seconds === 60) {
seconds = 0;
minutes++;
if (minutes === 60) {
minutes = 0;
hours++;
if (hours === 24) {
hours = 0;
}
}
}
updateDisplayCallback(hours, minutes, seconds);
}
}
// a function that makes an AJAX call and invokes callback, passing hours, minutes, and seconds.
function getTimeAsync(callback) {
$.ajax({
type: "POST",
url: "Default.aspx/GetLocalTime",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
var date, serverHours, serverMinutes, serverSeconds;
date = GetDateFromResponse(response);
serverHours = date.getHours();
serverMinutes = date.getMinutes();
serverSeconds = date.getSeconds();
callback(serverHours, serverMinutes, serverSeconds);
}
})
}
return {
setup: setupClock
};
})();
The function passed in for updateDisplayCallback is a simple function to display the date on the web page.
The basic idea is that the Javascript makes an asynchronous call to look up the server's time, store it on the client, and then update it once per second.
At first, this appears to work, but as time goes by, the displayed time gets behind a few seconds every minute. I left it running overnight, and when I came in the next morning, it was off by more than an hour! This is entirely unacceptable because the web application may be kept open for days at a time.
How can I modify this code so that the web browser will continuously and accurately display the server's time?
Javascript's setInterval is not accurate enough to allow you to keep the time like this.
My solution would be:
Periodically get the server's time in milliseconds (it does not need to be very often as the two clocks will hardly deviate that much)
Get the client time in milliseconds
Calculate the clock deviation between server and client (client-server)
Periodically update the display of the clock by getting the client time and adding the clock deviation
Edit:
To be more accurate, you could measure the round trip time of the server's request, divide it by 2 and factor that delay into the clock deviation. Assuming round trips are symmetrical in their duration, this would give a more accurate calculation.
setInterval is not a reliable way to schedule time critical events. It may take less or more than 1000ms to run your callback depending on how busy JavaScript it is at the moment.
A better approach would be to take a shorter interval and use new Date().getTime() to check if a second has passed.
The minimum interval browsers allow is as high 10.
Thanks for the answers. I have up-voted both answers so far as they contain useful information. However, I am not using the exact answer prescribed in either answer.
What I finally decided on is a bit different.
I wrote about what I learned on my personal web page.
First of all, I now understand that using setInterval(..., 1000) is not good enough to have something done once per second for a long time. However, 'polling' the time with a much shorter interval looking for the second to change seems very inefficient to me.
I decided that it does make sense to keep track of the 'offset' between the server time and the client time.
My final solution is to do the following:
(1) Do an AJAX call to the server to get the time. The function also checks the client time and computes the difference between the server time and the client time, in milliseconds. Due to network latency and other factors, this initial fetch may be off by a few seconds. For my purposes, this is okay.
(2) Execute a tick function. Each time tick executes, it checks how long it has been since the last time tick executed. It will use this time to compute an argument to be passed to setTimeout so that the time display is updated approximately once per second.
(3) Each time the tick function computes the time to be displayed, it takes the client time and adds the difference that was computed in step (1). This way, I don't depend upon the client to have the time set correctly, but I do depend upon the client to accurately measure elapsed time. For my purposes, this is okay. The most important thing is that regardless of how setTimeout may be inaccurate or interrupted by other processes (such as a modal dialog, for instance), the time displayed should always be accurate.

Categories

Resources