Come si usa javascript per calcolare il giorno dell'anno, da 1 a 366? Per esempio:
- Il 3 gennaio dovrebbe essere il 3 .
- Il 1 febbraio dovrebbe essere 32 .
Come si usa javascript per calcolare il giorno dell'anno, da 1 a 366? Per esempio:
Risposte:
A seguito della modifica dell'OP:
var now = new Date();
var start = new Date(now.getFullYear(), 0, 0);
var diff = now - start;
var oneDay = 1000 * 60 * 60 * 24;
var day = Math.floor(diff / oneDay);
console.log('Day of year: ' + day);
Modifica: il codice precedente non funzionerà quando nowè una data compresa tra il 26 marzo e il 29 ottobre e nowl'ora è prima dell'01: 00 (ad esempio 00:59:59). Ciò è dovuto al fatto che il codice non tiene conto dell'ora legale. Dovresti compensare questo:
var now = new Date();
var start = new Date(now.getFullYear(), 0, 0);
var diff = (now - start) + ((start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000);
var oneDay = 1000 * 60 * 60 * 24;
var day = Math.floor(diff / oneDay);
console.log('Day of year: ' + day);
Math.floorcostantemente mi ha dato un risultato di 1 giorno in meno del previsto dopo un certo giorno di aprile. Math.ceilha funzionato come previsto, ma ho visto che è consigliabile utilizzare al Math.roundposto di entrambi.
new Date(2014, 0, 1), e non new Date(2014, 0, 0)come hai qui. È intenzionale? Forse questo è ciò che spiega l'essere fuori un giorno come new Date(2014, 0, 0)tornerà 12/31/2013.
.setUTCHourse Date.UTC()per una soluzione più affidabile.
ceilpiuttosto che floor, questo ti darà un sistema di numerazione in cui Jan 1st = 1. Se vuoi Jan 1st = 0 (come floorti darebbe), sottrai 1 dal tuo risultato finale.
var diff = now - start + (start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000;
Funziona con i cambiamenti dell'ora legale in tutti i paesi (il "mezzogiorno" sopra non funziona in Australia):
Date.prototype.isLeapYear = function() {
var year = this.getFullYear();
if((year & 3) != 0) return false;
return ((year % 100) != 0 || (year % 400) == 0);
};
// Get Day of Year
Date.prototype.getDOY = function() {
var dayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
var mn = this.getMonth();
var dn = this.getDate();
var dayOfYear = dayCount[mn] + dn;
if(mn > 1 && this.isLeapYear()) dayOfYear++;
return dayOfYear;
};
getDay()deve essere cambiato in getDate(). Il primo restituisce il giorno della settimana (0 = domenica..6 = sabato), non il giorno.
Trovo molto interessante che nessuno abbia preso in considerazione l'utilizzo di UTC poiché non è soggetto a DST. Pertanto, propongo quanto segue:
function daysIntoYear(date){
return (Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()) - Date.UTC(date.getFullYear(), 0, 0)) / 24 / 60 / 60 / 1000;
}
Puoi testarlo con quanto segue:
[new Date(2016,0,1), new Date(2016,1,1), new Date(2016,2,1), new Date(2016,5,1), new Date(2016,11,31)]
.forEach(d =>
console.log(`${d.toLocaleDateString()} is ${daysIntoYear(d)} days into the year`));
Quali uscite per l'anno bisestile 2016 (verificate utilizzando http://www.epochconverter.com/days/2016 ):
1/1/2016 is 1 days into the year
2/1/2016 is 32 days into the year
3/1/2016 is 61 days into the year
6/1/2016 is 153 days into the year
12/31/2016 is 366 days into the year
function doyToDate(doy, year) { return new Date(year, 0, doy); }
new Date(8640000000000000), che è ancora inferiore a Number.MAX_SAFE_INTEGER. vedi questa risposta: stackoverflow.com/a/11526569/18511
Date.prototype.dayOfYear= function(){
var j1= new Date(this);
j1.setMonth(0, 0);
return Math.round((this-j1)/8.64e7);
}
alert(new Date().dayOfYear())
Per fortuna questa domanda non specifica se è richiesto il numero del giorno corrente , lasciando spazio a questa risposta.
Anche alcune risposte (anche su altre domande) avevano problemi di anno bisestile o utilizzavano l'oggetto Date. Sebbene javascript Date objectcopra circa 285616 anni (100.000.000 giorni) su entrambi i lati del 1 gennaio 1970, ero stufo di tutti i tipi di incongruenze di date inaspettate tra browser diversi (in particolare dall'anno 0 a 99). Ero anche curioso di sapere come calcolarlo.
Quindi ho scritto un semplice e soprattutto piccolo algoritmo per calcolare il giorno dell'anno corretto ( Proleptic Gregorian / Astronomical / ISO 8601: 2004 (clausola 4.3.2.1), quindi l' anno0 esiste ed è un anno bisestile e gli anni negativi sono supportati ) giorno dell'anno basato su anno , mese e giorno .
Notare che in AD/BCnotazione, l'anno 0 d.C. / BC non esiste: invece l'anno 1 BCè l'anno bisestile! SE è necessario tenere conto della notazione BC, sottrarre prima un anno dal valore dell'anno (altrimenti positivo) !!
Ho modificato (per javascript) l' algoritmo bitmask-modulo leapYear di cortocircuito e ho creato un numero magico per eseguire una ricerca un po 'saggia degli offset (che esclude jan e feb, quindi necessitano di 10 * 3 bit (30 bit è inferiore a 31 bit, quindi possiamo salvare in sicurezza un altro carattere su bitshift invece di >>>)).
Nota che né il mese né il giorno possono esserlo 0. Ciò significa che se hai bisogno di questa equazione solo per il giorno corrente (alimentandola usando .getMonth()) devi solo rimuovere --da --m.
Nota che questo presuppone una data valida (sebbene il controllo degli errori sia solo qualche carattere in più).
function dayNo(y,m,d){
return --m*31-(m>1?(1054267675>>m*3-6&7)-(y&3||!(y%25)&&y&15?0:1):0)+d;
}
<!-- some examples for the snippet -->
<input type=text value="(-)Y-M-D" onblur="
var d=this.value.match(/(-?\d+)[^\d]+(\d\d?)[^\d]+(\d\d?)/)||[];
this.nextSibling.innerHTML=' Day: ' + dayNo(+d[1], +d[2], +d[3]);
" /><span></span>
<br><hr><br>
<button onclick="
var d=new Date();
this.nextSibling.innerHTML=dayNo(d.getFullYear(), d.getMonth()+1, d.getDate()) + ' Day(s)';
">get current dayno:</button><span></span>
Ecco la versione con la corretta convalida dell'intervallo.
function dayNo(y,m,d){
return --m>=0 && m<12 && d>0 && d<29+(
4*(y=y&3||!(y%25)&&y&15?0:1)+15662003>>m*2&3
) && m*31-(m>1?(1054267675>>m*3-6&7)-y:0)+d;
}
<!-- some examples for the snippet -->
<input type=text value="(-)Y-M-D" onblur="
var d=this.value.match(/(-?\d+)[^\d]+(\d\d?)[^\d]+(\d\d?)/)||[];
this.nextSibling.innerHTML=' Day: ' + dayNo(+d[1], +d[2], +d[3]);
" /><span></span>
Di nuovo, una riga, ma l'ho divisa in 3 righe per leggibilità (e spiegazione successiva).
L'ultima riga è identica alla funzione sopra, tuttavia l'algoritmo leapYear (identico) viene spostato in una sezione di cortocircuito precedente (prima del calcolo del numero di giorni), perché è anche necessario sapere quanti giorni ha un mese in un dato (bisestile) anno.
La linea centrale calcola il numero di offset corretto (per il numero massimo di giorni) per un dato mese in un dato anno (bisestile) utilizzando un altro numero magico: poiché 31-28=3e 3è solo 2 bit, quindi 12*2=24bit, possiamo memorizzare tutti i 12 mesi. Poiché l'addizione può essere più veloce della sottrazione, aggiungiamo l'offset (invece di sottrarlo da 31). Per evitare un ramo decisionale di un anno bisestile per febbraio, modifichiamo quel numero magico di ricerca al volo.
Questo ci lascia con la prima riga (abbastanza ovvia): controlla che il mese e la data siano entro limiti validi e ci garantisce un falsevalore di ritorno sull'errore di intervallo (nota che anche questa funzione non dovrebbe essere in grado di restituire 0, perché 1 gen 0000 è ancora giorno 1.), che fornisce un facile controllo degli errori: if(r=dayNo(/*y, m, d*/)){}.
Se utilizzato in questo modo (dove mese e giorno potrebbero non essere 0), è possibile passare --m>=0 && m<12a m>0 && --m<12(salvando un altro carattere).
Il motivo per cui ho digitato lo snippet nella sua forma attuale è che per i valori del mese basati su 0, è sufficiente rimuovere il file --da --m.
Extra:
Nota, non utilizzare l'algoritmo di questo giorno al mese se hai bisogno solo del numero massimo di giorni al mese. In quel caso c'è un algoritmo più efficiente (perché abbiamo solo bisogno di leepYear quando il mese è febbraio) Ho postato come risposta a questa domanda: Qual è il modo migliore per determinare il numero di giorni in un mese con javascript? .
Date.prototype.dayNo = function(){ var y = this.getFullYear(); var m = this.getMonth()+1; var d = this.getDate(); return --m*31-(m>1?(1054267675>>m*3-6&7)-(y&3||!(y%25)&&y&15?0:1):0)+d; };
+1da this.getMonth()+1se rimuovi --da --m. EDIT Quindi, farei (per una libreria):Date.prototype.dayNo = function(){ var y=this.getFullYear(), m=this.getMonth(); return m*31-(m>1?(1054267675>>m*3-6&7)-(y&3||!(y%25)&&y&15?0:1):0)+this.getDate(); };
2^31 - 2016anni da adesso, probabilmente sarà un po 'obsoleto.
:)Ma fino ad allora, fornirà almeno risultati prevedibili e coerenti ahah. EDIT , solo per amor di teoria, usando l'algoritmo all-modulo convenzionale più lento per l'anno bisestile, l'intervallo può essere esteso a 2 ^ 53. L'algoritmo di ricerca mensile non è il fattore limitante.
Se non vuoi reinventare la ruota, puoi usare l'eccellente libreria date-fns (node.js):
var getDayOfYear = require('date-fns/get_day_of_year')
var dayOfYear = getDayOfYear(new Date(2017, 1, 1)) // 1st february => 32
Bene, se ti ho capito bene, vuoi 366 su un anno bisestile, 365 altrimenti, giusto? Un anno è bisestile se è uniformemente divisibile per 4 ma non per 100 a meno che non sia divisibile anche per 400:
function daysInYear(year) {
if(year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)) {
// Leap year
return 366;
} else {
// Not a leap year
return 365;
}
}
In tal caso, non credo che ci sia un metodo integrato; dovrai fare questo:
function daysInFebruary(year) {
if(year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)) {
// Leap year
return 29;
} else {
// Not a leap year
return 28;
}
}
function dateToDay(date) {
var feb = daysInFebruary(date.getFullYear());
var aggregateMonths = [0, // January
31, // February
31 + feb, // March
31 + feb + 31, // April
31 + feb + 31 + 30, // May
31 + feb + 31 + 30 + 31, // June
31 + feb + 31 + 30 + 31 + 30, // July
31 + feb + 31 + 30 + 31 + 30 + 31, // August
31 + feb + 31 + 30 + 31 + 30 + 31 + 31, // September
31 + feb + 31 + 30 + 31 + 30 + 31 + 31 + 30, // October
31 + feb + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, // November
31 + feb + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, // December
];
return aggregateMonths[date.getMonth()] + date.getDate();
}
(Sì, in realtà l'ho fatto senza copiare o incollare. Se c'è un modo semplice, sarò pazzo)
:)
Questo è un modo semplice per trovare il giorno corrente dell'anno e dovrebbe tenere conto degli anni bisestili senza problemi:
Javascript:
Math.round((new Date().setHours(23) - new Date(new Date().getYear()+1900, 0, 1, 0, 0, 0))/1000/60/60/24);
Javascript in Google Apps Script:
Math.round((new Date().setHours(23) - new Date(new Date().getYear(), 0, 1, 0, 0, 0))/1000/60/60/24);
L'azione principale di questo codice è trovare il numero di millisecondi trascorsi nell'anno corrente e quindi convertire questo numero in giorni. Il numero di millisecondi trascorsi nell'anno in corso può essere trovato sottraendo il numero di millisecondi del primo secondo del primo giorno dell'anno corrente, che si ottiene con new Date(new Date().getYear()+1900, 0, 1, 0, 0, 0)(Javascript) o new Date(new Date().getYear(), 0, 1, 0, 0, 0)(Google Apps Script), dai millisecondi della 23a ora del giorno corrente, che è stato trovato con new Date().setHours(23). Lo scopo di impostare la data corrente sulla 23a ora è garantire che il giorno dell'anno sia arrotondato correttamente di Math.round().
Una volta ottenuto il numero di millisecondi dell'anno corrente, puoi convertire questo tempo in giorni dividendo per 1000 per convertire i millisecondi in secondi, quindi dividendo per 60 per convertire i secondi in minuti, quindi dividendo per 60 per convertire i minuti in ore, e infine dividendo per 24 per convertire le ore in giorni.
Nota: questo post è stato modificato per tenere conto delle differenze tra JavaScript e JavaScript implementato in Google Apps Script. Inoltre, è stato aggiunto più contesto per la risposta.
.setHoursmetodo sul primo oggetto data e ho specificato l'ora del giorno con il secondo oggetto data, una modifica di 1 ora dall'ora legale non influirà sugli orari degli oggetti Date utilizzati in questo calcolo.
Penso che questo sia più semplice:
var date365 = 0;
var currentDate = new Date();
var currentYear = currentDate.getFullYear();
var currentMonth = currentDate.getMonth();
var currentDay = currentDate.getDate();
var monthLength = [31,28,31,30,31,30,31,31,30,31,30,31];
var leapYear = new Date(currentYear, 1, 29);
if (leapYear.getDate() == 29) { // If it's a leap year, changes 28 to 29
monthLength[1] = 29;
}
for ( i=0; i < currentMonth; i++ ) {
date365 = date365 + monthLength[i];
}
date365 = date365 + currentDay; // Done!
Questo metodo tiene conto del problema del fuso orario e dell'ora legale
function dayofyear(d) { // d is a Date object
var yn = d.getFullYear();
var mn = d.getMonth();
var dn = d.getDate();
var d1 = new Date(yn,0,1,12,0,0); // noon on Jan. 1
var d2 = new Date(yn,mn,dn,12,0,0); // noon on input date
var ddiff = Math.round((d2-d1)/864e5);
return ddiff+1;
}
(preso da qui )
Vedi anche questo violino
Math.round ((new Date (). SetHours (23) - new Date (new Date (). GetFullYear (), 0, 1, 0, 0, 0)) / 1000/86400);
ottimizza ulteriormente la risposta.
Inoltre, modificando setHours (23) o il penultimo zero in un secondo momento su un altro valore, è possibile fornire il giorno dell'anno relativo a un altro fuso orario. Ad esempio, per recuperare dall'Europa una risorsa situata in America.
Math.floor((Date.now() - Date.parse(new Date().getFullYear(), 0, 0)) / 86400000)
questa è la mia soluzione
Ne ho creato uno leggibile e farà il trucco molto rapidamente, oltre a gestire oggetti JS Date con fusi orari diversi.
Ho incluso alcuni casi di test per fusi orari, ora legale, secondi intercalari e anni bisestili.
PS ECMA-262 ignora i secondi intercalari, a differenza di UTC. Se dovessi convertirlo in una lingua che utilizza UTC reale, potresti semplicemente aggiungere 1 a oneDay.
// returns 1 - 366
findDayOfYear = function (date) {
var oneDay = 1000 * 60 * 60 * 24; // A day in milliseconds
var og = { // Saving original data
ts: date.getTime(),
dom: date.getDate(), // We don't need to save hours/minutes because DST is never at 12am.
month: date.getMonth()
}
date.setDate(1); // Sets Date of the Month to the 1st.
date.setMonth(0); // Months are zero based in JS's Date object
var start_ts = date.getTime(); // New Year's Midnight JS Timestamp
var diff = og.ts - start_ts;
date.setDate(og.dom); // Revert back to original date object
date.setMonth(og.month); // This method does preserve timezone
return Math.round(diff / oneDay) + 1; // Deals with DST globally. Ceil fails in Australia. Floor Fails in US.
}
// Tests
var pre_start_dst = new Date(2016, 2, 12);
var on_start_dst = new Date(2016, 2, 13);
var post_start_dst = new Date(2016, 2, 14);
var pre_end_dst_date = new Date(2016, 10, 5);
var on_end_dst_date = new Date(2016, 10, 6);
var post_end_dst_date = new Date(2016, 10, 7);
var pre_leap_second = new Date(2015, 5, 29);
var on_leap_second = new Date(2015, 5, 30);
var post_leap_second = new Date(2015, 6, 1);
// 2012 was a leap year with a leap second in june 30th
var leap_second_december31_premidnight = new Date(2012, 11, 31, 23, 59, 59, 999);
var january1 = new Date(2016, 0, 1);
var january31 = new Date(2016, 0, 31);
var december31 = new Date(2015, 11, 31);
var leap_december31 = new Date(2016, 11, 31);
alert( ""
+ "\nPre Start DST: " + findDayOfYear(pre_start_dst) + " === 72"
+ "\nOn Start DST: " + findDayOfYear(on_start_dst) + " === 73"
+ "\nPost Start DST: " + findDayOfYear(post_start_dst) + " === 74"
+ "\nPre Leap Second: " + findDayOfYear(pre_leap_second) + " === 180"
+ "\nOn Leap Second: " + findDayOfYear(on_leap_second) + " === 181"
+ "\nPost Leap Second: " + findDayOfYear(post_leap_second) + " === 182"
+ "\nPre End DST: " + findDayOfYear(pre_end_dst_date) + " === 310"
+ "\nOn End DST: " + findDayOfYear(on_end_dst_date) + " === 311"
+ "\nPost End DST: " + findDayOfYear(post_end_dst_date) + " === 312"
+ "\nJanuary 1st: " + findDayOfYear(january1) + " === 1"
+ "\nJanuary 31st: " + findDayOfYear(january31) + " === 31"
+ "\nNormal December 31st: " + findDayOfYear(december31) + " === 365"
+ "\nLeap December 31st: " + findDayOfYear(leap_december31) + " === 366"
+ "\nLast Second of Double Leap: " + findDayOfYear(leap_second_december31_premidnight) + " === 366"
);
Vorrei fornire una soluzione che esegue calcoli aggiungendo i giorni per ogni mese precedente:
function getDayOfYear(date) {
var month = date.getMonth();
var year = date.getFullYear();
var days = date.getDate();
for (var i = 0; i < month; i++) {
days += new Date(year, i+1, 0).getDate();
}
return days;
}
var input = new Date(2017, 7, 5);
console.log(input);
console.log(getDayOfYear(input));
In questo modo non devi gestire i dettagli degli anni bisestili e dell'ora legale.
Un'alternativa che utilizza i timestamp UTC. Inoltre, come altri hanno notato, il giorno che indica il primo mese è 1 anziché 0. Tuttavia, il mese inizia da 0.
var now = Date.now();
var year = new Date().getUTCFullYear();
var year_start = Date.UTC(year, 0, 1);
var day_length_in_ms = 1000*60*60*24;
var day_number = Math.floor((now - year_start)/day_length_in_ms)
console.log("Day of year " + day_number);
È possibile passare il parametro come numero di data nella setDatefunzione:
var targetDate = new Date();
targetDate.setDate(1);
// Now we can see the expected date as: Mon Jan 01 2018 01:43:24
console.log(targetDate);
targetDate.setDate(365);
// You can see: Mon Dec 31 2018 01:44:47
console.log(targetDate)
Questo potrebbe essere utile a coloro che hanno bisogno del giorno dell'anno come stringa e hanno a disposizione l'interfaccia utente jQuery.
Puoi usare jQuery UI Datepicker:
day_of_year_string = $.datepicker.formatDate("o", new Date())
Sotto funziona allo stesso modo di alcune delle risposte già menzionate ( (date_ms - first_date_of_year_ms) / ms_per_day):
function getDayOfTheYearFromDate(d) {
return Math.round((new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime()
- new Date(d.getFullYear(), 0, 0).getTime()) / 86400000);
}
day_of_year_int = getDayOfTheYearFromDate(new Date())
Per quelli tra noi che desiderano una rapida soluzione alternativa.
(function(){"use strict";
function daysIntoTheYear(dateInput){
var fullYear = dateInput.getFullYear()|0;
// "Leap Years are any year that can be exactly divided by 4 (2012, 2016, etc)
// except if it can be exactly divided by 100, then it isn't (2100, 2200, etc)
// except if it can be exactly divided by 400, then it is (2000, 2400)"
// (https://www.mathsisfun.com/leap-years.html).
var isLeapYear = ((fullYear & 3) | (fullYear/100 & 3)) === 0 ? 1 : 0;
// (fullYear & 3) = (fullYear % 4), but faster
//Alternative:var isLeapYear=(new Date(currentYear,1,29,12)).getDate()===29?1:0
var fullMonth = dateInput.getMonth()|0;
return ((
// Calculate the day of the year in the Gregorian calendar
// The code below works based upon the facts of signed right shifts
// • (x) >> n: shifts n and fills in the n highest bits with 0s
// • (-x) >> n: shifts n and fills in the n highest bits with 1s
// (This assumes that x is a positive integer)
(31 & ((-fullMonth) >> 4)) + // January // (-11)>>4 = -1
((28 + isLeapYear) & ((1-fullMonth) >> 4)) + // February
(31 & ((2-fullMonth) >> 4)) + // March
(30 & ((3-fullMonth) >> 4)) + // April
(31 & ((4-fullMonth) >> 4)) + // May
(30 & ((5-fullMonth) >> 4)) + // June
(31 & ((6-fullMonth) >> 4)) + // July
(31 & ((7-fullMonth) >> 4)) + // August
(30 & ((8-fullMonth) >> 4)) + // September
(31 & ((9-fullMonth) >> 4)) + // October
(30 & ((10-fullMonth) >> 4)) + // November
// There are no months past December: the year rolls into the next.
// Thus, fullMonth is 0-based, so it will never be 12 in Javascript
(dateInput.getDate()|0) // get day of the month
)&0xffff);
}
// Demonstration:
var date = new Date(2100, 0, 1)
for (var i=0; i<12; i=i+1|0, date.setMonth(date.getMonth()+1|0))
console.log(date.getMonth()+":\tday "+daysIntoTheYear(date)+"\t"+date);
date = new Date(1900, 0, 1);
for (var i=0; i<12; i=i+1|0, date.setMonth(date.getMonth()+1|0))
console.log(date.getMonth()+":\tday "+daysIntoTheYear(date)+"\t"+date);
// Performance Benchmark:
console.time("Speed of processing 65536 dates");
for (var i=0,month=date.getMonth()|0; i<65536; i=i+1|0)
date.setMonth(month=month+1+(daysIntoTheYear(date)|0)|0);
console.timeEnd("Speed of processing 65536 dates");
})();
La dimensione dei mesi dell'anno e il modo in cui funzionano gli anni bisestili si adattano perfettamente a mantenere il nostro tempo in linea con il sole. Diamine, funziona così perfettamente che tutto ciò che facciamo è regolare solo pochi secondi qua e là . Il nostro attuale sistema di anni bisestili è in vigore dal 24 febbraio 1582 e probabilmente rimarrà in vigore nel prossimo futuro.
L'ora legale, tuttavia, è molto soggetta a modifiche. Può darsi che tra 20 anni qualche paese possa compensare l'ora di un'intera giornata o di qualche altro estremo per l'ora legale. Un intero giorno di DST quasi certamente non accadrà mai, ma il DST è comunque molto attivo e indeciso. Pertanto, la soluzione di cui sopra è a prova di futuro oltre ad essere molto molto veloce.
Lo snippet di codice sopra viene eseguito molto velocemente. Il mio computer può elaborare 65536 date in ~ 52 ms su Chrome.
const dayOfYear = date => {
const myDate = new Date(date);
const year = myDate.getFullYear();
const firstJan = new Date(year, 0, 1);
const differenceInMillieSeconds = myDate - firstJan;
return (differenceInMillieSeconds / (1000 * 60 * 60 * 24) + 1);
};
const result = dayOfYear("2019-2-01");
console.log(result);
Questa è una soluzione che evita i fastidiosi problemi relativi all'oggetto Data e al fuso orario, richiede che la data di input sia nel formato "aaaa-gg-mm". Se vuoi cambiare il formato, modifica la funzione date_str_to_parts:
function get_day_of_year(str_date){
var date_parts = date_str_to_parts(str_date);
var is_leap = (date_parts.year%4)==0;
var acct_for_leap = (is_leap && date_parts.month>2);
var day_of_year = 0;
var ary_months = [
0,
31, //jan
28, //feb(non leap)
31, //march
30, //april
31, //may
30, //june
31, //july
31, //aug
30, //sep
31, //oct
30, //nov
31 //dec
];
for(var i=1; i < date_parts.month; i++){
day_of_year += ary_months[i];
}
day_of_year += date_parts.date;
if( acct_for_leap ) day_of_year+=1;
return day_of_year;
}
function date_str_to_parts(str_date){
return {
"year":parseInt(str_date.substr(0,4),10),
"month":parseInt(str_date.substr(5,2),10),
"date":parseInt(str_date.substr(8,2),10)
}
}
Mi preoccupo sempre quando mischio la matematica con le funzioni di data (è così facile perdere qualche anno bisestile altri dettagli). Di 'che hai:
var d = new Date();
Suggerirei di utilizzare quanto segue, i giorni verranno salvati in day:
for(var day = d.getDate(); d.getMonth(); day += d.getDate())
d.setDate(0);
Non riesco a vedere alcun motivo per cui questo non funzionerebbe bene (e non sarei così preoccupato per le poche iterazioni poiché questo non sarà usato così intensamente).
/ * USA QUESTO SCRIPT * /
var today = new Date();
var first = new Date(today.getFullYear(), 0, 1);
var theDay = Math.round(((today - first) / 1000 / 60 / 60 / 24) + .5, 0);
alert("Today is the " + theDay + (theDay == 1 ? "st" : (theDay == 2 ? "nd" : (theDay == 3 ? "rd" : "th"))) + " day of the year");
var days = new Date().getFullYear() % 4 == 0 ? 366 : 365;