Comment utiliser javascript pour calculer le jour de l'année, de 1 à 366? Par exemple:
- Le 3 janvier devrait être le 3 .
- Le 1er février devrait avoir 32 ans .
Comment utiliser javascript pour calculer le jour de l'année, de 1 à 366? Par exemple:
Réponses:
Suite à la modification de 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);
Edit: Le code ci - dessus échouera quand nowest une date entre le 26 mars et le 29 octobre et nowl'heure de est avant 1h du matin (par exemple 00:59:59). Cela est dû au fait que le code ne prend pas en compte l'heure d'été. Vous devez compenser cela:
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.floorm'a toujours donné un résultat de 1 jour de moins que prévu après un certain jour en avril. Math.ceila fonctionné comme prévu, mais j'ai vu qu'il soit conseillé d'utiliser à la Math.roundplace de l'un ou l'autre.
new Date(2014, 0, 1), et non new Date(2014, 0, 0)comme vous l'avez ici. Est-ce intentionnel? C'est peut-être ce qui explique le fait d'être parti d'un jour comme new Date(2014, 0, 0)cela reviendra 12/31/2013.
.setUTCHourset Date.UTC()pour une solution plus fiable.
ceilplutôt que floor, cela vous donnera un système de numérotation où le 1er janvier = 1. Si vous voulez que le 1er janvier = 0 (comme floorvous le donnez), soustrayez simplement 1 de votre résultat final.
var diff = now - start + (start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000;
Cela fonctionne avec les changements d'heure d'été dans tous les pays (le "midi" ci-dessus ne fonctionne pas en Australie):
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()doit être changé en getDate(). Le premier renvoie le jour de la semaine (0 = dimanche..6 = samedi), pas le jour.
Je trouve très intéressant que personne n'ait envisagé d'utiliser UTC car il n'est pas soumis à l'heure d'été. Par conséquent, je propose ce qui suit:
function daysIntoYear(date){
return (Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()) - Date.UTC(date.getFullYear(), 0, 0)) / 24 / 60 / 60 / 1000;
}
Vous pouvez le tester avec les éléments suivants:
[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`));
Quelles sorties pour l'année bissextile 2016 (vérifiées via 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), qui est toujours inférieure à Number.MAX_SAFE_INTEGER. voir cette réponse: 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())
Heureusement , cette question ne précise pas si le numéro du courant jour est nécessaire, laissant place à cette réponse.
De plus, certaines réponses (également sur d'autres questions) avaient des problèmes d'année bissextile ou utilisaient l'objet Date. Bien que le javascript Date objectcouvre environ 285616 ans (100 000 000 jours) de chaque côté du 1er janvier 1970, j'en avais marre de toutes sortes d' incohérences de date inattendues entre différents navigateurs (notamment les années 0 à 99). J'étais également curieux de savoir comment le calculer.
J'ai donc écrit un algorithme simple et surtout petit pour calculer le jour correct de l'année ( Proleptic Gregorian / Astronomical / ISO 8601: 2004 (clause 4.3.2.1), donc l' année0 existe et est une année bissextile et les années négatives sont prises en charge ). basé sur l' année , le mois et le jour .
Notez qu'en AD/BCnotation, l'année 0 AD / BC n'existe pas: à la place, l'année 1 BCest l'année bissextile! SI vous devez tenir compte de la notation BC, soustrayez simplement une année de la valeur de l'année (sinon positive) en premier !!
J'ai modifié (pour javascript) l' algorithme de court-circuit bitmask-modulo leapYear et est venu avec un nombre magique pour faire une recherche par bit des décalages (qui exclut jan et feb, nécessitant donc 10 * 3 bits (30 bits est moins que 31 bits, nous pouvons donc enregistrer en toute sécurité un autre caractère sur le décalage de bits au lieu de>>> )).
Notez qu'aucun mois ou jour ne peut l'être 0. Cela signifie que si vous avez besoin de cette équation juste pour le courant jour (alimentation à l'aide .getMonth()) il vous suffit de retirer la --de--m .
Notez que cela suppose une date valide (bien que la vérification des erreurs ne soit que quelques caractères de plus).
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>
Voici la version avec la validation de plage correcte .
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>
Encore une fois, une ligne, mais je l'ai divisée en 3 lignes pour la lisibilité (et l'explication suivante).
La dernière ligne est identique à la fonction ci-dessus, mais l'algorithme (identique) de leapYear est déplacé vers une section de court-circuit précédente (avant le calcul du nombre de jours), car il est également nécessaire de savoir combien de jours un mois a dans un donnée (bissextile) année.
La ligne médiane calcule le numéro de décalage correct (pour un nombre maximum de jours) pour un mois donné dans une année (bissextile) donnée en utilisant un autre nombre magique: puisque 31-28=3et 3est juste 2 bits, puis 12*2=24bits, nous pouvons stocker les 12 mois. Puisque l'addition peut être plus rapide que la soustraction, nous ajoutons le décalage (au lieu de le soustraire 31). Pour éviter une branche de décision d'année bissextile pour février, nous modifions ce numéro de recherche magique à la volée.
Cela nous laisse avec la première ligne (assez évidente): elle vérifie que le mois et la date sont dans des limites valides et nous assure une falsevaleur de retour en cas d'erreur de plage (notez que cette fonction ne devrait pas non plus pouvoir renvoyer 0, car 1 jan 0000 est encore jour 1.), fournissant facile vérification d'erreur: if(r=dayNo(/*y, m, d*/)){}.
S'il est utilisé de cette façon (où le mois et le jour peuvent ne pas être 0), alors on peut changer --m>=0 && m<12en m>0 && --m<12(enregistrer un autre caractère).
La raison pour laquelle j'ai tapé l'extrait dans sa forme actuelle est que pour les valeurs de mois basées sur 0, il suffit de supprimer le --de --m.
Extra:
Remarque, n'utilisez pas l'algorithme de ce jour par mois si vous n'avez besoin que d'un maximum de jours par mois. Dans ce cas, il existe un algorithme plus efficace (car nous n'avons besoin de leepYear que lorsque le mois est février) J'ai posté comme réponse à cette question: Quelle est la meilleure façon de déterminer le nombre de jours dans un mois avec 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; };
+1partir this.getMonth()+1si vous retirez le --de --m. EDIT Donc, je ferais (pour une bibliothèque):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 - 2016années, js sera probablement un peu dépassé.
:)Mais d'ici là, cela donnera au moins des résultats prévisibles et cohérents haha. EDIT , juste pour la théorie, en utilisant l'algo tout-modulo conventionnel plus lent pour leapyear, la plage peut être étendue à 2 ^ 53. L'algo de recherche mensuelle n'est pas le facteur limitant.
Si vous ne voulez pas réinventer la roue, vous pouvez utiliser l'excellente bibliothèque date-fns (node.js):
var getDayOfYear = require('date-fns/get_day_of_year')
var dayOfYear = getDayOfYear(new Date(2017, 1, 1)) // 1st february => 32
Eh bien, si je vous comprends bien, vous voulez 366 sur une année bissextile, 365 sinon, non? Une année est une année bissextile si elle est divisible par 4 mais pas par 100, sauf si elle est également divisible par 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;
}
}
Dans ce cas, je ne pense pas qu'il existe une méthode intégrée; vous devrez faire ceci:
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();
}
(Oui, je l'ai fait sans copier ni coller. S'il y a un moyen facile, je serai fou)
:)
C'est un moyen simple de trouver le jour actuel de l'année, et il devrait tenir compte des années bissextiles sans problème:
Javascript:
Math.round((new Date().setHours(23) - new Date(new Date().getYear()+1900, 0, 1, 0, 0, 0))/1000/60/60/24);
Javascript dans Google Apps Script:
Math.round((new Date().setHours(23) - new Date(new Date().getYear(), 0, 1, 0, 0, 0))/1000/60/60/24);
L'action principale de ce code est de trouver le nombre de millisecondes qui se sont écoulées dans l'année en cours, puis de convertir ce nombre en jours. Le nombre de millisecondes qui se sont écoulées dans l'année en cours peut être trouvé en soustrayant le nombre de millisecondes de la première seconde du premier jour de l'année en cours, obtenu avec new Date(new Date().getYear()+1900, 0, 1, 0, 0, 0)(Javascript) ou new Date(new Date().getYear(), 0, 1, 0, 0, 0)(Google Apps Script), des millisecondes de la 23e heure de la journée en cours, qui a été trouvée avec new Date().setHours(23). Le réglage de la date actuelle à la 23e heure a pour but de garantir que le jour de l'année est correctement arrondi de Math.round().
Une fois que vous avez le nombre de millisecondes de l'année en cours, vous pouvez convertir cette heure en jours en divisant par 1000 pour convertir les millisecondes en secondes, puis en divisant par 60 pour convertir les secondes en minutes, puis en divisant par 60 pour convertir les minutes en heures, et enfin en divisant par 24 pour convertir les heures en jours.
Remarque: Ce message a été modifié pour tenir compte des différences entre JavaScript et JavaScript mis en œuvre dans Google Apps Script. En outre, plus de contexte a été ajouté pour la réponse.
.setHoursméthode sur le premier objet date et spécifié l'heure du jour avec le deuxième objet date, un changement de 1 heure par rapport à l'heure d'été n'affectera pas les heures des objets Date utilisés dans ce calcul.
Je pense que c'est plus simple:
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!
Cette méthode prend en compte le problème du fuseau horaire et l'heure d'été
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;
}
(pris d' ici )
Voir aussi ce violon
Math.round ((new Date (). SetHours (23) - new Date (new Date (). GetFullYear (), 0, 1, 0, 0, 0)) / 1000/86400);
optimise davantage la réponse.
De plus, en remplaçant ultérieurement setHours (23) ou le dernier mais deux zéro par une autre valeur, le jour de l'année peut être associé à un autre fuseau horaire. Par exemple, pour récupérer depuis l'Europe une ressource située en Amérique.
Math.floor((Date.now() - Date.parse(new Date().getFullYear(), 0, 0)) / 86400000)
c'est ma solution
J'en ai créé un qui est lisible et qui fera l'affaire très rapidement, ainsi que des objets JS Date avec des fuseaux horaires disparates.
J'ai inclus pas mal de cas de test pour les fuseaux horaires, l'heure d'été, les secondes bissextiles et les années bissextiles.
PS ECMA-262 ignore les secondes intercalaires, contrairement à UTC. Si vous deviez le convertir dans une langue qui utilise le vrai UTC, vous pouvez simplement ajouter 1 à 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"
);
Je souhaite proposer une solution qui effectue des calculs en ajoutant les jours de chaque mois précédent:
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));
De cette façon, vous n'avez pas à gérer les détails des années bissextiles et de l'heure d'été.
Une alternative utilisant les horodatages UTC. De plus, comme d'autres l'ont noté, le jour indiquant le 1er du mois est 1 plutôt que 0. Le mois commence à 0 cependant.
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);
Vous pouvez passer le paramètre comme numéro de date dans la setDatefonction:
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)
Cela peut être utile à ceux qui ont besoin du jour de l'année sous forme de chaîne et qui disposent de l'interface utilisateur jQuery.
Vous pouvez utiliser jQuery UI Datepicker:
day_of_year_string = $.datepicker.formatDate("o", new Date())
En dessous, cela fonctionne de la même manière que certaines des réponses déjà mentionnées ( (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())
Pour ceux d'entre nous qui veulent une solution alternative rapide.
(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 taille des mois de l'année et la façon dont fonctionnent les années bissextiles s'intègrent parfaitement pour garder notre temps sur la bonne voie avec le soleil. Heck, cela fonctionne si parfaitement que tout ce que nous faisons est d' ajuster quelques secondes ici et là . Notre système actuel des années bissextiles est en vigueur depuis le 24 février 1582 et le restera probablement dans un avenir prévisible.
L'heure d'été, cependant, est très sujette à changement. Il se peut que dans 20 ans, certains pays décalent le temps d'une journée entière ou d'un autre extrême pour l'heure d'été. Une journée entière DST ne se produira presque certainement jamais, mais DST reste néanmoins très active et indécise. Ainsi, la solution ci-dessus est à l'épreuve du temps en plus d'être très très rapide.
L'extrait de code ci-dessus s'exécute très rapidement. Mon ordinateur peut traiter 65536 dates en ~ 52 ms sur 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);
C'est une solution qui évite les problèmes gênants d'objet Date et de fuseau horaire, elle nécessite que votre date d'entrée soit au format "aaaa-jj-mm". Si vous souhaitez changer le format, modifiez la fonction 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)
}
}
Cela m'inquiète toujours lorsque je mélange les mathématiques avec les fonctions de date (il est si facile de manquer un autre détail d'une année bissextile). Dites que vous avez:
var d = new Date();
Je suggérerais d'utiliser ce qui suit, les jours seront économisés dans day:
for(var day = d.getDate(); d.getMonth(); day += d.getDate())
d.setDate(0);
Je ne vois aucune raison pour laquelle cela ne fonctionnerait pas très bien (et je ne serais pas si inquiet des quelques itérations car cela ne sera pas utilisé de manière aussi intensive).
/ * UTILISEZ CE 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;