Дата проверки JS - в пределах 6 месяцев от сегодняшней

Я использую 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.

Вам следует взглянуть на moment.js или другую библиотеку, которая позволяет использовать интернет-часы для получения текущего времени. Date по умолчанию использует системное время на клиенте, которое обычно может изменяться по их прихоти.

Taplar 22.05.2018 18:11

@ Taplar - все значения в любом случае должны проверяться на сервере, так зачем вводить еще одну точку отказа и задержку? Местные часы можно сравнить с веб-сервером.

RobG 23.05.2018 11:29

@RobG Конечно, значения должны быть проверены на сервере. Мы говорим о проверке внешнего интерфейса, которая служит основной цели повышения UX сайта для пользователя. Разрешить пользователю открыть ваш пользовательский интерфейс и выбрать недопустимую дату только из-за того, что его системные часы неправильные, - это ужасный пользовательский интерфейс. Независимо от того, используете ли вы интернет-часы или ссылаетесь на серверные часы (которые для клиента являются интернет-часами) для определения диапазонов дат, которые должен отображаться пользователю, - это небольшая часть этой проблемы. Основная проблема заключается в том, что пользователю не следует предоставлять недопустимые параметры.

Taplar 23.05.2018 16:33
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
3
3 611
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Просто измените свой sixMonthBeforeNow с помощью приведенного ниже кода, и он должен работать.

var sixMonthBeforeNow = new Date(now).setMonth(now.getMonth() - 6);

Это не всегда работает, например 31 августа 2018 г. минус 6 месяцев - это 31 февраля, которое преобразуется в 3 марта. В високосном году это 2 марта. Точно так же 31 января минус 6 месяцев будет 31 июля, но 31 декабря минус 6 месяцев будет 1 июля и так далее.

RobG 23.05.2018 10:51
Ответ принят как подходящий

Вам нужно быть осторожным с арифметикой даты, потому что она не симметрична из-за неравномерной длины месяцев, поэтому вам нужны правила, чтобы справиться с этим. Например. какая дата ровно за 6 месяцев до 31 августа?

Прежде чем отвечать, примите во внимание:

  1. 28 февраля плюс 6 месяцев - это 28 августа
  2. 1 марта плюс 6 месяцев - это 1 сентября.
  3. Так какой день 6 месяцев перед 29, 30 и 31 августа? 28 февраля или 1 марта?

Подобные проблемы возникают для любого последнего дня месяца, когда в предыдущем 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 месяцев до этого. Сможете ли вы отредактировать мой код для этого?

TheOrdinaryGeek 23.05.2018 12:12

Другие вопросы по теме