按周添加日期会产生错误的日​​期。为什么会这样?

Adding dates by week produces wrong date. Why is this happening?

我做了一个具有教育目的的小项目(为了我自己)。该项目包括根据给定的周数计算日期之间的周数或开始或结束日期。在任何时候,用户都必须输入以下两个值:

一开始它工作正常,但是经过一些测试后我发现它抛出了不正确的值。例如,对于开始日期 3/22/2018(2018 年 3 月 22 日)和 28 周,它会抛出结束日期 11/03/2018(2018 年 11 月 3 日),这是错误的,但是,如果我计算开始日期 3/22/2018(2018 年 3 月 22 日)和结束日期 10/05/2018(2018 年 10 月 5 日)的周数它抛出 28 周是正确的。进一步检查显示它只发生在从 04/01/2018(2018 年 4 月 1 日)开始的日期。

经过一些研究,我发现以毫秒为单位进行日期计算更好,因为某些浏览器不支持某些日期函数。

尽管如此,我想知道是否对此行为有解释。

提前致谢。

<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>

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

在下面的代码片段中,end 当前设置的月份将从执行代码时刚好是的月份开始setDate 将设置新的日期值相对于任何月份的开始。

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

为了在这种情况下获得预期的结果,您应该使用此代码片段,它将 end 初始化为 startInput.value 时间(包括正确的月份):

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