javascript - 利用时刻舍入到下一个或第三个星期一

标签 javascript date momentjs

想知道是否有人可以提供帮助,我正在尝试使用 moment.js 来获取日期(例如今天),然后使用它返回下一个或第三个星期一,以较早者为准。

例如今天为 01/18,下一个(第 1 或第 3 个,在本例中为第 3 个星期一为 1/20)。

或者,如果今天是 1/27,那么下一个(本例中的第一个星期一将是 2/03)。

最佳答案

一种算法是:

  1. 如果日期不是星期一,请移至下星期一
  2. 如果当天是 7 号或之前,则为第一个星期一
  3. 如果这一天在 7 号之后、14 号之前,则为第二个周一,因此添加 7 天以获得第三个周一
  4. 如果当天是 21 日之后,则移至下个月的第一个星期一

没有库的实现是:

/* Get next 1st or 3rd Monday of month
** @param {Date} date : start date
** @returns {Date} date for 1st or 3rd Monday of month
*/
function getMonday(date) {
  // Copy date so don't affect original
  date = new Date(date);
  // If not Monday, move to next
  if (date.getDay() != 1) {
    date.setDate(date.getDate() + 8 - (date.getDay() || 7))
  }
  let day = date.getDate(); 
  // If after 1st Monday, move to 3rd
  if (day > 7 && day < 14) {
    date.setDate(date.getDate() + 7);
  // If after 3rd Monday, move to 1st of next month    
  } else if (day > 21) {
    date.setMonth(date.getMonth() + 1, 1);
    date = getMonday(date);    
  }  
  return date;
}

// Test in March 2020
let d = new Date(2020,2,1);
let opts = {weekday:'short', day:'2-digit', month:'short'};

for (var i=0; i<31; i++) {
  console.log(d.toLocaleString('en-gb', opts) + ' -> '
  + getMonday(new Date(d)).toLocaleString('en-gb', opts));
  d.setDate(d.getDate() + 1);
}

下面是使用 moment.js 的实现。使用 moment.endOf('week') 很诱人,但由于它具有“区域设置感知”功能,因此根据主机系统设置,它可能会在周六或周日结束,因此逻辑最终是相同的对于纯 js 解决方案,仅使用 moment.js 方法:

/* @param {Moment} m - moment object for start date
** @returns {Moment} moment object for required Monday
*/
function getMondayMoment(m) {
  m = moment(m);
  // If not Monday, move to next
  if (m.day() != 1) {
    m.add(8 - (m.day() || 7), 'days');
  }
  let day = m.date();
  // If after 1st Monday, move to 3rd
  if (day > 7 && day < 14) {
    m.add(7, 'days');
  // If after 3rd Monday, move to 1st of next month
  } else if (day > 21) {
    m.set({month: m.get('month') + 1, date: 1});
    m = getMondayMoment(m);
  }
  return m;
}

// Test over March 2020
let m = moment('2020-03-01');
for (var i=0; i<31; i++) {
  console.log(
    m.format('ddd DD MMM') + ' -> ' +
    getMondayMoment(m).format('ddd DD MMM')
  );
  m.add(1, 'day');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>

关于javascript - 利用时刻舍入到下一个或第三个星期一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59804830/

相关文章:

r - 使用 apply 转换 R 中的日期并处理 NA 日期

php - 什么是 MM/DD/YYYY 正则表达式,我如何在 php 中使用它?

r - 如何从数据库中过滤日期数字、不完整日期和 NA 并转换为 r 中的统一日期类

javascript - Moment.js 问题格式方法无法正常工作

javascript - Electron HTTPS 本地文件

javascript - Google App Engine Standard Java 在部署时使用 Unicode 字符破坏代码

javascript - Moment.js小数转时间格式

javascript - 如何将 "Saturday 9:00 PM"转换为日期对象?

javascript - 发布和订阅同一主题的 mqtt 最佳实践

javascript - 用户在提交后刷新页面会不会有问题?