Home > OS >  Transforming minutes to ms giving unexpected result
Transforming minutes to ms giving unexpected result

Time:07-24

Im developing a chess clock. The thing is that when Im retrieving the minutes and seconds from the DOM and transforming it with msToClockFormat I'm getting 100 times extra minutes. However, For more I look at the function, the more convinced I am that is working as it should be. The minutes are being divided by 60000, 1000 times 60`, and I dont see the error. Thanks.

let btn1 = document.getElementById("btn1");
let btn2 = document.getElementById("btn2");
let resetBtn = document.getElementById("reset");

let ms1 = stringTimeToMs(btn1.innerHTML);
let ms2 = stringTimeToMs(btn2.innerHTML);

let player1 = true;
let reset = false;

function tick() {
  if (!reset) {
    if (player1) {
      btn1.innerHTML = msToClockFormat(--ms1);
    } else {
      btn2.innerHTML = msToClockFormat(--ms2);
    }
  }
}

function msToClockFormat(ms) {
  let minutes = Math.floor(ms / 60000);
  let seconds = Math.floor((ms % 60000) / 1000);
  return minutes   ":"   (seconds < 10 ? "0"   seconds : seconds);
}

function stringTimeToMs(time) {
  let minutes = time.split(":")[0];
  let seconds = time.split(":")[1];
  return (minutes * 60   seconds) * 1000;
}

var myInterval = setInterval(tick, 1);

btn1.addEventListener("click", () => {
  player1 = false;
  reset = false;
})

btn2.addEventListener("click", () => {
  player1 = true;
  reset = false;
})

resetBtn.addEventListener("click", () => {
  btn1.innerHTML = "05:00";
  btn2.innerHTML = "05:00";
  player1 = true;
  ms1 = 5 * 60 * 1000;
  ms2 = 5 * 60 * 1000;
  reset = true;
})
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Clock</title>
  <link rel="stylesheet" href="https://unpkg.com/@picocss/pico@latest/css/pico.min.css">
  <script src="script.js" defer></script>
</head>

<body>
  <main >
    <div >
      <button  id="btn1">3:00</button>
    </div>

    <div >
      <button  id="btn2">3:00</button>
    </div>

    <div >
      <button id="reset">RESET</button>
    </div>

  </main>

</body>

</html>

CodePudding user response:

You'd probably have a better time keeping your state in your code, and just writing it into the DOM elements.

I changed the tick interval to 1000ms (because it's unlikely setInterval would work correctly with 1ms), but even so it's not guaranteed that your function will be called exactly 1000ms apart, so it would be better to look at the wall clock ( new Date()) to see how much time actually elapsed since the last "tick".

let btn1 = document.getElementById("btn1");
let btn2 = document.getElementById("btn2");
let resetBtn = document.getElementById("reset");

let ms1 = 300000;
let ms2 = 300000;

let player1 = true;
let reset = false;

function update() {
  btn1.innerHTML = msToClockFormat(ms1);
  btn2.innerHTML = msToClockFormat(ms2);
}

function tick() {
  if (!reset) {
    if (player1) {
      ms1 -= 1000;
    } else {
      ms2 -= 1000;
    }
  }
  update();
}

function msToClockFormat(ms) {
  let minutes = Math.floor(ms / 60000);
  let seconds = Math.floor((ms % 60000) / 1000);
  return minutes   ":"   (seconds < 10 ? "0"   seconds : seconds);
}

update();
var myInterval = setInterval(tick, 1000);

btn1.addEventListener("click", () => {
  player1 = false;
  reset = false;
})

btn2.addEventListener("click", () => {
  player1 = true;
  reset = false;
})

resetBtn.addEventListener("click", () => {
  player1 = true;
  ms1 = 5 * 60 * 1000;
  ms2 = 5 * 60 * 1000;
  reset = true;
})
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Clock</title>
  <link rel="stylesheet" href="https://unpkg.com/@picocss/pico@latest/css/pico.min.css">
  <script src="script.js" defer></script>
</head>

<body>
  <main >
    <div >
      <button  id="btn1"></button>
    </div>

    <div >
      <button  id="btn2"></button>
    </div>

    <div >
      <button id="reset">RESET</button>
    </div>

  </main>

</body>

</html>

CodePudding user response:

Inside StringTimeToMs, seconds is being read as String input "00" as opposed to integer. As a result, adding seconds in return (minutes * 60 seconds) * 1000; is concatenating "00" to the end of the number, making the number larger. Use parseInt to read the integer value.

function stringTimeToMs(time) {
    let minutes = time.split(":")[0];
    let seconds = parseInt(time.split(":")[1]);
    return (minutes * 60   seconds) * 1000;
}
  • Related