Creé dos selectores de semana (html input type="week"). Quiero saber cuántas semanas hay entre las dos semanas seleccionadas. Estos son mis dos selectores de semana html:
<input type="week" id="weekPicker1" required="required" min="1971-W01" max="2071-W52" value="2021-W01"> <input type="week" id="weekPicker2" required="required" min="1971-W01" max="2071-W52" value="2021-W52"> Devuelve 2021-W01 y 2021-W52 como una cadena.
En este caso hay 52 semanas entre las fechas. Pero, ¿cómo puedo hacer que Javascript sepa esto también?
Tengo este código Javascript para asegurarme de obtener los años y las semanas como números:
// Get dates in usable format. let startDate = inputFields[0].value.split("-"); let startYear = Number(startDate[0]); //2021 let startWeek = Number(startDate[1].replace("W", "")); //1 let endDate = inputFields[1].value.split("-"); let endYear = Number(endDate[0]); //2021 let endWeek = Number(endDate[1].replace("W", "")); //52Pero ahora, ¿cómo calculo esto?
Pensé en esto:
var yearDiff = endYear - startYear; var amountOfWeeks = endWeek - startWeek; amountOfWeeks += yearDiff * 52;Creo que casi funciona, excepto que no todos los años tienen 52 semanas (año bisiesto). Entonces, ¿cómo debo hacer esto de manera eficiente?
Editar:
Me gustaría verlo en JS puro. No hay biblioteca ni cosas por el estilo. Y quiero la cantidad de semanas en base a un calendario como este . Entonces, el cálculo basado en una semana de 7 días no dará lo que quiero.
Al final necesito usar las semanas para hacer cálculos. Entonces, usar un selector de fechas para seleccionar semanas todavía parece incorrecto. También probé si podía hacer el cálculo en base a días, etc., pero daría resultados erróneos. Cálculo que tengo que hacer: (longitud de semanas seleccionada): (cantidad máxima de semanas en el año) * 200.
Use date-fns y differenceInCalendarWeeks .
const result = differenceInCalendarWeeks( startDate, endDate )hay 52 semanas + 1 día en un año y 52 semanas + 2 días en un año bisiesto. Así que su sugerencia amountOfWeeks += yearDiff * 52; no parece exacto. La siguiente función convierte el año y las semanas de inicio y finalización en milisegundos, resta y vuelve a convertir en semanas. Debería funcionar con años bisiestos. Aunque no lo he probado.
function compareWeeks(startYear, startWeek, endYear, endWeek) { const start = new Date(startYear, 0).getTime() + startWeek * 7 * 24 * 60 * 60 * 1000 const end = new Date(endYear, 0).getTime() + endWeek * 7 * 24 * 60 * 60 * 1000 const diff = Math.abs(end - start) const diffWeeks = diff / 1000 / 60 / 60 / 24 / 7 return diffWeeks } Actualización para el año de numeración de semanas ISO (su caso de uso):
Según la wikipedia , un año ISO tiene 52 o 53 (año bisiesto ISO) semanas. 53 cuando comienza o termina con el jueves 52 . Echa un vistazo al siguiente código:
function weeksInBetween(startYear, startWeek, endYear, endWeek) { let diff = 0 for (let i = startYear; i < endYear; i++) { const has53Weeks = isISOLeapYear(i) if (has53Weeks) { diff += 53 } else { diff += 52 } } return (diff += endWeek - --startWeek) /* the '--startWeek' makes sure the starting week is not subtracted from the result, because you want the result to be inclusive' */ } function isISOLeapYear(year) { const startsWithThursday = new Date(year, 0, 1).toString().split(' ')[0] === 'Thu' const endsWithThursday = new Date(year, 11, 31).toString().split(' ')[0] === 'Thu' if (startsWithThursday || endsWithThursday) { return true } return false } console.log( weeksInBetween(2020, 1, 2021, 52), // 105 weeksInBetween(2009, 1, 2010, 52), // 105 weeksInBetween(2021, 1, 2021, 52), // 52 weeksInBetween(2021, 1, 2022, 52), // 104 weeksInBetween(2021, 1, 2021, 1) // 1 )