1

I made a small project with educational purposes (for myself). The project consists on calculating the number of weeks between dates or the start or final date depending on a given number of weeks. At any point, the user must input two of these values:

  • Start date
  • End date
  • Number of weeks

At the beggining it worked, however after some tests I noticed it was throwing incorrect values. For example, for a start date 3/22/2018 (march the 22nd, 2018) and 28 weeks it would throw and end date 11/03/2018 (november the 3rd, 2018) which is wrong, but, if I calculate the number of weeks for a start date 3/22/2018 (march the 22nd, 2018) and an end date 10/05/2018 (october the 5th, 2018) it throws 28 weeks which is correct. Further inspection shows it only happens for dates starting from 04/01/2018 (april the 1st, 2018).

After some research I found out doing date calculations in miliseconds is better as some browsers do not support some date functions.

Nevertheless I would like to know if there is an explanation on this behaviour.

Thanks in advance.

<script>
    function calcDates(){
        var startInput = document.getElementById("start");
        var endInput = document.getElementById("end");
        var weeksInput = document.getElementById("weeks");
        var startValidation = false;
        var endValidation = false;
        var weeksValidation = false;

        if (startInput.value != "") {
            startValidation = true;
        }
        else{
            startValidation = false;
        }


        if (endInput.value != "") {
            endValidation = true;
        }
        else{
            endValidation = false;
        }

        if (weeksInput.value != "") {
            weeksValidation = true;
        }
        else{
            weeksValidation = false;
        }

        //Calculate weeks number
        if ((startValidation == true && endValidation == true && weeksValidation == false)||document.getElementById("weekRadio").checked == true) {
            document.getElementById("weekRadio").checked = true;
            var start = new Date(startInput.value);
            var end = new Date(endInput.value);
            weeksInput.value = Math.round((end-start)/604800000);
        }

        //Calculate End date
        if ((startValidation == true && endValidation == false && weeksValidation == true)||document.getElementById("endRadio").checked == true) {
            document.getElementById("endRadio").checked = true;
            var start = new Date(startInput.value);
            var weeks = weeksInput.value;
            var end = new Date();
            end.setDate(start.getDate() + (weeks*7));
            console.log(start.getDate());
            console.log(weeks*7);
            console.log(start.getDate()+(weeks*7));
            console.log(end.toISOString().substring(0,10));
            endInput.value = end.toISOString().substring(0,10);
        }

        //Calculate Start date
        if ((startValidation == false && endValidation == true && weeksValidation == true)||document.getElementById("startRadio").checked == true) {
            document.getElementById("startRadio").checked = true;
            var end = new Date(endInput.value);
            var weeks = weeksInput.value;
            var start = new Date();
            start.setDate(end.getDate() - (weeks*7));
            console.log(-weeks*7);
            console.log(end.toISOString().substring(0,10));
            startInput.value = start.toISOString().substring(0,10);
        }
    }
</script>
  • The statement "*doing date calculations in miliseconds is better as some browsers do not support some date functions*" is without foundation. Name one browser that doesn't support all the built-in ECMA-262 Date methods. Using the built-in parser like `new Date(startInput.value)` is a very bad idea, see [*Why does Date.parse give incorrect results?*](https://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results) – RobG Apr 11 '18 at 00:54
  • Thaks for the observation on my lack of fundation. I see the best way is to parse manually, however, after the answer given by cybersam it works just fine the way it is. – Ricardo Santi Apr 11 '18 at 13:39
  • …until it doesn't. – RobG Apr 12 '18 at 04:34

1 Answers1

1

Date.setDate "sets the day of the Date object relative to the beginning of the currently set month."

In the following snippet of code, end's currently set month will start out being whatever month it happens to be at the time the code is executed. And setDate will set the new date value relative to the start of whatever month that is.

var end = new Date();
end.setDate(start.getDate() + (weeks*7));

In order to get the expected results in this scenario, you should use this code snippet, which initializes end to the startInput.value time (which will include the correct month):

var end = new Date(startInput.value);
end.setDate(start.getDate() + (weeks*7));
cybersam
  • 63,203
  • 6
  • 53
  • 76