简体   繁体   中英

Calculate how many days until an event, based on a recurring date and recurrence

I'm trying to build a function that calculates how many days left until an event. "date" is when the event begins and "repeat" handles the repetition of the event, the function that I trying to build iterates the data and give me back an array with the new next date event and how much days left until this.


let today = '06/17/2021'

const recurrentDate = { title: 'Vacations', date: '06/18/2021', repeat: 'NONE' }

const countdown = { title: 'Vacations', nextDate: '06/18/2021', daysLeft: 1 }

//See that recurrentDate2 > date

const recurrentDate2 = { title: 'Another event', date: '06/15/2021', repeat: 'MONTHLY' }

const countDown2 = { title: 'Another event', nextDate: '07/15/2021', daysLeft: 28 }

I was playing around with "momentjs" and "moment-recur" trying to build functions and things that calculate recurrence.

let date = moment(new Date('06/15/2021'));

let today = moment(new Date('06/17/202'));

let recurrence = date.recur().every(1).month();

let nextDate = recurrence.next(1);

What kind of thing I need to do if I going to receive data like this. Based on cases and calculates all the days left based on recurrence.

const data = [
  { title: 'Vacations', date: '09/25/2022', repeat: 'NONE' },
  { title: 'Family Event', date: '01/02/2021', repeat: 'DAILY' },
  { title: 'Anniversary', date: '04/19/2021', repeat: 'WEEKLY' },
  { title: 'Friends day', date: '02/27/2021', repeat: 'YEARLY' },
  { title: 'Family plan', date: '10/10/2021', repeat: 'MONTHLY' },
  { title: 'Conference', date: '12/19/2021', repeat: 'MONTHLY' },
];

Maybe anyone can help me to get a better performance for it, but here is my proud work.

var moment = require('moment');
require('moment-recur');

const data = [
  { title: 'Vacations', date: '09/25/2022', repeat: 'NONE' },
  { title: 'Family Event', date: '01/02/2021', repeat: 'DAILY' },
  { title: 'Anniversary', date: '04/19/2021', repeat: 'WEEKLY' },
  { title: 'Friends day', date: '02/27/2021', repeat: 'YEARLY' },
  { title: 'Family plan', date: '10/10/2020', repeat: 'MONTHLY' },
  { title: 'Conference', date: '12/19/2021', repeat: 'MONTHLY' },
];

const newData = data.map(item => {
      const dataDate =  moment(new Date(item.date))

      if ( item.repeat === "NONE"  ) {
        return {
          ...item,
          nextDate: dataDate < today ? 0 : item.date,
          daysLeft: dataDate.diff(today, "days")
        }
      }
      if ( item.repeat === "DAILY" ) {
        if (dataDate > today) {
          return {
            ...item,
            nextDate: item.date,
            daysLeft: dataDate.diff(today, "days")
          }
        } 
        if ( dataDate < today ) {
          let recurrence = today.recur().every(1).day()    
          let nextDate = recurrence.next(1)

          return {
            ...item,
            nextDate: nextDate[0].format('MM/DD/YYYY'),
            daysLeft: nextDate[0].endOf('day').diff(today, "days")
          }
        } else {
          return {
            ...item,
            nextDate: dataDate,
            daysLeft: dataDate.endOf('day').diff(today, "days")
          }
        }
      }
      if ( item.repeat === "WEEKLY" ) {
        if (dataDate > today) {
          return {
            ...item,
            nextDate: item.date,
            daysLeft: dataDate.diff(today, "days")
          }
        } 
        if ( dataDate < today ) {
          let getWeeksNumber = today.week() - dataDate.week()
          let currentDataDateWeek = dataDate.add(getWeeksNumber, "weeks")         

          return {
            ...item,
            nextDate: currentDataDateWeek.format('MM/DD/YYYY'),
            daysLeft: currentDataDateWeek.endOf('day').diff(today, "days")
          }
        } else {
          return {
            ...item,
            nextDate: dataDate,
            daysLeft: dataDate.endOf('day').diff(today, "days")
          }
        }
      }
      if ( item.repeat === "MONTHLY" ) {
        if (dataDate > today) {
          return {
            ...item,
            nextDate: item.date,
            daysLeft: dataDate.diff(today, "days")
          }
        } 
        if ( dataDate < today ) {
          let getMonthsNumber = today.diff(dataDate, "months")
          let currentDataDateMonth = dataDate.add(getMonthsNumber, "months")
          if (currentDataDateMonth < today) {
            let recurrence = currentDataDateMonth.recur().every(1).month()    
          let nextDate = recurrence.next(1)

          return {
            ...item,
            nextDate: nextDate[0].format('MM/DD/YYYY'),
            daysLeft: nextDate[0].endOf('day').diff(today, "days")
          }
          } else {

          return {
            ...item,
            nextDate: currentDataDateMonth.format('MM/DD/YYYY'),
            daysLeft: currentDataDateMonth.endOf('day').diff(today, "days")
          }
          }
        } else {
          return {
            ...item,
            nextDate: dataDate,
            daysLeft: dataDate.endOf('day').diff(today, "days")
          }
        }
      }
      if ( item.repeat === "YEARLY" ) {
        if (dataDate > today) {
          return {
            ...item,
            nextDate: item.date,
            daysLeft: dataDate.diff(today, "days")
          }
        } 
        if ( dataDate < today ) {
          let getYearNumber = today.diff(dataDate, "years")
          let currentDataDateYear = dataDate.add(getYearNumber, "years")
          if (currentDataDateYear < today) {
            let recurrence = currentDataDateYear.recur().every(1).year()    
          let nextDate = recurrence.next(1)

          return {
            ...item,
            nextDate: nextDate[0].format('MM/DD/YYYY'),
            daysLeft: nextDate[0].endOf('day').diff(today, "days")
          }
          } else {

          return {
            ...item,
            nextDate: currentDataDateYear.format('MM/DD/YYYY'),
            daysLeft: currentDataDateYear.endOf('day').diff(today, "days")
          }
          }
        } else {
          return {
            ...item,
            nextDate: dataDate,
            daysLeft: dataDate.endOf('day').diff(today, "days")
          }
        }
      }
      return item
})

console.log(newData)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM