Odpowiedzi:
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.
Dzień 0 to ostatni dzień poprzedniego miesiąca. Ponieważ konstruktor miesiąca jest oparty na 0, działa to ładnie. Trochę hack, ale to w zasadzie to, co robisz, odejmując 32.
var d=new Date();d.setFullYear(year, month, date);.
monthma 12 lat ? Czy Datekonstruktor nie powinien przyjmować wartości od 0 do 11 ?
Jeśli często wywołujesz tę funkcję, może być przydatne buforowanie wartości w celu uzyskania lepszej wydajności.
Oto wersja buforująca odpowiedzi 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(więc nie ma uniwersalnej odpowiedzi na to pytanie) i tego, jak często Twój kod będzie wywoływał metodę dayInMonthz tymi samymi wartościami. Więc jedyną rozsądną odpowiedzią jest: profiluj swój kod i testuj go!
cacheużywam localStorage.
Niektóre odpowiedzi (także na inne pytania) dotyczyły problemów z rokiem przestępnym lub wykorzystywały obiekt Date. Chociaż javascript Date objectobejmuje około 285616 lat (100 000 000 dni) po obu stronach 1 stycznia 1970 r., Miałem dość wszelkiego rodzaju nieoczekiwanych niespójności dat w różnych przeglądarkach (zwłaszcza w latach od 0 do 99). Byłem też ciekawy, jak to obliczyć.
Napisałem więc prosty, a przede wszystkim mały algorytm do obliczania poprawnej ( Proleptic Gregorian / Astronomical / ISO 8601: 2004 (punkt 4.3.2.1), więc rok0 istnieje i jest rokiem przestępnym, a lata ujemne są obsługiwane ) liczby dni dla danego miesiąca i roku.
Wykorzystuje algorytm zwarcia bitmask-modulo leapYear (nieznacznie zmodyfikowany dla js) i wspólny algorytm mod-8 miesięcy.
Zauważ, że w AD/BCnotacji rok 0 AD / BC nie istnieje: zamiast tego rok 1 BCjest rokiem przestępnym!
JEŚLI musisz uwzględnić notację BC, po prostu odejmij najpierw jeden rok (w przeciwnym razie dodatniej) wartości roku !! (Lub odejmij rok od 1do dalszych obliczeń).
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>
Uwaga, miesiące muszą być liczone od 1!
Zauważ, że jest to inny algorytm niż magiczne wyszukiwanie liczb, których użyłem w moim JavaScript, aby obliczyć dzień roku (1 - 366) odpowiedź, ponieważ tutaj dodatkowa gałąź dla roku przestępnego jest potrzebna tylko dla lutego.
Aby wyeliminować zamieszanie, prawdopodobnie utworzyłbym ciąg miesiąca na podstawie, ponieważ obecnie jest oparty na 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
Oto idzie
new Date(2019,2,0).getDate(); //28
new Date(2020,2,0).getDate(); //29
Składnia ES6
const d = (y, m) => new Date(y, m, 0).getDate();
zwroty
console.log( d(2020, 2) );
// 29
console.log( d(2020, 6) );
// 30
Biorąc pod uwagę lata przestępne:
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];
}
Bezpośrednie obliczenia jednowierszowe (bez obiektu 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
Odchylenie z miesiącami od 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);
}
Jeśli chcesz określić liczbę dni w bieżącym miesiącu obiektu Date, rozważ następującą metodę:
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();
}
}
Następnie możesz uruchomić to w ten sposób:
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!
Może być nieco przesadzone w porównaniu z wybraną odpowiedzią :) Ale oto jest:
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));
Powyższy kod znalazłem tutaj: 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));
Powyższy kod znalazłem tutaj: https://github.com/datejs/Datejs/blob/master/src/core.js
Jeśli zamierzasz przekazać zmienną daty, może to być pomocne
const getDaysInMonth = date =>
new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
daysInThisMonth = getDaysInMonth(new Date());
console.log(daysInThisMonth);
Być może nie jest to najbardziej eleganckie rozwiązanie, ale łatwe do zrozumienia i utrzymania; i jest przetestowany w walce.
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();