【问题标题】:Identify second/third saturday using moment.js使用 moment.js 识别第二个/第三个星期六
【发布时间】:2020-08-12 06:13:02
【问题描述】:

我正在尝试实现一个方法,如果日期是假日则返回。出于此用例的目的,假期被天真地定义为所有星期日,以及第二个和第三个星期六。这是sn-p的代码,

export const isHoliday = (date: moment.Moment | Date) => {
  if (date instanceof Date) {
    date = moment(date);
  }

  const dayOfWeek = date.day();

  if (dayOfWeek >= 1 && dayOfWeek < 6) {
    // it is a weekday
    return false;
  }

  if (dayOfWeek === 0) {
    // it is a sunday
    return true;
  }

  if (dayOfWeek === 6) {
    return isSecondSaturday(date) || isThirdSaturday(date);
  }
};

还有其他方法,

const isSecondSaturday = (date: moment.Moment) => {
  return isNthSaturday(date, 2);
};

const isThirdSaturday = (date: moment.Moment) => {
  return isNthSaturday(date, 3);
};

const isNthSaturday = (today: moment.Moment, n: number) => {
  const thisMonth = today.clone().utc().startOf("month");
  const firstSaturday = thisMonth.day(6); // <-- culprit?
  const nthSaturday = firstSaturday.add(n - 1, "week");

  return nthSaturday.date() === today.date();
};

在我的测试中,我发现某些月份的第二个和第三个星期六没有正确识别。我认为这可能是我遗漏的一些小事。

【问题讨论】:

  • 使用 instanceof 进行测试是 problematic。既然您已经在使用 moment.js,那么请使用 isValid,例如if (moment.isValid(date))....
  • 感谢分享 :) 我会这样做❤️

标签: javascript date momentjs


【解决方案1】:

能否请您提供以下实施在哪个月份不起作用?我已将您的实现放到控制台并检查了前四个月 - 它运行良好。

function isHoliday(date) {
  const dayOfWeek = date.day();

  if (date instanceof Date) {
    date = moment(date);
  }


  if (dayOfWeek >= 1 && dayOfWeek < 6) {
    // it is a weekday
    return false;
  }

  if (dayOfWeek === 0) {
    // it is a sunday
    return true;
  }

  if (dayOfWeek === 6) {
    return isSecondSaturday(date) || isThirdSaturday(date);
  }
};

function isSecondSaturday(date) {
  return isNthSaturday(date, 2);
};

function isThirdSaturday(date) {
  return isNthSaturday(date, 3);
};

function isNthSaturday(today, n){
  const thisMonth = today.clone().utc().startOf("month");
  const firstSaturday = thisMonth.day(6); // <-- culprit?
  const nthSaturday = firstSaturday.add(n - 1, "week");
  return nthSaturday.date() === today.date();
};



function checkHolidaysInMonth(monthIndex) {
  var thisYear = moment().utc().startOf("year");
  thisYear.add(monthIndex,'months');
  for(var i = 0; i < 31; i++) {
    if(isHoliday(thisYear) === true) {
      console.log("Is 2nd or 3rd Sat or Sun: " + thisYear.format())
    }
    thisYear.add(1,'days');
  }
}

checkHolidaysInMonth(3);
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"&gt;&lt;/script&gt;

【讨论】:

  • 感谢 Marek 的帮助。我正在做更多的调试,我认为你是对的。我认为其他方法之一有副作用(我没有分享,因为我觉得它与问题无关)。我对传入的所有参数都使用了 clone(),现在它可以工作了!如果您认为这是问题,请告诉我。
【解决方案2】:

好的,我已经找到了解决方案。我一直在我的代码中使用另一种方法来查找最后一个工作日期。这涉及到日期的一些减法。这应该与方法隔离,但由于 momentjs 改变了原始时刻,因此每当调用该函数时都会产生副作用

因此,如果您正在操作参数,请在操作之前对其使用 clone() 方法 (see docs)。

例如moment().clone()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-07
    • 1970-01-01
    • 1970-01-01
    • 2021-10-21
    • 2021-12-04
    • 2021-11-09
    • 1970-01-01
    相关资源
    最近更新 更多