-1

I am trying to understand Math.max(timeLeft/1000,0); returning its maximum value as 0. I did a lot of research as a noob. I read the w3schools's tutorial about Math and all its methods. However the value returning 0 is really confusing me. The full code is below.

var start = document.getElementById("start");
var dis = document.getElementById("display");
var finishTime;
var timerLength = 10;
var timeoutID;
dis.innerHTML = "Time Left: " + timerLength;
if(localStorage.getItem('myTime')){
    Update();
}
start.onclick = function () {
    localStorage.setItem('myTime', ((new Date()).getTime() + timerLength * 1000));
    if (timeoutID != undefined) window.clearTimeout(timeoutID);
    Update();
}

function Update() {
    finishTime = localStorage.getItem('myTime');
    var timeLeft = (finishTime - new Date());
    dis.innerHTML = "Time Left: " + Math.max(timeLeft/1000,0);
    timeoutID = window.setTimeout(Update, 100);
}

Also why is window.setTimeout(Update, 100); behaving as setInterval in this code?

The full working code is here

Note: I read this article and I'm trying to understand how localstorage is working with the date function.

Another note: There is nothing wrong with the code above. It is working as it should. I am just trying to understand a certain piece of code, which is really confusing. I now understand why it is returning as 0.

Community
  • 1
  • 1
Santosh
  • 3,477
  • 5
  • 37
  • 75
  • `finishTime - new Date()` is likely returning a negative number. `0` is larger than any negative number. – Felix Kling Jan 01 '17 at 09:52
  • Please update the question with a **runnable** [mcve] demonstrating the problem. Also, ask **one** question/question, not two. – T.J. Crowder Jan 01 '17 at 09:52
  • 4
    You need to learn how to use debugger to debug the code. Set some breakpoints, log the value of `timeLeft` and other vars, it shouldn't be hard to find out the reason. – Bryan Chen Jan 01 '17 at 09:53
  • new Date() is a object returning a current date. To test I used this code (new Date()).getTime(); It is returning current date and time in milliseconds. – Santosh Jan 01 '17 at 09:53
  • 1
    Question : can you tell us what is the output of `localStorage.getItem('myTime')` ? Remark : `aDate - new Date()` is likely to return a negative integer since `new Date` is *now*. –  Jan 01 '17 at 09:54
  • 2
    @T.J.Crowder: Since `Update` calls `window.setTimeout` again, one might argue that it does. At least I guess that's the behavior the OP is referring to. – Felix Kling Jan 01 '17 at 09:54
  • 2
    *"new Date() is a object returning a current date."* Yes, that is correct. If `finishTime` is a value representing a date in the *past*, then `new Date()` will return a larger value. A small value minus a large value results in a negative number. What `Math.max` does is very simply. If you get `0` as result, then the other number must be `<= 0`. It's not that complicated. – Felix Kling Jan 01 '17 at 09:55
  • @BryanChen Yes I did it a lot. If you run (finishTime - new Date()) on onclick event it should return a positive number as timerlength but it is returning negative number. – Santosh Jan 01 '17 at 09:58
  • 1
    I tried the jsfiddle, and it seems to work correctly: `timeLeft` is positive for 10 seconds until it goes negative and the visible timer stops at 0. What exactly is the problem here? – JJJ Jan 01 '17 at 10:02
  • @procrastinator Thanks I get that. I see that the finishTime is decreasing from the positive integer 10. So whenever I click on button, the value is updated. – Santosh Jan 01 '17 at 10:08
  • @FelixKling Thanks Now I get that. Even after refresh the finishTime is same as before when we set the value on onclick event. And it doesn't change until we click the button again. Thanks again. Also can you explain why setTimeout is behaving like setInterval? – Santosh Jan 01 '17 at 10:15
  • Again : can you tell us what is the output of `localStorage.getItem('myTime')` ? Copy-paste please ;-) –  Jan 01 '17 at 10:21
  • @procrastinator myTime: 1483266244327 in LocalStorage in console. It returns the current time when we first click on the button and keep going towards negative. Why this is going to negative too – Santosh Jan 01 '17 at 10:24

3 Answers3

3

timeLeft is negative, so 0 is the max value.

LF00
  • 27,015
  • 29
  • 156
  • 295
Marc Balmer
  • 1,780
  • 1
  • 11
  • 18
  • Yes I get it now. how the timeLeft is returning negative value. Also could you please explain why the setTimeout is behaving like setInterval ? – Santosh Jan 01 '17 at 10:19
  • setTimeout vs. setInterval has been discussed a few times already, e.g. here: http://stackoverflow.com/questions/729921/settimeout-or-setinterval – Marc Balmer Jan 01 '17 at 10:26
1

Math.max(timeLeft/1000, 0) return 0 when timeLeft is non-positive number.

window.setTimeout(Update, 100) is behaving as setInterval is that it call itself in loop every 100 just as the setInterval.

LF00
  • 27,015
  • 29
  • 156
  • 295
  • Thanks but I am not able to find that loop that make the setTimeout is executed evertime. Can you point it in code please. – Santosh Jan 01 '17 at 10:16
  • the setTimeout is in the Update function. Update execute every 100 in your code. So does the setTimeout. – LF00 Jan 01 '17 at 10:18
1

Actually Math.max does not always returns zero, otherwise you would always see "0" in the display span. It returns zero only when new Date() becomes greater than finishTime (after timerLength * 1000 ms = 10 * 1000 ms = 10 s).

About setTimeout, considering the following code, f calls setTimeout, which calls f after 1 sec, which calls setTimeout, and so on :

function f () {
  setTimeout(f, 1000);
}

The result is similar to setInterval but not exactly the same. Read the following article to know why (author : jQuery's father himself) : http://ejohn.org/blog/how-javascript-timers-work/.

var start = document.getElementById("start");
var dis = document.getElementById("display");
var finishTime;
var timerLength = 10;
var timeoutID;
var fakeStorage = (new Date()).getTime() + timerLength * 1000;
dis.innerHTML = "Time Left: " + timerLength;
if(fakeStorage){
  Update();
}
start.onclick = function () {
  fakeStorage = ((new Date()).getTime() + timerLength * 1000);
  if (timeoutID != undefined) window.clearTimeout(timeoutID);
  Update();
}

function Update() {
  finishTime = fakeStorage;
  var timeLeft = (finishTime - new Date());
  dis.innerHTML = "Time Left: " + Math.max(timeLeft/1000,0);
  timeoutID = window.setTimeout(Update, 100);
}
<button type="button" id="start">start</button>
<span id="display"></span>