2008-11-24 13 views

Respuesta

149

function daysInMonth (month, year) { // Use 1 for January, 2 for February, etc. 
 
    return new Date(year, month, 0).getDate(); 
 
} 
 

 
console.log(daysInMonth(2, 1999)); // February in a non-leap year. 
 
console.log(daysInMonth(2, 2000)); // February in a leap year.

El día 0 es el último día del mes anterior. Como el constructor del mes está basado en 0, funciona bien. Un poco de un truco, pero eso es básicamente lo que está haciendo al restar 32.

+35

esta sintaxis me ha estado confundiendo por un tiempo. Para seguir el patrón de JS, recomendaré implementar el truco de esta manera: 'return new Date (year, month + 1, 0) .getDate();' – fguillen

+2

Desafortunadamente, esto falla para las fechas anteriores al 1000 AD donde solo se puede configurar el año correctamente al usar SetFullYear(). Para que sea a prueba de balas, use nueva Fecha (2000+ (año% 2000), mes, 0) .getDate() –

+4

Nota para mi yo futuro: la ecuación de fguillen con el '+ 1' da 28 días cuando el año es 2014 y el mes es 1 (que, en JavaScript Date-object, significa febrero). Probablemente quiera ir con eso para al menos asombro. ¡Pero qué gran idea de FlySwat! –

7

Si llama a esta función a menudo, puede ser útil guardar en caché el valor para un mejor rendimiento.

Aquí es el cacheado versión de FlySwat's answer:

var daysInMonth = (function() { 
    var cache = {}; 
    return function(month, year) { 
     var entry = year + '-' + month; 

     if (cache[entry]) return cache[entry]; 

     return cache[entry] = new Date(year, month, 0).getDate(); 
    } 
})(); 
+5

¿La rutina C/C++ interna es tan lenta que esto requiere el almacenamiento en caché? –

+1

@PeteAlvin Depende de la implementación de 'Date' (por lo que no hay una respuesta universal a esa pregunta) y de la frecuencia con la que su código llamará al' dayInMonth' con los mismos valores. Entonces, la única respuesta sensata es: ¡perfila tu código y cámbialo de referencia! – dolmen

+1

¡Me gusta! Pero en lugar de usar un objeto nuevo, 'caché', uso' localStorage'. – andrew

0
function numberOfDays(iMonth, iYear) { 
     var myDate = new Date(iYear, iMonth + 1, 1); //find the fist day of next month 
     var newDate = new Date(myDate - 1); //find the last day 
      return newDate.getDate();   //return # of days in this month 
     } 
5

Algunas respuestas (también en otras cuestiones) tenía problemas de años bisiestos o utilizará la fecha a objetos. Aunque el Date object de javascript cubre aproximadamente 285616 años (100,000,000 días) a cada lado del 1 de enero de 1970, estaba harto de todo tipo de fechas inesperadas inconsistencies en diferentes navegadores (más notablemente en el año 0 a 99). También tenía curiosidad por cómo calcularlo.

Así que escribió un sencillo y, sobre todo, pequeña algoritmo para calcular la correcta (ProlepticGregorian/astronómico/ISO 8601: 2004 (cláusula 4.3.2.1), por lo year 0 existe y es un año bisiesto y años negativos son compatibles) número de días para un mes y año dados.
Utiliza el algoritmo short-circuit bitmask-modulo leapYear algorithm (ligeramente modificado para js) y el mod-8 de mes común.

Tenga en cuenta que en la notación AD/BC, año 0 AD/BC no existe: en su lugar año 1 BC es el año bisiesto!
SI necesita registrar la notación BC, simplemente restar un año del valor anual (de lo contrario positivo) primero !! (O restar el año de 1 para más años de cálculos.)

function daysInMonth(m, y){ 
 
    return m===2?y&3||!(y%25)&&y&15?28:29:30+(m+(m>>3)&1); 
 
}
<!-- example for the snippet --> 
 
<input type="text" value="enter year" onblur=" 
 
    for(var r='', i=0, y=+this.value 
 
    ; 12>i++ 
 
    ; r+= 'Month: ' + i + ' has ' + daysInMonth(i, y) + ' days<br>' 
 
    ); 
 
    this.nextSibling.innerHTML=r; 
 
" /><div></div>

Nota, meses deben basarse-1!

Nota, este es un algoritmo diferente a la búsqueda de número mágico que utilicé en mi respuesta Javascript calculate the day of the year (1 - 366), porque aquí la rama adicional para el año bisiesto solo es necesaria para febrero.

0

Teniendo en cuenta los años bisiestos:

function (year, month) { 
    var isLeapYear = ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0); 

    return [31, (isLeapYear ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]; 
} 
3

Para quitar la confusión que probablemente haría que la cadena meses basada como está actualmente basada 1.

function daysInMonth(month,year) { 
    monthNum = new Date(Date.parse(month +" 1,"+year)).getMonth()+1 
    return new Date(year, monthNum, 0).getDate(); 
} 

daysInMonth('feb', 2015) 
//28 

daysInMonth('feb', 2008) 
//29 
2

Con moment.js DaysInMonth() método que puede utilizar:

moment().daysInMonth(); // number of days in the current month 
moment("2012-02", "YYYY-MM").daysInMonth() // 29 
moment("2012-01", "YYYY-MM").daysInMonth() // 31 
1

de una sola línea cálculo directo (sin objeto Date):

function daysInMonth(m, y) {//m is 1-based, feb = 2 
 
    return 31 - (--m^1? m % 7 & 1: y & 3? 3: y % 25? 2: y & 15? 3: 2); 
 
} 
 

 
console.log(daysInMonth(2, 1999)); // February in a non-leap year 
 
console.log(daysInMonth(2, 2000)); // February in a leap year

Variación con la 0 meses basados:

function daysInMonth(m, y) {//m is 0-based, feb = 1 
    return 31 - (m^1? m % 7 & 1: y & 3? 3: y % 25? 2: y & 15? 3: 2); 
} 
1

Si desea que el número de días del mes actual de un objeto Date, consideremos el siguiente método:

Date.prototype.getNumberOfDaysInMonth = function(monthOffset) { 
    if (monthOffset !== undefined) { 
     return new Date(this.getFullYear(), this.getMonth()+monthOffset, 0).getDate(); 
    } else { 
     return new Date(this.getFullYear(), this.getMonth(), 0).getDate(); 
    } 
} 

continuación, puede ejecutar de esta manera:

var myDate = new Date(); 
myDate.getNumberOfDaysInMonth(); // Returns 28, 29, 30, 31, etc. as necessary 
myDate.getNumberOfDaysInMonth(); // BONUS: This also tells you the number of days in past/future months! 
0

En una sola línea:

// month is 1-12 
function getDaysInMonth(year, month){ 
    return month == 2 ? 28 + (year % 4 == 0 ? (year % 100 == 0 ? (year % 400 == 0 ? 1 : 0) : 1):0) : 31 - (month - 1) % 7 % 2; 
} 
0

Quizás no sea la solución más elegante, pero e asy para entender y mantener; y, está probado en la batalla.

function daysInMonth(month, year) { 
    var days; 
    switch (month) { 
     case 1: // Feb, our problem child 
      var leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0); 
      days = leapYear ? 29 : 28; 
      break; 
     case 3: case 5: case 8: case 10: 
      days = 30; 
      break; 
     default: 
      days = 31; 
     } 
    return days; 
}, 
Cuestiones relacionadas