Javascript 使用 moment.js 查找给定工作日(即星期一)的下一个实例

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34979051/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 17:08:26  来源:igfitidea点击:

Find next instance of a given weekday (ie. Monday) with moment.js

javascriptmomentjs

提问by Mike Thrussell

I want to get the date of the next Monday or Thursday (or today if it is Mon or Thurs). As Moment.js works within the bounds of a Sunday - Saturday, I'm having to work out the current day and calculate the next Monday or Thursday based on that:

我想获取下周一或周四的日期(如果是周一或周四,则为今天)。由于 Moment.js 在周日至周六的范围内工作,我必须计算出当前日期并基于此计算下周一或周四:

if (moment().format("dddd")=="Sunday") { var nextDay = moment().day(1); }
if (moment().format("dddd")=="Monday") { var nextDay = moment().day(1); }
if (moment().format("dddd")=="Tuesday") { var nextDay = moment().day(4); }
if (moment().format("dddd")=="Wednesday") { var nextDay = moment().day(4); }
if (moment().format("dddd")=="Thursday") { var nextDay = moment().day(4); }
if (moment().format("dddd")=="Friday") { var nextDay = moment(.day(8); }
if (moment().format("dddd")=="Saturday") { var nextDay = moment().day(8); }

This works, but surely there's a better way!

这有效,但肯定有更好的方法!

回答by XML

The trick here isn't in using Moment to go to a particular day from today. It's generalizing it, so you can use it with any day, regardless of where you are in the week.

这里的诀窍不是使用 Moment 从今天开始到特定的一天。它是概括性的,因此您可以在任何一天使用它,无论您在一周中的哪个位置。

First you need to know where you are in the week: moment().day(), or the slightly more predictable (in spite of locale) moment().isoWeekday(). Critically, these methods return an integer, which makes it easy to use comparison operators to determine where you are in the week, relative to your targets.

首先,您需要知道您在一周中的位置:moment().day(),或者稍微更可预测的(尽管有语言环境)moment().isoWeekday()。至关重要的是,这些方法返回一个整数,这使得使用比较运算符可以轻松确定您在一周中相对于目标的位置。

Use that to know if today's day is smaller or bigger than the day you want. If it's smaller/equal, you can simply use this week's instance of Monday or Thursday...

用它来知道今天的一天比你想要的一天小还是大。如果它更小/相等,您可以简单地使用本周的星期一或星期四实例......

const dayINeed = 4; // for Thursday
const today = moment().isoWeekday();

if (today <= dayINeed) { 
  return moment().isoWeekday(dayINeed);
}

But, if today is bigger than the day we want, you want to use the same day of next week: "the monday of next week", regardless of where you are in the current week. In a nutshell, you want to first go into next week, using moment().add(1, 'weeks'). Once you're in next week, you can select the day you want, using moment().day(1).

但是,如果今天比我们想要的那一天大,你想使用下周的同一天:“下周的星期一”,不管你在本周的哪个地方。简而言之,您想先进入下周,使用moment().add(1, 'weeks'). 进入下周后,您可以使用 选择所需的日期moment().day(1)

Together:

一起:

const dayINeed = 4; // for Thursday
const today = moment().isoWeekday();

// if we haven't yet passed the day of the week that I need:
if (today <= dayINeed) { 
  // then just give me this week's instance of that day
  return moment().isoWeekday(dayINeed);
} else {
  // otherwise, give me *next week's* instance of that same day
  return moment().add(1, 'weeks').isoWeekday(dayINeed);
}

See also https://stackoverflow.com/a/27305748/800457

另见https://stackoverflow.com/a/27305748/800457



EDIT: other commenters have pointed out that the OP wanted something more specific than this: the next of an array of values ("the next Monday or Thursday"), not merely the next instance of some arbitrary day. OK, cool.

编辑:其他评论者指出,OP 想要比这更具体的东西:值数组中的下一个(“下一个星期一或星期四”),而不仅仅是某个任意日期的下一个实例。嗯不错。

The general solution is the beginning of the total solution. Instead of comparing for a single day, we're comparing to an array of days: [1,4]:

通解是全解的开始。我们不是比较一天,而是比较一组天数[1,4]::

const daysINeed = [1,4]; // Monday, Thursday
// we will assume the days are in order for this demo, but inputs should be sanitized and sorted

function isThisInFuture(targetDayNum) {
  // param: positive integer for weekday
  // returns: matching moment or false
  const todayNum = moment().isoWeekday();  

  if (todayNum <= targetDayNum) { 
    return moment().isoWeekday(targetDayNum);
  }
  return false;
}

function findNextInstanceInDaysArray(daysArray) {
    // iterate the array of days and find all possible matches
    const tests = daysINeed.map(isThisInFuture);

    // select the first matching day of this week, ignoring subsequent ones, by finding the first moment object
    const thisWeek = tests.find((sample) => {return sample instanceof moment});

    // but if there are none, we'll return the first valid day of next week (again, assuming the days are sorted)
    return thisWeek || moment().add(1, 'weeks').isoWeekday(daysINeed[0]);;
}
findNextInstanceInDaysArray(daysINeed);

I'll note that some later posters provided a very lean solution that hard-codes an array of valid numeric values. If you always expect to search the same days, and don't need to generalize for other searches, that'll be the more computationallyefficient solution, although not the easiest to read, and impossible to extend.

我会注意到,后来的一些海报提供了一个非常精简的解决方案,可以对一组有效数值进行硬编码。如果您总是希望在同一天进行搜索,并且不需要对其他搜索进行泛化,那么这将是计算效率更高的解决方案,尽管不是最容易阅读且无法扩展。

回答by AshUK

get the next monday using moment

使用 moment 获得下一个星期一

moment().startOf('isoWeek').add(1, 'week');

回答by Gavriel

moment().day()will give you a number referring to the day_of_week.

moment().day()会给你一个数字,指的是 day_of_week。

What's even better: moment().day(1 + 7)and moment().day(4 + 7)will give you next Monday, next Thursday respectively.

有什么更好的:moment().day(1 + 7)moment().day(4 + 7)将分别给你在下周一,下周四。

See more: http://momentjs.com/docs/#/get-set/day/

查看更多:http: //momentjs.com/docs/#/get-set/day/

回答by vinjenzo

The following can be used to get any next weekday date from now (or any date)

以下可用于从现在(或任何日期)获取下一个工作日的日期

var weekDayToFind = moment().day('Monday').weekday(); //change to searched day name

var searchDate = moment(); //now or change to any date
while (searchDate.weekday() !== weekDayToFind){ 
  searchDate.add(1, 'day'); 
}

回答by Andrejs Kuzmins

IMHO more elegant way:

恕我直言,更优雅的方式:

var setDays = [ 1, 1, 4, 4, 4, 8, 8 ],
    nextDay = moment().day( setDays[moment().day()] );

回答by David Kirk

Most of these answers do not address the OP's question. Andrejs Kuzmins' is the best, but I would improve on it a little more so the algorithm accounts for locale.

这些答案中的大多数都没有解决 OP 的问题。Andrejs Kuzmins 是最好的,但我会改进它一点,以便算法考虑语言环境。

var nextMoOrTh = moment().isoWeekday([1,4,4,4,8,8,8][moment().isoWeekday()-1]);

回答by Hams Ahmed Ansari

Next Monday or any other day

下周一或其他任何一天

moment().startOf('isoWeek').add(1, 'week').day("monday");

回答by Mark C Mitchell

Here's a solution to find the next Monday, or today if it is Monday:

这是查找下周一或今天(如果是周一)的解决方案:

const dayOfWeek = moment().day('monday').hour(0).minute(0).second(0);

const endOfToday = moment().hour(23).minute(59).second(59);

if(dayOfWeek.isBefore(endOfToday)) {
  dayOfWeek.add(1, 'weeks');
}

回答by softcode

Here's e.g. next Monday:

这是下周一的例子:

var chosenWeekday = 1 // Monday

var nextChosenWeekday = chosenWeekday < moment().weekday() ? moment().weekday(chosenWeekday + 7) : moment().weekday(chosenWeekday)

回答by omg_me

The idea is similar to the one of XML, but avoids the if / elsestatement by simply adding the missing days to the current day.

这个想法类似于XML,但通过简单地将缺少的天数添加到当前日期来避免if / else语句。

const desiredWeekday = 4; // Thursday
const currentWeekday = moment().isoWeekday();
const missingDays = ((desiredWeekday - currentWeekday) + 7) % 7;
const nextThursday = moment().add(missingDays, "days");

We only go "to the future" by ensuring that the days added are between 0 and 6.

我们只通过确保添加的天数在 0 到 6 之间来“走向未来”。