fecha - javascript para encontrar el año bisiesto
saber si un año es bisiesto en javascript (7)
Es más seguro usar objetos Date para cosas de fecha y hora, por ejemplo,
isLeap = new Date(year, 1, 29).getMonth() == 1
Dado que las personas siguen preguntando cómo funciona exactamente esto, tiene que ver con cómo JS calcula el valor de la fecha de año-año-día (detalles here ). Básicamente, primero calcula el primer día del mes y luego le agrega N -1 días. Entonces, cuando solicitemos el 29 de febrero en un año sin salto, 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 de febrero + 28 = 29 de febrero:
> new Date(2016, 1, 29)
< Mon Feb 29 2016 00:00:00 GMT+0100 (CET)
En el código anterior, establezco la fecha a 29 de febrero y veo si se produjo una renovación. Si no es así (el mes sigue siendo 1, es decir, febrero), este es un año bisiesto, de lo contrario, no será un salto.
¿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 if 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 +''/'' + '''';
}
}
else if (day > 28) {
field.focus();
field.value = month +''/'' + '''';
}
}
Mejor cálculo histórico de años bisiestos.
El siguiente código toma en cuenta que los años bisiestos se introdujeron en 45BC con el calendario juliano, y que la mayoría del mundo occidental adoptó el calendario gregoriano en 1582 aC, y que 0CE = 1BC.
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 tanto, si usted es más anglosajón, esta versión es mejor (asumiremos que Gran Bretaña adoptó el calendario juliano con conquista romana a partir del 43 a. C.).
isLeap = function(yr) {
if (yr > 1752) return !((yr % 4) || (!(yr % 100) && (yr % 400)));
if (yr >= 43) return !(yr % 4);
return false;
};
Puede hacer que esto funcione .isLeapYear()
llamando a .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>
Uso esto porque odio tener que seguir refiriéndome a enero como 0 y febrero como 1. A mí, a PHP y a las fechas legibles, febrero = 2. Sé que realmente no importa ya que el número nunca cambia, pero solo mantiene mi cerebro pensando lo mismo en diferentes códigos.
var year = 2012;
var isLeap = new Date(year,2,1,-1).getDate()==29;
Correcto y rápido:
ily = function(yr) { return (yr%400)?((yr%100)?((yr%4)?false:true):false):true; }
Si estás en un bucle o contando los nanosegundos, esto es dos magnitudes más rápido que ejecutar tu año a través de un nuevo objeto Date (). Compara el rendimiento aquí: http://jsperf.com/ily
En comparación con el uso de la new Date()
esto es 100 veces más rápido!
Actualizar:
Esta última versión utiliza una prueba de bits de los 3 bits inferiores (si es un múltiplo de 4), así como una verificación de que el año es un múltiplo de 16 (los 4 bits inferiores en binario es 15) y un múltiplo de 25.
ily = function(y) {return !(y & 3 || !(y % 25) && y & 15);};
Es ligeramente más rápido otra vez que mi versión anterior (abajo):
ily = function(yr) {return !((yr % 4) || (!(yr % 100) && (yr % 400)));};
También es un 5% más rápido, en comparación con la versión ya rápida 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 sustracción por una debería funcionar incluso más rápido que la comparación en la mayoría de las arquitecturas de CPU.