javascript - moment.js - Check if two moments are from the same week, but weeks begin on Friday and end on Thursday - Stack Over

I am creating a Discord bot with node.js and discord.js, and there's a feature that allows users t

I am creating a Discord bot with node.js and discord.js, and there's a feature that allows users to vote thanks to a mand, but I'd like them to vote only once a week.

The issue is that, on this Discord, weeks start on Friday and end on Thursday, therefore I can't simply write :

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

Therefore, I have written some code that seems to work, but I'd like your opinion on it as it seems very sloppy and I'm not sure if I have taken into account all of the possibilities (I don't know if I need to use my month variables for example):

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

};

As I said, this seems do to the trick but I would like someone else's opinion on it to be sure there isn't a simpler way or, if there isn't, if I haven't forgotten anything.

Thank you for reading :)

I am creating a Discord bot with node.js and discord.js, and there's a feature that allows users to vote thanks to a mand, but I'd like them to vote only once a week.

The issue is that, on this Discord, weeks start on Friday and end on Thursday, therefore I can't simply write :

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

Therefore, I have written some code that seems to work, but I'd like your opinion on it as it seems very sloppy and I'm not sure if I have taken into account all of the possibilities (I don't know if I need to use my month variables for example):

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

};

As I said, this seems do to the trick but I would like someone else's opinion on it to be sure there isn't a simpler way or, if there isn't, if I haven't forgotten anything.

Thank you for reading :)

Share Improve this question asked Jun 2, 2017 at 12:46 TokipudiTokipudi 1031 silver badge8 bronze badges 2
  • You could atleast store the result from moment() and moment(dateLastVote) in variables instead of calling them repeatedly. – Arg0n Commented Jun 2, 2017 at 12:49
  • Yes it's true. I haven't really polished the code yet, I just tried to figure what worked and what didn't so I didn't really think about that. – Tokipudi Commented Jun 2, 2017 at 12:52
Add a ment  | 

3 Answers 3

Reset to default 4

I do not know how our approaches pare to each other in matter of performance, but I still wanna show my approach on the problem:

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");
}

What the solution does is calculating the start of the week of each of the given dates in respect to the offset (for values >= -7 and <= 0) and returning whether both have the same start of the week. Same start of the week = same week.

All you have to do is call the function passing two date objects (or moment objects) and an offset between -7 and 0, depending on how the week is shifted in relation to a "regular" week.

I think that the best way to do want you need is to tell moment that your week starts on Friday. You can simply use updateLocale method customizing dow (day of week) key of the week object and then use your first code snippet. See Customize section of the docs to get more info about locale customization.

Here a live example of setting a custom day as first day of the week and then using your code to check if a given day is in the current week:

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./ajax/libs/moment.js/2.18.1/moment.min.js"></script>

EDIT An improved solution is to use moment isSame passing 'week' as second parameter. As the docs states:

Check if a moment is the same as another moment.

If you want to limit the granularity to a unit other than milliseconds, pass it as the second parameter.

Here a live sample:

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./ajax/libs/moment.js/2.18.1/moment.min.js"></script>

According to the Moment docs you can set the ISO start of the week:

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

then you can use the same functionality to check if the days are in the same week of the year.

Take a look: https://momentjs./docs/#/get-set/iso-weekday/

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744102332a4558588.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信