I realized that a change in system time is not immediately reflected in javascript, event if I use a new Date object. It is only updated every minute.
var fakeElapsed = 0;
$(document).ready(function(){
var oldTime = 0;
function fakeTimeLoop(time){
fakeElapsed+=(time-oldTime);
oldTime = time;
$("div").html(fakeElapsed);
}
var clock = new Date();
var start = clock.getTime();
oldTime = clock.getTime();
setInterval(function(){
var clock2 = new Date();
var end = clock2.getTime();
var elapsed = end-start;
if(elapsed%5===0){
fakeTimeLoop(end);
}},
1
);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div></div>
</body>
Time code, if you would turn time forward (or backwards), it takes a minute to change the time elapsed.
Is there anyway to update to the system time every second?
Edit: for those who are confused, a change in system is not reflected immediately on Chrome and Opera, but on IE and Mozzila, it is immediately reflected, I assume its order to avoid expensive system calls every time it needs to build a new Date object.
What I am looking for: is that anyway to get the current system time in chrome/opera or detect a change in system time immediately?
It's not exactly clear to me what you're trying to accomplish, but your setInterval is programmed to execute every millisecond (the second parameter is in milliseconds), but browsers treat any value less than 10 as equal to 10. Even with that restriction, the timing isn't guaranteed to be exact, so the function may well execute every 11, 12, 13, etc. milliseconds.
When you change your computer date/time and refresh the web page, new Date() will not return correct date/time. After 20-25 seconds it will return correct time. Probably it is a browsers' bug (I tested on Windows 10, Edge an Chrome).
Related
As I was looking for a simple Stopwatch implementation in JS, I found this code http://codepen.io/_Billy_Brown/pen/dbJeh/
The problem is that it's not working fine, the clock go way too fast. I got 30 seconds on the screen when i got only 23 seconds on my watch.
And I don't understand why. The timer function is called every millisecond and should be updating the time correctly.
setInterval(this.timer, 1);
Is the problem coming from the browser or from the JS code.
Thanks in advance.
The timers in Javascript doesn't have millisecond precision.
There is a minimum time for the interval, which differs depending on the browser and browser version. Typical minimums are 4 ms for recent browsers and 10 ms for a little older browsers.
Also, you can't rely on the callback being called at exact the time that you specify. Javascript is single threaded, which means that if some other code is running when the timer triggers a tick, it has to wait until that other code finishes.
In fact the code you gave is imitating time flow, but it is not synchronized with system time.
Every millisecond it just invokes the function this.time, which performs recounting of millis, seconds and so on
without getting native system time, but just adding 1 to variable representing "imaginary milliseconds".
So we can say that resulting pseudo-time you see depends on your CPU, browser and who knows what else.
On our modern fantastically fast computers the body of this.time function is being executed faster than millisecond (wondering what would happen on Pentium 2 with IE5 on board).
Anyhow there is no chance for the this.time to be executed exactly in particular fixed period on all computers and browsers.
The simplest correct way to show the time passed since startpoint according to the system time is:
<body>
<script>
var startTime = new Date() // assume this initialization to be start point
function getTimeSinceStart()
{
var millisSinceStart = new Date() - startTime
, millis = millisSinceStart % 1000
, seconds = Math.floor(millisSinceStart / 1000)
return [seconds, millis].join( ':' )
}
(function loop()
{
document.title = getTimeSinceStart() // look on the top of page
setTimeout( loop, 10 )
}())
</script>
</body>
P.S. What #Guffa says in his answer is correct (generally for js in browsers), but in this case it does not matter and not affect the problem
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 am trying to run a function for each milliseconds, In order to achieve so, I just preferred setInterval concept in javascript. My code is given below,
HTML:
<div id=test>0.0</div>
Script:
var xVal = 0;
var xElement = null;
xElement = document.getElementById("test");
var Interval = window.setInterval(startWatch, 1);
function startWatch(){
xVal += 1;
xElement.innerHTML = xVal;
}
so the above code is working fine. But while I am testing the result with a real clock, the real clock requires 1000 milliseconds to complete 1 second, at the same time the result require more than 1000 milliseconds to complete a second.
DEMO
Can anybody tell me,
Is there any mistakes with my code? If yes then tell me, How to display milliseconds accurately.?
There are no mistakes in your code, but JavaScript timers (setInterval and setTimeout) are not precise. Browsers cannot comply with such a short interval. So I'm afraid there is no way to precisely increment the milliseconds by one, and display the updates, on a web browser. In any case, that's not even visible to the human eye!
A precise workaround would involve a larger interval, and timestamps to calculate the elapsed time in milliseconds:
var start = new Date().getTime();
setInterval(function() {
var now = new Date().getTime();
xElement.innerHTML = (now - start) + 'ms elapsed';
}, 40);
You can't. There is a minimum delay that browsers use. You cannot run a function every millisecond.
From Mozilla's docs:
...4ms is specified by the HTML5 spec and is consistent across browsers...
Source: https://developer.mozilla.org/en-US/docs/Web/API/window.setTimeout#Minimum.2F_maximum_delay_and_timeout_nesting
The DOM can't actually update 1000 times per second. Your monitor can't even display 1000 frames in one second, for that matter. Calculate the difference between the start time and current time in milliseconds within your function and use that:
(function(){
var xElement = document.getElementById("test");
var start = new Date;
(function update(){
xElement.innerHTML = (new Date - start);
setTimeout(update, 0);
})();
}();
Updated fiddle
You can't do so using your method because of the delay rendering the HTML and running the interval. Doing it this way will display the time correctly at about 60FPS.
http://jsfiddle.net/3hEs4/3/
var xElement = null;
var startTime = new Date();
xElement = document.getElementById("test");
var Interval = window.setInterval(startWatch, 17);
function startWatch(){
var currentTime = new Date();
xElement.innerHTML = currentTime - startTime;
}
You might also want to look into using requestanimationframe instead of a hardcoded setInterval like that.
The setInterval callback probably does not happen with millisecond accuracy, since the thread the timer is running on might not even actually be running when the time is up, or the browser throttles events, or any other of quite a few things.
In addition, since most Javascript engines are single threaded, what the implementation of setInterval might do is once it triggers, run your callback, and then reset the clock for the next call. Since you're doing some DOM manipulation, that might take several milliseconds on its own.
In short, you're expecting a Real Time Operating System behavior from an interpreter running inside of another application, on top of what is more than likely not an RTOS.
I had the same question and couldn't find any working solution, so I created one myself. The code below essentially calls five setTimouts every 5 ms, for each ms between 5 and 10. This circumvents the minimum 4 ms constraint, and (having checked in Firefox, Chrome, and Opera) works fairly well.
const start = performance.now();
let newNow = 0;
let oldNow = 0;
const runner = function(reset) {
// whatever is here will run ca. every ms
newNow = performance.now();
console.log("new:", newNow);
console.log(" diff:", newNow - oldNow);
oldNow = newNow
if (newNow - start < 1000 && reset) {
setTimeout(function() {
runner(true);
}, 5);
for (let i = 6; i < 11; i++) {
setTimeout(function() {
runner(false);
}, i);
}
}
};
runner(true);
It could of course be written more elegantly, e.g. so that you can more easily customize things like the graduation (e.g. 0.5 ms or 2 ms instead of 1 ms), but anyway the principle is there.
I know that in theory you could call 5 setIntervals instead, but that would in reality cause a drift that would quickly ruin the ms precision.
Note also that there are legitimate cases for the use. (I for one need continual measurement of touch force, which is not possible otherwise.)
I have a countdown script that gets the live time and subtracts it from a set time. It all works apart from the fact that it doesn't update unless you refresh your page. The setInterval at the bottom of my function instructs the function to run every one second, but it doesn't seem to be doing that...
Can anybody help?
Here is my jsfiddle: http://jsfiddle.net/4yMZy/
Each time cCountDown runs, its is calculating the time left like so:
nDates = new Date(datetime);
xDay = new Date("Fri, 26 May 2012 16:34:00 +0000");
timeLeft = (xDay - nDates);
The value of datetime there never changes from one run to another. So cCountDown is constantly running, but is always comparing the difference between the same two dates. Since the same two dates are used, the difference is always the same, so you do not see any countdown occur.
You could change nDates = new Date(datetime); to nDates = new Date(); and it will start counting down, but I am not sure why you are getting datetime from some server in the first place.
There are some other issues with your code as well. You should run it through jslint or jshint.
If changed your code to http://jsfiddle.net/4yMZy/7/
So it fetches the time and updates the seconds according to the set interval.
Edit:
jsfiddle actually provides a button for that on the top.
I am working on a little script that warns the user that his session is about to time out and his/her changes might not get saved.
On any browser, that works pretty well and I implemented a solution that just uses setTimeout to trigger a dialog box after a certain amount of time (unless the user takes certain actions in between).
On iOS Safari, however, this approach doesn't work, as the setTimeout gets "halted" while the user navigates to another app on his/her phone. Once the user opens Safari again and comes back to the page, the timer continues where it left off, rather than looking at the total time that expired.
Any suggestions on how to approach a session timeout warning that doesn't break on the iPhone?
Set the end time of the session in a variable.
Instead of using a counter, use javascript's date:
// get a date object
var today = new Date();
// ask the object for some information
var hours = today.getHours();
var minutes = today.getMinutes();
var seconds = today.getSeconds();
var theHour = today.getHours();
Compare the end time to the current time every second
Disclaimer: Handle case where user returns and session has ended.