Tengo esta prueba de ciprés donde estoy comprobando una fecha de facturación correcta. Nuestro sitio web tiene suscripciones mensuales y funciona de la siguiente manera: si inicia su suscripción el 31 de enero, su próxima fecha de facturación será automáticamente el 1 de marzo, ya que febrero tiene solo 28 días. Lo mismo si inicia su suscripción el 31 de marzo, su próxima fecha de facturación será el primero de mayo, ya que no hay 31 de abril y cambia automáticamente al primer día del mes siguiente. Comenzando en otras fechas normales como el 15, siempre será la misma fecha (15) del mes siguiente, etc.
Mi problema es que cuando pruebo esto con Cypress, siempre obtengo el último día del próximo mes. Por ejemplo, si pruebo que voy a comenzar mi suscripción el 31 de marzo, mi prueba tendrá el 30 de abril como resultado esperado, lo cual no es correcto ya que quiero que el resultado esperado de mi prueba sea el 1 de mayo.
Estoy usando esta función pero parece que no puedo hacer que funcione correctamente ya que hay muchas diferencias en los meses.
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') }Realmente agradecería la ayuda de alguien con esto, ya que soy nuevo en Cypress y en las pruebas en general. (Lo siento, el inglés no es mi primer idioma)
Tanto dayjs como javascript new Date() no pueden agregar todas las fechas exactamente como lo desea.
Pero puede usar dayjs().daysInMonth() para obtener resultados exactamente según su descripción,
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}/${1}` // 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') })Sus requisitos son un poco inusuales. Por lo general, cuando se agrega un mes y se desborda, el requisito es devolver el último día del mes, no el primero del mes siguiente. Pero no es difícil, solo obtenga la fecha de inicio (día en mes), agregue un mes y, si la fecha resultante no es la misma, configúrela en el 1, por ejemplo:
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()) );Day.js ya existe para hacer cálculos de fechas.
Puede usar su .add() para agregar 30 días a una fecha dayjs().add(30, 'day') .
También puede formatear las fechas con .format() para formatearlas de la manera que desee dayjs('2019-01-25').format('DD/MM/YYYY') // '25/01/2019'