Использование момента для округления до следующего 1-го или 3-го понедельника - PullRequest
1 голос
/ 19 января 2020

интересовался, может ли кто-нибудь помочь, я пытаюсь использовать момент. js, чтобы взять дату (как сегодня), а затем использовать ее, чтобы вернуть следующий 1-й или 3-й понедельник, в зависимости от того, что наступит раньше.

Так, например, сегодня как 01/18, следующий (1-й или 3-й, в данном случае 3-й понедельник будет 1/20).

Или если сегодня будет 1/27 следующего (1-й понедельник в этом случае будет 2/03).

1 Ответ

0 голосов
/ 19 января 2020

Один алгоритм:

  1. Если дата еще не понедельник, перейдите к следующему понедельнику
  2. Если день седьмой или раньше, это первый понедельник
  3. Если день после 7-го и до 14-го, это второй понедельник, поэтому добавьте 7 дней, чтобы получить 3-й понедельник
  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);
}

Реализация, использующая момент. js ниже. Заманчиво использовать moment.endOf('week'), но, поскольку он «осведомлен о локали», он может закончиться в субботу или воскресенье в зависимости от настроек хост-системы, поэтому logi c в конечном итоге будет идентичен простому решению js, только используя момент. 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>
...