Каков наилучший способ определить количество дней в месяце с помощью JavaScript?
Я использую эту функцию, но я хотел бы знать, какой самый эффективный и точный способ получить его.
function daysInMonth(iMonth, iYear) {
return 32 - new Date(iYear, iMonth, 32).getDate();
}
12 ответов
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.
Если вы часто вызываете эту функцию, может быть полезно кэшировать значение для повышения производительности.
вот кэширование версии ответ 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();
}
})();
некоторые ответы (также на другие вопросы) имели високосные проблемы или использовали объект даты. Хотя javascript Date object
охватывает приблизительно 285616 лет (100 000 000 дней) по обе стороны от 1 января 1970 года, я был сыт по горло всеми видами неожиданной даты противоречия в разных браузерах (особенно год от 0 до 99). Мне также было любопытно, как его вычислить.
поэтому я написал простой и, прежде всего, маленький алгоритм вычисления правильно (Proleptic Григорианский / Astronomical / ISO 8601: 2004 (пункт 4.3.2.1), so год 0
существует и является високосным и отрицательные годы поддерживаются) количество дней для заданного месяца и года.
Он использует короткое замыкание маска-дулю алгоритм leapYear (слегка модифицированный для js) и общий алгоритм mod-8 месяцев.
обратите внимание, что в AD/BC
нотации, 0 год н. э./до н. э. не существует: вместо года 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
С момент.js вы можете использовать метод daysInMonth ():
moment().daysInMonth(); // number of days in the current month
moment("2012-02", "YYYY-MM").daysInMonth() // 29
moment("2012-01", "YYYY-MM").daysInMonth() // 31
однострочное прямое вычисление (без объекта даты):
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
вариация с с 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);
}
Если вы хотите количество дней в текущем месяце объекта даты, рассмотрим следующий метод:
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!
в одну строку:
// 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;
}
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
}
учитывая високосные годы:
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];
}
возможно, не самое элегантное решение, но легко понять и поддерживать; и, это боевое испытание.
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;
},