javascript para encontrar el año bisiesto

6 minutos de lectura

¿Cómo puedo hacer que el siguiente código funcione cuando tengo un mes de febrero? Actualmente está llegando al día y luego se detiene antes de llegar al si para determinar si es un año bisiesto.

 if (month == 2) {
    if (day == 29) {
        if (year % 4 != 0 || year % 100 == 0 && year % 400 != 0) {
            field.focus();
             field.value = month +"https://stackoverflow.com/" +  '';
        }
    }
    else if (day > 28) {
        field.focus();
             field.value = month +"https://stackoverflow.com/" +  '';
    }
}

  • “Parar” ¿cómo? ¿Hay un error?

    – Peka

    17 nov.

  • nunca evalúa el año para ver si es un año bisiesto va directamente al campo.enfoque y campo.valor si es un año bisiesto o no

    –Juan Almonte

    17 nov.

  • Sus condiciones se ven un poco extrañas: tal como están escritas ahora, solo verifica day para valores de 29 o mayores (basado en el day == 29 y day > 28 si cláusulas). Supongo que querías escribir day <= 28, pero si ese es el caso, podrías descartar el segundo else if cláusula y usar una else cláusula directamente. También podría ser más seguro agregar un conjunto adicional de paréntesis a la cláusula del año bisiesto: if (year % 4 != 0 || (year % 100 == 0 && year % 400 != 0))

    – JW8

    17 nov.


  • Es posible que deba mostrar parte del código circundante sobre cómo se configuran esas variables. Si está utilizando un objeto Fecha, recuerde que utiliza meses basados ​​en cero.

    – nnnnnn

    18 nov.

javascript para encontrar el año bisiesto
jorge

Es más seguro de usar Objetos de fecha para cosas de fecha y hora, por ejemplo

isLeap = new Date(year, 1, 29).getMonth() == 1

Dado que la gente sigue preguntando cómo funciona exactamente esto, tiene que ver con cómo JS calcula el valor de la fecha del año-mes-día (detalles aquí). Básicamente, primero calcula el primero del mes y luego le agrega N -1 días. Entonces, cuando preguntamos por el 29 de febrero en un año no bisiesto, el resultado será el 1 de febrero + 28 días = 1 de marzo:

> new Date(2015, 1, 29)
< Sun Mar 01 2015 00:00:00 GMT+0100 (CET)

En un año bisiesto, el 1 + 28 = 29 de febrero:

> new Date(2016, 1, 29)
< Mon Feb 29 2016 00:00:00 GMT+0100 (CET)

En el código anterior, configuré la fecha para el 29 de febrero y observé si se produjo un traspaso. Si no (el mes sigue siendo 1, es decir, febrero), es un año bisiesto, de lo contrario, no es bisiesto.

  • Santa vaca. ¡Qué truco! :)

    – Sime Vidas

    17 nov.

  • Úselo solo para escenarios de bajo volumen, ya que esto es alrededor de 100 veces más lento que usar algo como isLeap = !((yr % 4) || (!(yr % 100) && (yr % 400))); jsperf.com/ily/7

    – Codificación pasada

    24 oct.


  • lo que hace el == 1 hacer aquí?

    –Ryman Holmes

    24 abr.

  • @RymanHolmes Meses en JavaScript Date objeto tienen índice cero. En un año bisiesto, el día 29 del primer mes (febrero) es válido, por lo que getMonth() devoluciones 1 (Febrero). En un año no bisiesto, JavaScript “corrige” el 29 de febrero al 1 de marzo, por lo que getMonth() regresará 2 (Marcha).

    – Salvajemente inexacto

    26 mayo 2014 en 17:21

  • Esto no funciona en IE11 ya que al pasar el 29 de febrero se corrige al 28 de febrero en el resultado Date() objeto. Por lo tanto, devuelve 1 y marca incorrectamente como año bisiesto.

    – AdamJB

    19 dic. 19 en 11:59

javascript para encontrar el año bisiesto
Codificación pasada

Comparado con el uso new Date() ¡Esto es alrededor de 100 veces más rápido!

Actualizar:

Esta última versión utiliza una prueba de bits de los 3 bits inferiores (es un múltiplo de 4), así como una comprobación de que el año es un múltiplo de 16 (los 4 bits inferiores en binario son 15) y un múltiplo de 25.

ily = function(y) {return !(y & 3 || !(y % 25) && y & 15);};

http://jsperf.com/ily/15

Es un poco más rápido de nuevo que mi versión anterior (abajo):

ily = function(yr) {return !((yr % 4) || (!(yr % 100) && (yr % 400)));};

http://jsperf.com/ily/7

También es un 5% más rápido, en comparación con la ya rápida versión de operador condicional de broc.seib.

Resultados de la prueba de velocidad: http://jsperf.com/ily/6

Resultados esperados de la prueba lógica:

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

isLeap = !(new Date(year, 1, 29).getMonth()-1)

… la resta por uno debería funcionar incluso más rápido que la comparación en la mayoría de las arquitecturas de CPU.

  • Si tuviera que calcular miles de estos por segundo, podría estar de acuerdo, sin embargo, la legibilidad debería triunfar sobre la velocidad cuando la diferencia de velocidad en cuestión es prácticamente insignificante entre ellos.

    – Codificación pasada

    24 oct.

  • Acabo de hacer algunas pruebas de velocidad y new Date es alrededor de 100 veces más lento que usar la lógica booleana (digamos algo como !((yr % 4) || (!(yr % 100) && (yr % 400)))). Se podría decir que ahora he tirado la legibilidad por la ventana con este por el bien de la velocidad, pero 100 veces puede valer la pena 🙂

    – Codificación pasada

    24 oct.


Correcto y rápido:

ily = function(yr) { return (yr%400)?((yr%100)?((yr%4)?false:true):false):true; }

Si está en un ciclo o contando los nanosegundos, esto es dos magnitudes más rápido que ejecutar su año a través de un nuevo objeto Date(). Compare el rendimiento aquí: http://jsperf.com/ily

Mejor cómputo histórico de los años bisiestos.

El siguiente código tiene en cuenta que los años bisiestos se introdujeron en el año 45 a. C. con el calendario juliano, y que la mayoría del mundo occidental adoptó el calendario gregoriano en 1582 d. C., y que 0CE = 1 a.

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

Gran Bretaña y sus colonias adoptaron el calendario gregoriano en 1752, por lo que si eres más anglocéntrico, esta versión es mejor (supondremos que Gran Bretaña adoptó el calendario juliano con la conquista romana a partir del 43 EC).

isLeap = function(yr) {
  if (yr > 1752) return !((yr % 4) || (!(yr % 100) && (yr % 400)));
  if (yr >= 43) return !(yr % 4);
  return false;
};

  • + para las lecciones de historia. Ahora la pregunta: ¿no se introdujeron los años bisiestos con carácter retroactivo?

    – inetphantom

    22 ago. 18 a las 21:28


Lo uso porque odio tener que seguir refiriéndome a enero como 0 y febrero como 1. Para mí y PHP y fechas legibles, febrero = 2. Sé que en realidad no importa, ya que el número nunca cambia, pero hace que mi cerebro siga pensando lo mismo en diferentes códigos.

var year = 2012;
var isLeap = new Date(year,2,1,-1).getDate()==29;

  • + para las lecciones de historia. Ahora la pregunta: ¿no se introdujeron los años bisiestos con carácter retroactivo?

    – inetphantom

    22 ago. 18 a las 21:28


javascript para encontrar el año bisiesto
guijob

Puedes hacer que esto funcione fácilmente llamando .isLeapYear() desde 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>

.

¿Ha sido útil esta solución?