Need help with time arithmetic in Javascript

Good evening. I would like to ask for assistance about time arithmetic. The time arithmetic in Javascript function addResumeBreakIntervals() and data push to array in the function are not working in my Pomodoro webpage that I assembled.

You’re just pushing a time string representing the time the function gets called to storage as many times as the value of repititions, so at the time I’m writing this reply, if you had 2 repetitions, then pomodoroArray would be ["11:58 AM", "11:58 AM"], as would backToWorkArray

function addResumeBreakIntervals() {
  var resumeInterval = document.getElementById("backToWorkInterval").value; // never actually gets used
  var resumeDuration = parseFloat(resumeInterval);
  var breakInterval = document.getElementById("breakInterval").value; // never actually gets used
  var breakDuration = parseFloat(breakInterval);
  var ctr = document.getElementById("repitition").value;
  var repeat = parseFloat(ctr);
  var resumeTime = new Date();
  var resumeHours = resumeTime.getHours(); // this is just a number
  var resumeMinutes = resumeTime.getminutes(); // this is just a number
  var breakTime = new Date(); // This is going to be almost the same as `resumeTime`, maybe a millisecond after
  var breakHours = breakTime.gethours(); // just a number
  var breakMinutes = breakTime.getminutes(); // just a number
  var timeNow = new Date();  // This is going to be almost the same as `resumeTime` and `breakTime, maybe a millisecond after
  var hoursNow = timeNow.getHours(); // just a number
  var minutesNow = timeNow.minutes(); // just a number
  while (repeat != 0) {
    // the following doesn't do anything, you're just changing the numbers in the variables above,
    // it has no effect on the date objects because those numbers are in no way connected to them.
    resumeMinutes = minutesNow + resumeDuration;
    if (resumeMinutes > 60) {
      resumeHours = resumeHours + 1;
      if (resumeHours > 12 || resumeHours > 24) {
        resumeHours = 0;
      }
    }

    breakMinutes = breakMinutes + breakDuration;
    if (breakMinutes > 60) {
      breakHours = breakHours + 1;
      if (breakHours > 12 || breakHours > 24) {
        breakHours = 0;
      }
    }
    // Now you just convert the date objects to locale strings, so at the time I'm wiriting this
    // reply, you're just getting the string "11:58 AM" over and over again.
    breakTimeString = String(
      breakTime.toLocaleTimeString("en-US", {
        hour12: true,
        hour: "numeric",
        minute: "numeric"
      })
    );

    resumeTimeString = String(
      resumeTime.toLocaleTimeString("en-US", {
        hour12: true,
        hour: "numeric",
        minute: "numeric"
      })
    );
    
    // Now you're just repeatedly pushing "11:58 AM" to storage over and over again:
    pomodoroArray.push(breakTimeString);
    sessionStorage.setItem("breakTimeString", JSON.stringify(pomodoroArray));
    backToWorkArray.push(resumeTimeString);
    sessionStorage.setItem("resumeTimeString", JSON.stringify(pomodoroArray));
    repeat = repeat - 1;
  }
}

If you use getHours or getMinutes, they’re literally just going to give you a number representing the hours/minutes of the date. Once you’ve got that number, it’s literally that, just a number. Altering it alters the number, it doesn’t change the date object it was extracted from. You need to actually set the values on the date object.

Also you have three date objects representing the current time rather than one, so it’s all going to go out of sync. This is incredibly complicated code, I would seriously spend some time simplifying it because it’s extremely hard to debug and fix

Edit: as a quick example for this function, take the resumeDuration, breakDuration and the repetitions, and return the two arrays of times. This isn’t really tested, so I assume there are a few bugs in it, but as a starting point:

function humanTime(dateObj) {
  return dateObj.toLocaleTimeString("en-US", {
    hour12: true,
     hour: "numeric",
     minute: "numeric"
  });
}

function addResumeBreakIntervals(resumeDuration, breakDuration, repetitions) {
  const time = new Date();
  const pomodoroArray = [];
  const backToWorkArray = [];

  // JS dates use milliseconds, so to add a
  // minute, it's the time + 60000.
  for (let i = 0; i < repetitions; i++) {
    time.setTime(time.getTime() + resumeDuration * 60000);
    pomodoroArray.push(humanTime(time));
    time.setTime(time.getTime() + breakDuration * 60000);
    backToWorkArray.push(humanTime(time));
  }
  return {
    pomodoroTimes: pomodoroArray,
    backToWorkTimes: backToWorkArray,
  };
}
1 Like

Thank you very much for determining the problem and the solution for my script @DanCouper. I will try executing your solution.