Respostas:
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.
O dia 0 é o último dia do mês anterior. Como o construtor de mês é baseado em 0, isso funciona bem. Um pouco hack, mas é basicamente isso que você está fazendo subtraindo 32.
var d=new Date();d.setFullYear(year, month, date);
.
month
for 12 ? O Date
construtor não deveria ter um valor de 0 a 11 ?
Se você chamar essa função com frequência, pode ser útil armazenar o valor em cache para melhor desempenho.
Aqui está a versão em cache da resposta do FlySwat :
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();
}
})();
Date
(portanto, não há uma resposta universal para essa pergunta) e da frequência com que seu código chamará o dayInMonth
com os mesmos valores. Portanto, a única resposta sensata é: analise o seu código e faça um benchmark!
cache
, eu uso localStorage
.
Algumas respostas (também em outras questões) tiveram problemas de ano bissexto ou usaram o objeto Data. Embora o javascript Date object
cubra aproximadamente 285616 anos (100 milhões de dias) em ambos os lados de 1º de janeiro de 1970, eu estava farto de todos os tipos de inconsistências de data inesperadas em diferentes navegadores (principalmente do ano 0 a 99). Também estava curioso para saber como calculá-lo.
Então eu escrevi um algoritmo simples e, acima de tudo, pequeno para calcular o número correto de dias ( Proléptico Gregoriano / Astronômico / ISO 8601: 2004 (cláusula 4.3.2.1), então ano0
existe e é um ano bissexto e anos negativos são suportados ) número de dias para um determinado mês e ano.
Ele usa o algoritmo bitmask-módulo leapYear de curto-circuito (ligeiramente modificado para js) e o algoritmo comum mod-8 meses.
Observe que, em AD/BC
notação, o ano 0 AD / BC não existe: em vez disso, o ano 1 BC
é o ano bissexto!
SE você precisar contabilizar a notação BC, simplesmente subtraia um ano do valor do ano (caso contrário positivo) primeiro !! (Ou subtraia o ano 1
para cálculos de ano adicionais.)
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, os meses devem ser baseados em 1!
Observe, este é um algoritmo diferente da pesquisa de número mágico que usei no meu Javascript para calcular o dia do ano (1 - 366) , porque aqui o ramo extra para o ano bissexto é necessário apenas para fevereiro.
Para tirar a confusão, eu provavelmente faria a string do mês com base, pois atualmente é baseada em 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
Com moment.js, você pode usar o método daysInMonth ():
moment().daysInMonth(); // number of days in the current month
moment("2012-02", "YYYY-MM").daysInMonth() // 29
moment("2012-01", "YYYY-MM").daysInMonth() // 31
Aqui vai
new Date(2019,2,0).getDate(); //28
new Date(2020,2,0).getDate(); //29
Sintaxe ES6
const d = (y, m) => new Date(y, m, 0).getDate();
retorna
console.log( d(2020, 2) );
// 29
console.log( d(2020, 6) );
// 30
Considerando os anos bissextos:
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];
}
Cálculo direto de uma linha (sem 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
Variação com meses baseados em 0:
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);
}
Se você quiser o número de dias no mês atual de um objeto Date, considere o seguinte 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();
}
}
Então você pode executá-lo assim:
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!
Pode ser um pouco matador em comparação com a resposta selecionada :) Mas aqui está:
function getDayCountOfMonth(year, month) {
if (month === 3 || month === 5 || month === 8 || month === 10) {
return 30;
}
if (month === 1) {
if (year % 4 === 0 && year % 100 !== 0 || year % 400 === 0) {
return 29;
} else {
return 28;
}
}
return 31;
};
console.log(getDayCountOfMonth(2020, 1));
Encontrei o código acima aqui: https://github.com/ElemeFE/element/blob/dev/src/utils/date-util.js
function isLeapYear(year) {
return ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0);
};
const getDaysInMonth = function (year, month) {
return [31, (isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
};
console.log(getDaysInMonth(2020, 1));
Encontrei o código acima aqui: https://github.com/datejs/Datejs/blob/master/src/core.js
Se você vai passar uma variável de data, isso pode ser útil
const getDaysInMonth = date =>
new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
daysInThisMonth = getDaysInMonth(new Date());
console.log(daysInThisMonth);
Talvez não seja a solução mais elegante, mas fácil de entender e manter; e é testado em batalha.
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;
},
return new Date(year, month + 1, 0).getDate();