момент.js-проверьте, если два момента с той же недели, но недели начинаются в пятницу и заканчиваются в четверг

Я создаю бота диссонанса с узлом.JS и раздор.js, и есть функция, которая позволяет пользователям голосовать благодаря команде, но я бы хотел, чтобы они голосовали только раз в неделю.

проблема в том, что на этот раздрай, недели начинаются в пятницу и заканчиваются в четверг, поэтому я не могу просто написать :

var weekNow = moment().week();
var weekLastVote = moment(dateLastVote).week();
if (weekNow == weekLastVote){
    //Prevent from voting again
} else {
    //Let the user vote
}

поэтому я написал некоторый код, который, похоже, работает, но я хотел бы услышать Ваше мнение об этом, поскольку он кажется очень неряшливым, и я не уверен, что я взял учитывая все возможности (я не знаю, нужно ли мне использовать мой месяц переменные для примера):

module.exports = {
isSameWeek: function (dateLastVote) {
    // moments for today's date
    var dayNow = moment().weekday();
    var weekNow = moment().week();
    var monthNow = moment().month();
    var yearNow = moment().year();
    var dateNow = moment().format('MMDDYYYY'); // moment without hours/minutes/seconds

    // moments for last vote's date
    var dayLastVote = moment(dateLastVote).weekday();
    var weekLastVote = moment(dateLastVote).week();
    var monthLastVote = moment(dateLastVote).month();
    var yearLastVote = moment(dateLastVote).year();
    var dateLastVote = moment(dateLastVote).format('MMDDYYYY'); // moment without hours/minutes/seconds

    if ((yearNow === yearLastVote && weekNow === weekLastVote && dayLastVote < 5) || // 5 = Friday, starting day of the week (a week = Friday to thursday)
        (yearNow === yearLastVote && weekNow - 1 === weekLastVote && dayLastVote >= 5 && dayNow < 5) || 
        (dateNow === dateLastVote)
    ){
        return true;
    } else {
        return false;
    }
}

};

Спасибо за прочтение :)

3 ответов


Я не знаю, как наши подходы сравниваются друг с другом в вопросе производительности, но я все еще хочу показать свой подход к проблеме:

function isSameWeek(firstDay, secondDay, offset) {
    var firstMoment = moment(firstDay);
    var secondMoment = moment(secondDay);

    var startOfWeek = function (_moment, _offset) {
        return _moment.add("days", _moment.weekday() * -1 + (_moment.weekday() >= 7 + _offset ? 7 + _offset : _offset));
    }

    return startOfWeek(firstMoment, offset).isSame(startOfWeek(secondMoment, offset), "day");
}

решение вычисляет начало недели каждой из заданных дат относительно смещения (для значений >= -7 и

все, что вам нужно сделать, это вызвать функцию, передающую два объекта даты (или момент объекты) и смещение между -7 и 0, в зависимости от того, как неделя смещается по отношению к "обычной" неделе.


Я думаю, что лучший способ сделать хотите, что вам нужно, это сказать, что неделя начинается в пятницу. Вы можете просто использовать updateLocale способ настройка dow (день недели) ключ week object, а затем используйте свой первый фрагмент кода. См.настройка раздел документов для получения дополнительной информации о настройке локали.

вот живой пример установки пользовательского дня в качестве первого дня недели, а затем с помощью кода, чтобы проверить, если данный день находится в текущем неделя:

moment.updateLocale('en', {
  week: {
    dow : 5, // Friday is the first day of the week.
  }
});

function checkWeek(dateLastVote){
  var weekNow = moment().week();
  var weekLastVote = moment(dateLastVote).week();
  if (weekNow == weekLastVote){
      //Prevent from voting again
      console.log(moment(dateLastVote).format('YYYY-MM-DD') + ' is in the current week')
  } else {
      //Let the user vote
      console.log(moment(dateLastVote).format('YYYY-MM-DD') + ' is NOT in the current week')
  }
}

checkWeek('2017-05-30'); // same week mon-sun, but previous week fri-thu
checkWeek('2017-06-01'); // same week mon-sun, but previous week fri-thu
checkWeek('2017-06-08'); // next week mon-sun, but current week fri-thu

// First day of the current week
console.log(moment().startOf('week').format('YYYY-MM-DD'));
// Last day of the current week
console.log(moment().endOf('week').format('YYYY-MM-DD'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>

редактировать улучшенное решение - использовать moment isSame передает 'week' как второй параметр. Как говорится в документах:

Проверьте, совпадает ли момент с другим моментом.

если вы хотите ограничить степень детализации единицей, отличной от миллисекунд, передайте ее в качестве второго параметра.

здесь жить пример:

moment.updateLocale('en', {
  week: {
    dow : 5, // Friday is the first day of the week.
  }
});

function isSameWeek(dateLastVote){
  var now = moment();
  var lastVote = moment(dateLastVote);
  if (now.isSame(lastVote, 'week')){
      //Prevent from voting again
      console.log(moment(dateLastVote).format('YYYY-MM-DD') + ' is in the current week')
  } else {
      //Let the user vote
      console.log(moment(dateLastVote).format('YYYY-MM-DD') + ' is NOT in the current week')
  }
}

isSameWeek('2017-06-10'); // same week mon-sun, but next week fri-thu
isSameWeek('2017-06-03'); // previous week mon-sun, but current week fri-thu
isSameWeek('2017-06-06'); // current week both mon-sun and fri-thu

// First day of the current week
console.log(moment().startOf('week').format('YYYY-MM-DD'));
// Last day of the current week
console.log(moment().endOf('week').format('YYYY-MM-DD'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>

в соответствии с документами момента вы можете установить ISO начало недели:

moment().isoWeekday(1); // Monday
moment().isoWeekday(7); // Sunday

затем вы можете использовать ту же функциональность, чтобы проверить, Если дней на той же неделе год.

посмотреть: https://momentjs.com/docs/#/get-set/iso-weekday/