У меня есть калькулятор даты javascript, который иногда работает, а иногда нет. Я прочитал Как получить количество дней между двумя датами в JavaScript?, но я не уверен, где реализовать какое-либо из предложений, поскольку мне кажется, что даты в этом посте предопределены внутри кода, а не через входные данные.
Например, если вы введете дату 1 октября 2019 года, вы получите результаты:
45 дней: четверг, 14 ноября 2019 г.
180 дней: воскресенье, 29 марта 2020 г.
Но если вы введете дату 1 декабря 2019 года, вы получите результаты:
45 дней: среда, 15 января 2020 г.
180 дней: пятница, 29 мая 2020 г.
Это не может быть правильным, потому что в декабре 31 день. 31 + 15 = 46? Какой-то просчет происходит в большинстве месяцев.
(function ($) {
var weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
var afterTime = function (time, days) {
time = time + (24 * 60 * 60 * 1000) * days;
return time;
};
var getDate = function () {
var yy = $('input#year').val();
var mm = $('select#month').val();
var dd = $('input#day').val();
var wd;
if (yy.trim().length === 0 || mm.trim().length === 0 || dd.trim().length === 0) {
return;
}
var startDate = new Date(yy, mm, dd);
var resultDate;
resultDate = new Date();
resultDate.setTime(afterTime(startDate.getTime(), 45));
yy = resultDate.getFullYear();
mm = resultDate.getMonth();
dd = resultDate.getDate();
wd = resultDate.getDay();
$('#dateAfter45').html('<span>Your 45 Days from now ends on:</span> ' + weekdays[wd] + ', ' + months[mm] + ' ' + dd + ', ' + yy);
resultDate = new Date();
resultDate.setTime(afterTime(startDate.getTime(), 180));
yy = resultDate.getFullYear();
mm = resultDate.getMonth();
dd = resultDate.getDate();
wd = resultDate.getDay();
$('#dateAfter180').html('<span>Your 180 Days from now ends on:</span> ' + weekdays[wd] + ', ' + months[mm] + ' ' + dd + ', ' + yy);
};
$(document).ready(function () {
$('input#year').change(function () {
getDate();
});
$('input#day').change(function () {
getDate();
});
$('select#month').change(function () {
getDate();
});
});
})(jQuery);<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class = "dateselector">
<div class = "start-date">
<form class = "form">
<div class = "form-row align-items-center">
<div class = "col-auto">
<!--label for = "month">Month</label-->
<select name = "month" id = "month" class = "form-control">
<option value = "" disabled selected>- Select a Month -</option>
<option value = "0">January</option>
<option value = "1">February</option>
<option value = "2">March</option>
<option value = "3">April</option>
<option value = "4">May</option>
<option value = "5">June</option>
<option value = "6">July</option>
<option value = "7">August</option>
<option value = "8">September</option>
<option value = "9">October</option>
<option value = "10">November</option>
<option value = "11">December</option>
</select>
</div>
<div class = "col-auto">
<!--label for = "day">Day</label-->
<input type = "text" name = "day" id = "day" class = "form-control" placeholder = "Day" maxlength = "2">
</div>
<div class = "col-auto">
<!--label for = "day">Year</label-->
<input type = "text" name = "year" id = "year" class = "form-control" placeholder = "Year" maxlength = "4">
</div>
<div class = "col-auto">
<!--label for = "day">Year</label-->
<span class = "butn hvr-sweep-to-top">Calculate</span>
</div>
</div>
</form>
</div>
<div class = "result-date">
<h4 id = "dateAfter45"></h4>
<h4 id = "dateAfter180"></h4>
</div>
</div>Я не уверена. Взял бы я это и просто заменил: resultDate.setTime(afterTime(startDate.getTime(), 45));?
Да, используйте это вместо resultDate.setTime(afterTime(startDate.getTime(), 45));
В результате вы все равно получите 15 января.
Я понимаю, что в месяце нет "0", но что можно сделать, чтобы это исправить?
Я обновил ответ, чтобы объяснить, почему вы получаете 14 ноября вместо 15 ноября.
замена resultDate.setTime(afterTime(startDate.getTime(), 45)); на resultDate.setDate(resultDate.getDate() + 45); возвращает текущую дату без учета входных значений, см. здесь: codepen.io/chuckers82/pen/GbbLWr
Я вошел 1 октября 2019 года, там было написано 15 ноября 2019 года.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


45 — это 31 + 14. 31 день после 1 декабря — это 1 января, 14 дней после 1 января — это 15 января.
Результат правильный. Арифметика даты, которая пересекает границы месяца, смещена на 1, потому что в месяцах нет дня 0.
Причина, по которой вы получаете 14 ноября в первом случае, заключается в том, что переход на летнее время происходит где-то в октябре. Ваша функция afterTime() считает, что все дни длятся 24 часа, но когда заканчивается летнее время, мы добавляем к этому дню дополнительный час. Итак, вы переходите от Oct 1 00:00:00 к Nov 14 23:00:00 вместо Nov 15 00:00:00.
Используйте встроенную арифметику дат в классе Date, она автоматически подстраивается под это.
resultDate.setTime(afterTime(startDate.getTime(), 45));
Хорошо, так как я могу это исправить??
Исправить что? В этом нет ничего плохого. Ваше ожидание неверно, результат правильный. Это дата через 45 дней после 1 декабря.
это пример, который я сделал для краткого расчета дней недели и месяца, надеюсь, это тоже поможет вам
Date.prototype.calculateDays = function(days) {
var date = new Date(this.valueOf());
//here you can enter the date you picked
date.setDate(date.getDate() + days);
return date;
}
var options = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric'
};
let resultDate = new Date();
let firstDate = resultDate.calculateDays(45).toLocaleDateString('en-US', options);
console.info(firstDate);
let secondDate = resultDate.calculateDays(180).toLocaleDateString('en-US', options);
console.info(secondDate);
Почему вы делаете свою собственную арифметику дат, а не просто
resultdaDate.setDate(resultDate.getDate() + 45)?