Я использую Bootstrap Datepicker, и в зависимости от выбранной даты мне нужно отобразить сообщение для пользователя.
Раньше я никогда не использовал Конструктор даты, поэтому он для меня в новинку.
Что мне нужно сделать, это следующее;
Если выбранная ими дата находится в пределах последних 6 месяцев сегодняшней даты, они получают скидку. Если выбранная ими дата не совпадает с последними 6 месяцами сегодняшнего дня, они этого не сделают.
Хотя он работает некорректно, создали играть здесь.
Любая помощь будет оценена по достоинству. Код также ниже;
HTML
<input type = "text" class = "form-control" id = "datepicker" placeholder = "Year Graduated" value = "" data-date-format = "dd/mm/yyyy">
<p id = "rate"></p>
JS
function compareDate() {
// get date from datepicker
var dateEntered = $("#datepicker").datepicker("getDate");
dateEntered = new Date(dateEntered).getTime();
//alert("date entered: " + dateEntered);
// set todays date
var now = new Date();
// set date six months before today
var sixMonthBeforeNow = new Date(now).setTime(now.getTime() - 3 * 28 * 24 * 60 * 60);
//alert("six months before: " + sixMonthBeforeNow);
// if date entered is within six months from today
if (dateEntered > sixMonthBeforeNow) {
alert("You qualify for the discount rate.");
$("#rate").html('discount rate');
}
// if date entered is over six months from today
if (dateEntered < sixMonthBeforeNow) {
alert("you graduated more than six months ago");
$("#rate").html('no discount');
}
}
$("#datepicker").datepicker({
weekStart: 1,
daysOfWeekHighlighted: "6,0",
autoclose: true,
todayHighlight: true
});
$("#datepicker").change(function() {
compareDate();
});
Примечание: я бы предпочел не использовать какие-либо другие сторонние библиотеки / плагины JS.
@ Taplar - все значения в любом случае должны проверяться на сервере, так зачем вводить еще одну точку отказа и задержку? Местные часы можно сравнить с веб-сервером.
@RobG Конечно, значения должны быть проверены на сервере. Мы говорим о проверке внешнего интерфейса, которая служит основной цели повышения UX сайта для пользователя. Разрешить пользователю открыть ваш пользовательский интерфейс и выбрать недопустимую дату только из-за того, что его системные часы неправильные, - это ужасный пользовательский интерфейс. Независимо от того, используете ли вы интернет-часы или ссылаетесь на серверные часы (которые для клиента являются интернет-часами) для определения диапазонов дат, которые должен отображаться пользователю, - это небольшая часть этой проблемы. Основная проблема заключается в том, что пользователю не следует предоставлять недопустимые параметры.



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


Просто измените свой sixMonthBeforeNow с помощью приведенного ниже кода, и он должен работать.
var sixMonthBeforeNow = new Date(now).setMonth(now.getMonth() - 6);
Это не всегда работает, например 31 августа 2018 г. минус 6 месяцев - это 31 февраля, которое преобразуется в 3 марта. В високосном году это 2 марта. Точно так же 31 января минус 6 месяцев будет 31 июля, но 31 декабря минус 6 месяцев будет 1 июля и так далее.
Вам нужно быть осторожным с арифметикой даты, потому что она не симметрична из-за неравномерной длины месяцев, поэтому вам нужны правила, чтобы справиться с этим. Например. какая дата ровно за 6 месяцев до 31 августа?
Прежде чем отвечать, примите во внимание:
Подобные проблемы возникают для любого последнего дня месяца, когда в предыдущем 6-месячном месяце не было 31 дня. Должен ли предел быть 30-го числа или 1-го числа следующего месяца? Когда вы ответили на этот вопрос, вы можете разработать алгоритм, чтобы дать правильный ответ, а затем код для его реализации.
Если вы хотите, чтобы в таких случаях дата была установлена на конец месяца за 6 месяцев до этого, вы можете проверить месяц, полученный в результате вычитания 6 месяцев, и, если это не 6, установите его на последний день предыдущего месяца, например
function sixMonthsPrior(date) {
// Copy date so don't affect original
var d = new Date(date);
// Get the current month number
var m = d.getMonth();
// Subtract 6 months
d.setMonth(d.getMonth() - 6);
// If the new month number isn't m - 6, set to last day of previous month
// Allow for cases where m < 6
var diff = (m + 12 - d.getMonth()) % 12;
if (diff < 6) d.setDate(0)
return d;
}
// Helper to format the date
function formatDate(d) {
return d.toLocaleString(undefined, {day:'2-digit', month:'short', year:'numeric'});
}
// Tests
[ new Date(2018, 7,31), // 31 Aug 2018
new Date(2018, 8, 1), // 1 Sep 2018
new Date(2018,11,31), // 31 Dec 2018
new Date(2019, 2,31) // 31 Mar 2019
].forEach( d => console.info(formatDate(d) + ' => ' + formatDate(sixMonthsPrior(d))));Если это не та логика, которую вы хотите применить, вам нужно сказать, что это такое.
PS. Вы также можете реализовать описанную выше логику, просто сравнив даты начала и окончания (номер дня). Если они разные, то должно быть, прошло больше месяца, поэтому установлено значение 0.
Это отличный ответ @RobG Спасибо за подробное объяснение. Я никогда не рассматривал все возможности. Я думаю, что логика, которую я буду придерживаться, - установить дату на конец месяца за 6 месяцев до этого. Сможете ли вы отредактировать мой код для этого?
Вам следует взглянуть на
moment.jsили другую библиотеку, которая позволяет использовать интернет-часы для получения текущего времени.Dateпо умолчанию использует системное время на клиенте, которое обычно может изменяться по их прихоти.