javascript pour trouver l'année bissextile
Comment puis-je obtenir le code ci-dessous à travailler quand j'ai un mois de février? À l'heure actuelle, il s'arrête au jour le jour avant de se rendre au fi pour déterminer s'il s'agit d'une année bissextile.
if (month == 2) {
if (day == 29) {
if (year % 4 != 0 || year % 100 == 0 && year % 400 != 0) {
field.focus();
field.value = month +'/' + '';
}
}
else if (day > 28) {
field.focus();
field.value = month +'/' + '';
}
}
7 réponses
Il est plus sûr d'utiliser des Date d'objets pour datetime trucs, par exemple
isLeap = new Date(year, 1, 29).getMonth() == 1
puisque les gens ne cessent de demander comment exactement cela fonctionne, il a à voir avec la façon dont JS calcule la valeur de date de l'Année-Mois-Jour (détails ici ). Fondamentalement, il calcule d'abord le premier du mois, puis ajoute N -1 jours. Donc quand nous demandons le 29 février sur une année non bissextile, le résultat sera le 1er février + 28 jours = 1er Mars:
> new Date(2015, 1, 29)
< Sun Mar 01 2015 00:00:00 GMT+0100 (CET)
sur une année bissextile, le 1er + 28 = 29 février:
> new Date(2016, 1, 29)
< Mon Feb 29 2016 00:00:00 GMT+0100 (CET)
dans le code ci-dessus, j'ai fixé la date au 29 février et regarde si un retournement a eu lieu. Si ce n'est pas le cas (le mois est toujours 1, c.-à-d. février), il s'agit d'une année bissextile, sinon une année non bissextile.
comparé à l'utilisation de new Date()
c'est est environ 100 fois plus rapide!
mise à jour:
cette dernière version utilise un test de bits des 3 bits inférieurs (est-ce un multiple de 4), ainsi qu'un contrôle de l'année étant un multiple de 16 (4 bits inférieurs en binaire est de 15) et étant un multiple de 25.
ily = function(y) {return !(y & 3 || !(y % 25) && y & 15);};
Il est un peu plus rapide encore que ma précédente version (ci-dessous):
ily = function(yr) {return !((yr % 4) || (!(yr % 100) && (yr % 400)));};
il est également 5% plus rapide, par rapport à la version opérateur conditionnel déjà rapide par broc.seib
résultats de L'essai de vitesse: http://jsperf.com/ily/6
résultats attendus des essais logiques:
alert(ily(1900)); // false
alert(ily(2000)); // true
alert(ily(2001)); // false
alert(ily(2002)); // false
alert(ily(2003)); // false
alert(ily(2004)); // true
alert(ily(2100)); // false
alert(ily(2400)); // true
Correct et rapide:
ily = function(yr) { return (yr%400)?((yr%100)?((yr%4)?false:true):false):true; }
si vous êtes dans une boucle ou si vous comptez les nanosecondes, c'est deux grandeurs plus rapides que de passer votre année à travers un nouvel objet Date (). Comparez la performance ici: http://jsperf.com/ily
isLeap = !(new Date(year, 1, 29).getMonth()-1)
...la soustraction par un devrait fonctionner encore plus rapidement que la comparaison sur la plupart des architectures CPU.
Mieux historiques calcul des années bissextiles.
le code ci-dessous tient compte du fait que les années bissextiles ont été introduites en 45 av. j.-c. avec le calendrier julien, et que la majorité du monde occidental a adopté le calendrier Grégorien en 1582 av. J.-C., et que 0C = 1 av. j.-c.
isLeap = function(yr) {
if (yr > 1582) return !((yr % 4) || (!(yr % 100) && (yr % 400)));
if (yr >= 0) return !(yr % 4);
if (yr >= -45) return !((yr + 1) % 4);
return false;
};
la Grande-Bretagne et ses colonies ont adopté le calendrier Grégorien en 1752, donc si vous êtes plus centrique cette version est meilleure (nous supposerons que la Grande-Bretagne a adopté le calendrier julien calendrier avec la conquête romaine à partir de 43CE).
isLeap = function(yr) {
if (yr > 1752) return !((yr % 4) || (!(yr % 100) && (yr % 400)));
if (yr >= 43) return !(yr % 4);
return false;
};
j'utilise ceci parce que je déteste devoir continuer à faire référence à janvier comme 0 et février comme 1. Pour moi et PHP et dates lisibles, février=2. Je sais que ça n'a pas vraiment d'importance car le nombre ne change jamais mais ça garde juste mon cerveau pensant la même chose à travers un code différent.
var year = 2012;
var isLeap = new Date(year,2,1,-1).getDate()==29;
vous pouvez facilement faire cela pour travailler en appelant .isLeapYear()
de momentjs
:
var notLeapYear = moment('2018-02-29')
console.log(notLeapYear.isLeapYear()); // false
var leapYear = moment('2020-02-29')
console.log(leapYear.isLeapYear()); // true
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.21.0/moment.min.js"></script>