it-swarm.com.ru

javaScript, чтобы найти високосный год

Как я могу получить приведенный ниже код для работы, когда у меня месяц февраль? В настоящее время он приближается к дню, а затем останавливается перед тем, как определить, является ли это високосным годом. 

 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 +'/' +  '';
    }
}
20
Juan Almonte

Безопаснее использовать объекты Date для материала datetime, например.

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

Поскольку люди продолжают спрашивать о том, как именно это работает, это связано с тем, как JS вычисляет значение даты из года-месяца-дня (подробности здесь ). По сути, он сначала вычисляет первое число месяца, а затем добавляет к нему N -1 дней. Поэтому, когда мы просим 29 февраля не в високосный год, результатом будет 1 февраля + 28 дней = 1 марта:

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

В високосный год 1 + 28 = 29 февраля:

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

В приведенном выше коде я установил дату 29 февраля и проверил, произошло ли переворачивание. Если нет (месяц по-прежнему 1, то есть февраль), это високосный год, в противном случае - не високосный.

104
georg

По сравнению с использованием new Date() это примерно в 100 раз быстрее!

Обновление:

Эта последняя версия использует битовый тест младших 3 битов (это кратно 4), а также проверку года, кратного 16 (младшие 4 бита в двоичном виде - 15) и кратного 25. 

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

http://jsperf.com/ily/15

Это немного быстрее, чем моя предыдущая версия (ниже):

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

http://jsperf.com/ily/7

Это также на 5% быстрее по сравнению с уже быстрой версией условного оператора, созданной broc.seib

Результаты теста скорости: http://jsperf.com/ily/6

Ожидаемые результаты логического теста:

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
12
Gone Coding

Правильно и быстро:

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

Если вы находитесь в цикле или считаете наносекунды, это на две величины быстрее, чем проходить год через новый объект Date (). Сравните производительность здесь: http://jsperf.com/ily

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

... вычитание на единицу должно работать даже быстрее, чем сравнение на большинстве архитектур ЦП.

5
bofs

Лучшее историческое вычисление високосных лет.

Приведенный ниже код учитывает, что високосные годы были введены в 45 г. до н.э. по юлианскому календарю, а большинство западного мира приняло григорианский календарь в 1582 г. до н.э., а 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;
};

Великобритания и ее колонии приняли григорианский календарь в 1752 году, поэтому, если вы более англоцентричны, эта версия лучше (предположим, что Великобритания приняла юлианский календарь с римским завоеванием, начиная с 43 г. до н.э.).

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

Вы можете легко заставить это работать, вызывая .isLeapYear() from 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
guijob

Я использую это, потому что я ненавижу называть январь 0 и февраль 1 . Мне и PHP и читаемым датам февраль = 2. Я знаю, что это на самом деле не имеет значения, так как число никогда не меняется, а просто заставляет мой мозг думать одинаково в разных кодах.

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

Псевдокод

if year is not divisible by 4 then not leap year
else if year is not divisible by 100 then leap year
else if year is divisible by 400 then leap year
else not leap year

JavaScript

function isLeapYear (year) {
    return year % 4 == 0 && ( year % 100 != 0 || year % 400 == 0 )
}

Использование приведенного выше кода гарантирует, что вы делаете только одну проверку для year, если year не делится на 4 Просто добавляя скобки, вы сохраняете 2 проверки на year, которые не делятся на 4

0
Daut