3

still new to learning JavaScript. I want to loop through some values. If value is greater or equal to a certain number, then break the loop and get the previous number. For example:

var time = [14, 35];
var interval = 40; // in minutes
var startTime = [10, 40];

var timeFormatted = '2019-02-04 '+time[0]+':'+time[1];
var startTimeFormatted = '2019-02-04 '+startTime[0]+':'+startTime[1];

var dtTime = new Date(timeFormatted);
var dtStartTime = new Date(startTimeFormatted);

var currentTime = dtStartTime;
for(i = 0; i < 20; i++) {
    var previouslySelectedTime = currentTime;
    currentTime.setMinutes(currentTime.getMinutes() + interval);
    currentTime = new Date(currentTime);
    if(currentTime >= dtTime) {
        break;
    }
}

alert(previouslySelectedTime);

The final time result of beforeTime should be 14:00:00 but it is showing 14:40:00. What could be wrong?

5

If you look at currentTime, it is referencing a Date object. So, when you execute the next code:

var previouslySelectedTime = currentTime;

the variable previouslySelectedTime will reference the same object that is referenced by currentTime. Then later you execute:

currentTime.setMinutes(currentTime.getMinutes() + interval);

that will change the object referenced by both, currentTime and previouslySelectedTime. The easy fix to this will be to create a new Date from currentTime before assigning it to the mentioned variable:

var previouslySelectedTime = new Date(currentTime);

Also, after fixing this, there is no need of the next line:

currentTime = new Date(currentTime);

Example

var time = [14, 35];
var interval = 40; // in minutes
var startTime = [10, 40];

var timeFormatted = '2019-02-04 ' + time[0] + ':' + time[1];
var startTimeFormatted = '2019-02-04 ' + startTime[0] + ':' + startTime[1];

var dtTime = new Date(timeFormatted);
var currentTime = new Date(startTimeFormatted);
var previouslySelectedTime;

for (let i = 0; i < 20; i++)
{
    previouslySelectedTime = new Date(currentTime);
    currentTime.setMinutes(currentTime.getMinutes() + interval);

    if (currentTime >= dtTime)
        break;
}

alert(previouslySelectedTime);

Simplified version:

Even more, you could make some simplifications in your code if you use the methods that Date() object provides and a while loop.

var time = [14, 35];
var interval = 40; // in minutes
var startTime = [10, 40];

var dtTime = new Date();
dtTime.setHours(time[0], time[1], 0);
var currentTime = new Date();
currentTime.setHours(startTime[0], startTime[1], 0);
var previouslySelectedTime;

while (currentTime < dtTime)
{
    previouslySelectedTime = new Date(currentTime);
    currentTime.setMinutes(currentTime.getMinutes() + interval);    
}

alert(previouslySelectedTime);

  • I'd like to know why someone -1 to this answer, especially if this works – pixie123 Apr 22 at 4:52
5

you can use do while for this purpose

where the loop iterate at least once before the condition is evaluated, if true continue else break.

var time = [14, 35];
var interval = 40; // in minutes
var startTime = [10, 40];

var timeFormatted = '2019-02-04 '+time[0]+':'+time[1];
var startTimeFormatted = '2019-02-04 '+startTime[0]+':'+startTime[1];

var dtTime = new Date(timeFormatted);
var dtStartTime = new Date(startTimeFormatted);

var currentTime = dtStartTime;
var previouslySelectedTime = null;
do {
    var previouslySelectedTime = currentTime;
    currentTime.setMinutes(currentTime.getMinutes() + interval);
    currentTime = new Date(currentTime);

} while (!(currentTime < dtTime));

alert(previouslySelectedTime);
2

A small change can solve your problem.

var previouslySelectedTime = new Date(currentTime);//line no : 10

Reason:

here javascript is copy reference only. That's why, when currentTime change then previouslySelectedTime also change.

Solution:

You should apply Deep copy here.

https://medium.com/@Farzad_YZ/3-ways-to-clone-objects-in-javascript-f752d148054d

1

You are creating a reference by the following line

var previouslySelectedTime = currentTime;

So after this when you setMinutes on currentTime it also changes previouslySelectedTime

.You need to copy the value of currentTime and then assign it to previouslySelectedTime using JSON.parse(JSON.stringify())

var time = [14, 35];
var interval = 40; // in minutes
var startTime = [10, 40];

var timeFormatted = '2019-02-04 '+time[0]+':'+time[1];
var startTimeFormatted = '2019-02-04 '+startTime[0]+':'+startTime[1];

var dtTime = new Date(timeFormatted);
var dtStartTime = new Date(startTimeFormatted);

var currentTime = dtStartTime;
var previouslySelectedTime;

for(let i = 0; i < 20; i++) {
    previouslySelectedTime = JSON.parse(JSON.stringify(currentTime));
    currentTime.setMinutes(currentTime.getMinutes() + interval);
    currentTime = new Date(currentTime);
    if(currentTime >= dtTime) {
        break;
    }
    
}

console.log(previouslySelectedTime);

  • Explain the reason for downvote – Maheer Ali Apr 22 at 4:51
  • I did not downvote. I selected the other answer as best answer because it used new Date() which I already had instead of JSON which is a bit confusing to me – pixie123 Apr 22 at 4:56
  • @pixie123 Np new Date() is a better option – Maheer Ali Apr 22 at 4:59
  • @pixie123 You should also take care of two other things. You should declare previouslySelectedTime outside of for loop and change it inside loop. And also use let for declaration of i inside loop. – Maheer Ali Apr 22 at 5:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.