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 +'/' +  '';
    }
}
19
demandé sur Juan Almonte 2011-11-18 02:50:28

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.

101
répondu georg 2015-02-02 20:31:17

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);};

http://jsperf.com/ily/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)));};

http://jsperf.com/ily/7

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
10
répondu Gone Coding 2015-05-20 13:08:14

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

6
répondu broc.seib 2013-06-14 20:12:08
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.

5
répondu bofs 2013-04-01 16:41:03

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;
};
2
répondu spirographer 2015-10-02 02:51:20

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;
1
répondu Adam 2013-08-09 14:53:33

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>
1
répondu guijob 2018-03-06 05:19:33