Ответы:
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.
День 0 - последний день предыдущего месяца. Поскольку конструктор месяца основан на 0, это прекрасно работает. Немного взлома, но в основном это то, что вы делаете, вычитая 32.
var d=new Date();d.setFullYear(year, month, date);.
monthесть 12 ? Разве Dateконструктор не должен принимать значение от 0 до 11 ?
Если вы часто вызываете эту функцию, может быть полезно кэшировать значение для повышения производительности.
Вот кеширующая версия ответа 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(поэтому универсального ответа на этот вопрос нет) и от того, как часто ваш код будет вызывать dayInMonthс одинаковыми значениями. Итак, единственный разумный ответ: профилируйте свой код и сравните его!
cacheя использую localStorage.
В некоторых ответах (также на другие вопросы) были проблемы с високосным годом или использовался объект Date. Хотя javascript Date objectохватывает примерно 285616 лет (100000000 дней) по обе стороны от 1 января 1970 года, мне надоели всевозможные неожиданные несоответствия дат в разных браузерах (особенно с 0 по 99 год). Мне также было любопытно, как это рассчитать.
Поэтому я написал простой и, прежде всего, небольшой алгоритм для вычисления правильного ( Proleptic Gregorian / Astronomical / ISO 8601: 2004 (пункт 4.3.2.1), поэтому год0 существует и является високосным, и поддерживаются отрицательные годы ) количества дней для данный месяц и год.
Он использует алгоритм короткого замыкания bitmask-modulo leapYear (немного изменен для js) и общий алгоритм mod-8 месяцев.
Обратите внимание, что в AD/BCнотации год 0 AD / BC не существует: вместо этого год 1 BCявляется високосным!
ЕСЛИ вам нужно учесть нотацию BC, тогда просто сначала вычтите один год из (в противном случае положительного) годового значения !! (Или вычтите год из 1для дальнейших расчетов года.)
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>
Обратите внимание, месяцы должны начинаться с 1!
Обратите внимание, что это другой алгоритм, чем поиск по магическому числу, который я использовал в своем Javascript, вычисляющий день года (1 - 366) , потому что здесь дополнительная ветка для високосного года нужна только для февраля.
Чтобы устранить путаницу, я бы, вероятно, сделал строку месяца на основе, поскольку в настоящее время она основана на 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
Вот идет
new Date(2019,2,0).getDate(); //28
new Date(2020,2,0).getDate(); //29
Синтаксис ES6
const d = (y, m) => new Date(y, m, 0).getDate();
возвращается
console.log( d(2020, 2) );
// 29
console.log( d(2020, 6) );
// 30
С учетом високосных лет:
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];
}
Однострочное прямое вычисление (без объекта 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
Вариация с нулевыми месяцами:
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);
}
Если вам нужно количество дней в текущем месяце объекта Date, рассмотрите следующий метод:
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();
}
}
Тогда вы можете запустить его так:
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!
Может быть, немного убить по сравнению с выбранным ответом :) Но вот он:
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));
Я нашел приведенный выше код здесь: 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));
Я нашел приведенный выше код здесь: https://github.com/datejs/Datejs/blob/master/src/core.js
Если вы собираетесь передать переменную даты, это может быть полезно
const getDaysInMonth = date =>
new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
daysInThisMonth = getDaysInMonth(new Date());
console.log(daysInThisMonth);
Возможно, не самое элегантное решение, но простое для понимания и обслуживания; и это проверено в боях.
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();