CYPRESS:考虑到二月(28 天)和有 30 天的月份,如何在当前日期上加一个月?

CYPRESS: How to add one month to my current date with consideration to months like February(28 days) and months that have 30 days?

我有这个柏树测试,我正在检查正确的账单日期。我们的网站按月订阅,其工作方式如下: 如果您在 1 月 31 日开始订阅,您的下一个账单日期将自动在 3 月 1 日,因为 2 月只有 28 天。 同样,如果您在 3 月 31 日开始订阅,那么您的下一个账单日期将是 5 月 1 日,因为 4 月没有 31 日,它会自动更改为下个月的第一天。 从其他正常日期开始,如 15 日将始终是下个月的同一日期(15 日)等。

我的问题是在使用 cypress 进行测试时,我总是得到下个月的最后一天。例如,如果我测试我将在 3 月 31 日开始订阅,我的测试将在 4 月 30 日作为预期结果,这是不正确的,因为我希望我的测试的预期结果是 5 月 1 日。

我正在使用这个功能,但我似乎无法让它正常工作,因为月份之间有很多差异。

export const getBillingDate = (todayDate: string, months: number) => {
  const date1 = new Date(todayDate)
  const date2 = new Date(todayDate)
  date1.setDate(1)
  const daysInNextMonth = getDaysInMonth(addMonths(date1, months))
  date2.setDate(Math.min(date2.getDate(), daysInNextMonth))
  return format(addMonths(date2, months), 'MMMM do, yyyy')
}

我真的很感谢任何人的帮助,因为我是 Cypress 的新手和一般测试。 (抱歉英语不是我的母语)

Day.js 已经存在,可以计算日期。

您可以使用他们的 .add() 将日期 dayjs().add(30, 'day') 添加 30 天。

您还可以使用 .format() 格式化日期,以按照您想要的方式格式化 dayjs('2019-01-25').format('DD/MM/YYYY') // '25/01/2019'

dayjs 和 javascript new Date() 都未能完全按照您的要求添加所有日期。

但是您可以使用 dayjs().daysInMonth() 来获得与您的描述完全一致的结果,

const getBilling = (startDate) => {
  const [year, month, day] = startDate.split('/')

  const sd = dayjs(startDate)
  const firstOfNextMonth = sd.month(sd.month() + 1).date(1)
  const daysInNextMonth = dayjs(firstOfNextMonth).daysInMonth()

  let end;
  if (daysInNextMonth < day) {
    end = `${year}/${+month+2}/`  // always bump to 1st day of month + 2
  } else {
    end = `${year}/${+month+1}/${day}`
  }

  return dayjs(end, 'YYYY/MM/DD').format('YYYY/MM/DD')
}

it('gets billing date, accounting for short months', () => {

  //Jan
  expect(getBilling('2022/01/15')).to.eq('2022/02/15')
  expect(getBilling('2022/01/31')).to.eq('2022/03/01')

  //Feb
  expect(getBilling('2022/02/15')).to.eq('2022/03/15')
  expect(getBilling('2022/02/28')).to.eq('2022/03/28')

  //Mar
  expect(getBilling('2022/03/15')).to.eq('2022/04/15')
  expect(getBilling('2022/03/31')).to.eq('2022/05/01')

})

您的要求有点不寻常。通常当添加一个月并且它溢出时,要求是 return 该月的最后一天,而不是下个月的第一天。但这并不难,只需获取开始日期(月中的日期),添加一个月,如果结果日期不相同,则将其设置为 1,例如:

function addBillingMonth(date = new Date()) {
  let d = new Date(+date);
  let dayNum = d.getDate();
  d.setMonth(d.getMonth() + 1);
  if (dayNum !== d.getDate()) {
    d.setDate(1);
  }
  return d;
}

// Examples
[ new Date(2021,11,31), // 31 Dec
  new Date(2022, 0,15), // 15 Jan
  new Date(2022, 0,31), // 31 Jan
  new Date(2022, 2,31), // 31 Mar
].forEach(d => console.log(d.toDateString() +
  ' next bill: ' + addBillingMonth(d).toDateString())
);
  

你有一个months参数,如果你想增加超过一个月,你应该每个月单独计算。

'dayjs` 绝对给你更多选择。

const expect = chai.expect

const addBillingMonth = (start) => {
  let next = start.add(1, 'month')
  if (start.date() !== next.date()) {
    next = next.add(1, 'month').startOf('month')
  }
  return next  
}

const getBilling = (startDate, months = 1) => {
  let result = dayjs(startDate)
  for (let i = 0; i < months; i++) {
    result = addBillingMonth(result)  // repeat for each month
  }
  return result.format('YYYY/MM/DD')
}

expect(getBilling('2022/01/15')).to.eq('2022/02/15')
expect(getBilling('2022/01/31')).to.eq('2022/03/01')
expect(getBilling('2022/02/15')).to.eq('2022/03/15')
expect(getBilling('2022/02/28')).to.eq('2022/03/28')
expect(getBilling('2022/03/15')).to.eq('2022/04/15')
expect(getBilling('2022/03/31')).to.eq('2022/05/01')
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/4.3.6/chai.min.js"></script>
<script src="https://unpkg.com/dayjs@1.8.21/dayjs.min.js"></script>