Calcola l’ultimo giorno del mese in JavaScript

Se fornisci 0 come dayValue in Date.setFullYear ottieni l’ultimo giorno del mese precedente:

 d = new Date(); d.setFullYear(2008, 11, 0); // Sun Nov 30 2008 

C’è un riferimento a questo comportamento in Mozilla . Si tratta di una funzionalità cross-browser affidabile o dovrei esaminare metodi alternativi?

 var month = 0; // January var d = new Date(2008, month + 1, 0); alert(d); // last day in January IE 6: Thu Jan 31 00:00:00 CST 2008 IE 7: Thu Jan 31 00:00:00 CST 2008 IE 8: Beta 2: Thu Jan 31 00:00:00 CST 2008 Opera 8.54: Thu, 31 Jan 2008 00:00:00 GMT-0600 Opera 9.27: Thu, 31 Jan 2008 00:00:00 GMT-0600 Opera 9.60: Thu Jan 31 2008 00:00:00 GMT-0600 Firefox 2.0.0.17: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time) Firefox 3.0.3: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time) Google Chrome 0.2.149.30: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time) Safari for Windows 3.1.2: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time) 

Le differenze di output sono dovute a differenze nell’implementazione di toString() , non perché le date sono diverse.

Naturalmente, solo perché i browser identificati in precedenza utilizzano 0 come ultimo giorno del mese precedente non significa che continueranno a farlo, o che i browser non elencati lo faranno, ma conferisce credibilità alla convinzione che dovrebbe funzionare allo stesso modo in ogni browser.

Vorrei utilizzare una data intermedia con il primo giorno del mese successivo e restituire la data del giorno precedente:

 int_d = new Date(2008, 11+1,1); d = new Date(int_d - 1); 

Trovo che questa sia la soluzione migliore per me. Lascia che l’object Date lo calcoli per te.

 var today = new Date(); var lastDayOfMonth = new Date(today.getFullYear(), today.getMonth()+1, 0); 

Impostare il parametro del giorno su 0 significa un giorno in meno del primo giorno del mese che è l’ultimo giorno del mese precedente.

Il mio collega ha inciampato su quanto segue che potrebbe essere una soluzione più facile

 function daysInMonth(iMonth, iYear) { return 32 - new Date(iYear, iMonth, 32).getDate(); } 

rubato da http://snippets.dzone.com/posts/show/2099

In termini informatici, le new Date() e regular expression sono lente! Se vuoi un one-liner super veloce (e super-criptico), prova questo (supponendo che m sia in formato Jan=1 ). Continuo a provare diverse modifiche al codice per ottenere le migliori prestazioni.

La mia versione più veloce attuale:

Dopo aver esaminato questa domanda correlata Controllo anno bisestile usando operatori bit a bit (velocità incredibile) e scoprendo che cosa rappresentava il numero magico 25 & 15, ho trovato questo ibrido ottimizzato di risposte:

 function getDaysInMonth(m, y) { return m===2 ? y & 3 || !(y%25) && y & 15 ? 28 : 29 : 30 + (m+(m>>3)&1); } 

Dato lo spostamento di bit, questo ovviamente presuppone che i parametri di m & y siano entrambi interi, poiché i numeri di passaggio come stringhe comporterebbero risultati strani.

JSFiddle: http://jsfiddle.net/TrueBlueAussie/H89X3/22/

Risultati JSPerf: http://jsperf.com/days-in-month-head-to-head/5

Per qualche ragione, (m+(m>>3)&1) è più efficiente di (5546>>m&1) su quasi tutti i browser.

L’unica vera competizione per la velocità è di @GitaarLab, quindi ho creato un JSPerf testa a testa per testare su: http://jsperf.com/days-in-month-head-to-head/5


Funziona sulla base della mia risposta all’anno bisestile: javascript per trovare l’anno bisestile questa risposta qui Controllo dell’anno bisestile utilizzando operatori bit a bit (velocità sorprendente) e la seguente logica binaria.

Una breve lezione sui mesi binari:

Se si interpreta l’indice dei mesi desiderati (Jan = 1) in binario, si noterà che i mesi con 31 giorni hanno il bit 3 chiaro e il bit 0 impostato, o il bit 3 impostato e il bit 0 chiaro.

 Jan = 1 = 0001 : 31 days Feb = 2 = 0010 Mar = 3 = 0011 : 31 days Apr = 4 = 0100 May = 5 = 0101 : 31 days Jun = 6 = 0110 Jul = 7 = 0111 : 31 days Aug = 8 = 1000 : 31 days Sep = 9 = 1001 Oct = 10 = 1010 : 31 days Nov = 11 = 1011 Dec = 12 = 1100 : 31 days 

Ciò significa che puoi spostare il valore 3 posti con >> 3 , XOR i bit con l’originale ^ m e vedere se il risultato è 1 o 0 nella posizione bit 0 usando & 1 . Nota: risulta che + è leggermente più veloce di XOR ( ^ ) e (m >> 3) + m dà lo stesso risultato nel bit 0.

Risultati JSPerf : http://jsperf.com/days-in-month-perf-test/6

Una leggera modifica alla soluzione fornita da lebreeze :

 function daysInMonth(iMonth, iYear) { return new Date(iYear, iMonth, 0).getDate(); } 

Questo funziona per me. Fornirà l’ultimo giorno dell’anno e del mese indicati:

 var d = new Date(2012,02,0); var n = d.getDate(); alert(n); 

prova questo.

 lastDateofTheMonth = new Date(year, month, 0) 

esempio:

 new Date(2012, 8, 0) 

produzione:

 Date {Fri Aug 31 2012 00:00:00 GMT+0900 (Tokyo Standard Time)} 

Questo funziona bene:

 Date.prototype.setToLastDateInMonth = function () { this.setDate(1); this.setMonth(this.getMonth() + 1); this.setDate(this.getDate() - 1); return this; } 
 function getLastDay(y, m) { return 30 + (m < = 7 ? ((m % 2) ? 1 : 0) : (!(m % 2) ? 1 : 0)) - (m == 2) - (m == 2 && y % 4 != 0 || !(y % 100 == 0 && y % 400 == 0)); } 

imposta il mese che hai bisogno di datare e poi imposta il giorno a zero, quindi il mese inizia in 1 – 31 in data, quindi ottieni l’ultimo giorno ^^

 var last = new Date(new Date(new Date().setMonth(7)).setDate(0)).getDate(); console.log(last); 

So che è solo questione di semantica, ma ho finito per usarlo in questa forma.

 var lastDay = new Date(new Date(2008, 11+1,1) - 1).getDate(); console.log(lastDay); 

Poiché le funzioni sono risolte dall’argomento interno, verso l’esterno, funziona allo stesso modo.

È quindi ansible sostituire solo l’anno e il mese / anno con i dettagli richiesti, indipendentemente dalla data corrente. O un mese / anno particolare.

Sotto la funzione dà l’ultimo giorno del mese:

 function getLstDayOfMonFnc(date) { return new Date(date.getFullYear(), date.getMonth(), 0).getDate() } console.log(getLstDayOfMonFnc(new Date(2016, 2, 15))) // Output : 29 console.log(getLstDayOfMonFnc(new Date(2017, 2, 15))) // Output : 28 console.log(getLstDayOfMonFnc(new Date(2017, 11, 15))) // Output : 30 console.log(getLstDayOfMonFnc(new Date(2017, 12, 15))) // Output : 31 

Allo stesso modo possiamo ottenere il primo giorno del mese:

 function getFstDayOfMonFnc(date) { return new Date(date.getFullYear(), date.getMonth(), 1).getDate() } console.log(getFstDayOfMonFnc(new Date(2016, 2, 15))) // Output : 1 

Questo ti darà il mese corrente il primo e l’ultimo giorno.

Se è necessario cambiare “anno”, rimuovere d.getFullYear () e impostare l’anno.

Se è necessario cambiare “mese”, rimuovere d.getMonth () e impostare l’anno.

 var d = new Date(); var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; var fistDayOfMonth = days[(new Date(d.getFullYear(), d.getMonth(), 1).getDay())]; var LastDayOfMonth = days[(new Date(d.getFullYear(), d.getMonth() + 1, 0).getDay())]; console.log("First Day :" + fistDayOfMonth); console.log("Last Day:" + LastDayOfMonth); alert("First Day :" + fistDayOfMonth); alert("Last Day:" + LastDayOfMonth); 

No, non tutti i browser utilizzeranno 0 come ultimo giorno. IE e Firefox lo faranno ma Opera no.

Controlla la seguente fonte per maggiori informazioni:

Ultimo giorno del mese