Primero tiene un número de serie que se convirtió a partir de una fecha, por ejemplo: 40988 sería el 21 de marzo de 2012. ¿Cómo podría devolver 21 sabiendo que el número de serie es 40988 y NO usando el objeto de fecha? También tengo otras 2 funciones que puedo usar: numberOfDaysYear(year) que devuelve la cantidad de días de un año específico (365 o 366) y también tengo numberOfDaysMonth(month, year) que devuelve la cantidad de días de un mes específico y un año específico (31, 30, 28 o 29). El límite de años va desde 1900 hasta 2199, así que esto es con lo que comencé
`
//Count the number of 365 years and 366 years var counterNormalYears = 0 var counterLeapYears = 0 for (let i = 1900; i <= 2199; i++) { if (numberOfDaysYear(i) == 365) { counterNormalYears += 1 } else if (numberOfDaysYear(i) == 366) { counterLeapYears += 1 } }` Pasando de aquí, ¿qué tipo de enfoque podría tomar para luego encontrar los días que tiene la fecha sin usar el objeto de fecha?
probablemente lo haría como
let day = 40988, year = 1899, month = 0; while (day > 0) day -= numberOfDaysYear(++year); day += numberOfDaysYear(year); while (day > 0) day -= numberOfDaysMonth(++month, year); day += numberOfDaysMonth(month, year);Para explicar ...
year utilizado de nuevo a los daysday a las 2, debido a las matemáticas 🤣tenía un problema en el código original... pero esto debería funcionar
Sin embargo, prefiero usar Fecha
d = new Date('1900-01-01'); d.setDate(40988 + 1); // because of maths 🤣 // doneNo muestra las otras funciones, así que me burlé de ellas. Un método simple es contar los días de cada año desde 1900 hasta que queden menos de 1 año de días. Luego cuente los días de cada mes hasta que queden menos de 1 mes. Los días restantes son el día del mes.
La función daysToDate devuelve una matriz de [año, mes, día] como números para que sea más útil. Si solo quieres el día, solo obtén el último elemento. En el ejemplo, convertí los valores en una marca de tiempo AAAA-MM-DD.
Realiza una validación mínima de la entrada, probablemente se requiera un poco más.
// Return true if year is a leap year function isLeap(year) { return !(year % 4 || !(year % 100) && year % 400); } // Return number of days in year function daysInYear(year) { return isLeap(year)? 366 : 365; } // Return number of days in month // Month is calendar month number function daysInMonth(year, month) { if (month == 2 && isLeap(year)) { return 29; } return [,31,28,31,30,31,30,31,31,30,31,30,31][month]; } // Convert days since 1900 to [year, month, day] // Month is calendar month number // Assumes 1 Jan 1900 is 1 function daysToDate(days) { // Ensure days is within range 1990-01-01 to 2199-12-31 if (days < 1 || days > 109573) { return; } let daysCounted = 0; let year = 1900; // Loop over years until less than a year's worth // of days left while (daysInYear(year) < (days - daysCounted)) { daysCounted += daysInYear(year); ++year; } let month = 1; // Loop over month until less than a month's worth // of days left while (daysInMonth(year, month) < (days - daysCounted)) { daysCounted += daysInMonth(year, month); ++month; } return [year, month, days - daysCounted]; } [ 1, // 1 Jan 1900 365, // 31 Dec 1900 366, // 1 Jan 1901 730, // 31 Dec 1901 40988, // 21 Mar 2012 109573 // 31 Dec 2199 ].forEach(days => console.log( days + ': ' + daysToDate(days).map(n=>(n<10?'0':'')+n).join('-') ));