Check if year is leap year in javascript [duplicate] - javascript

This question already has answers here:
javascript to find leap year
(15 answers)
Closed 4 years ago.
function leapYear(year){
var result;
year = parseInt(document.getElementById("isYear").value);
if (years/400){
result = true
}
else if(years/100){
result = false
}
else if(years/4){
result= true
}
else{
result= false
}
return result
}
This is what I have so far (the entry is on a from thus stored in "isYear"), I basically followed this here, so using what I already have, how can I check if the entry is a leap year based on these conditions(note I may have done it wrong when implementing the pseudocode, please correct me if I have)
Edit: Note this needs to use an integer not a date function

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

The function checks if February has 29 days. If it does, then we have a leap year.
ES5
function isLeap(year) {
return new Date(year, 1, 29).getDate() === 29;
}
ES6
const isLeap = year => new Date(year, 1, 29).getDate() === 29;
Result
isLeap(1004) // true
isLeap(1001) // false

A faster solution is provided by Kevin P. Rice here:https://stackoverflow.com/a/11595914/5535820
So here's the code:
function leapYear(year)
{
return (year & 3) == 0 && ((year % 25) != 0 || (year & 15) == 0);
}

If you're doing this in an Node.js app, you can use the leap-year package:
npm install --save leap-year
Then from your app, use the following code to verify whether the provided year or date object is a leap year:
var leapYear = require('leap-year');
leapYear(2014);
//=> false
leapYear(2016);
//=> true
Using a library like this has the advantage that you don't have to deal with the dirty details of getting all of the special cases right, since the library takes care of that.

You can use the following code to check if it's a leap year:
ily = function(yr) {
return (yr % 400) ? ((yr % 100) ? ((yr % 4) ? false : true) : false) : true;
}

You can try using JavaScript's Date Object
new Date(year,month).getFullYear()%4==0
This will return true or false.

My Code Is Very Easy To Understand
var year = 2015;
var LeapYear = year % 4;
if (LeapYear==0) {
alert("This is Leap Year");
} else {
alert("This is not leap year");
}

Related

How to determine whether a year is a leap year in JavaScript

I'm trying to determine whether a year is a leap year or not. I'm not sure where i'm missing something because this code is meant to determine that.
Thanks for your help.
let Year = (year) => {
this.year = year;
};
Year.prototype.isLeap = () => {
return (
this.year % 400 === 0 ||
(this.year % 4 === 0 && (this.year % 100 === 0))
);
};
let year = new Year(2014);
year.isLeap();
Thanks I've figured it out.
Initially i did it will the kind of If statement you guys are pointing to here!, so I'm now refactoring to av a cleaner code.
My code was having issue on this line
(this.year % 4 === 0 && (this.year % 100 === 0))
the right syntax is
(this.year % 4 === 0 && !(this.year % 100 === 0))
You could just check the feburary 29th of the given year and see if its changes to march 1st.
const date = new Date(this.year, 1, 29);
return date.getMonth() === 1;
If getMonth() returns 1, then its still feburary which means its leap year.
Number.prototype.isLeap = function() {
return !(this % 4 || !(this % 100) && this % 400);
}
let year = 2000;
console.log(year.isLeap()); // prints true
year = 1900;
console.log(year.isLeap()); // prints false
year = 1904;
console.log(year.isLeap()); // prints true
year = 2003;
console.log(year.isLeap()); // prints false
The following code block will work well on Javascript and also on Typescript if you remove the function keyword. To understand the logic behind this implementation have a look at this link How to determine whether a year is a leap year.
function isLeapYear(year) {
let isLeapObj = {};
if ((year % 4 === 0 && year % 100 != 0) || year % 400 === 0) {
isLeapObj['isLeap'] = true;
isLeapObj['days'] = 366;
} else {
isLeapObj['isLeap'] = false;
isLeapObj['days'] = 365;
}
return isLeapObj;
}
x = isLeapYear(2020);
console.log(x);
For Javscript use the following code
In regards to #brenjt's answer above you might want to change the value 29 to 30
const date = new Date(this.year, 1, 30);
if (date.getMonth() === 1) {
console.log("it's not a leap year");
} else {
console.log("it's a leap year");
}

Hide element on weekends

I have some HTML/javascript elements that I want to only be visible on Mon - Fri
How can I achieve this? I only know how to hide it on specific dates with this code
window.setInterval(function(){
var current = new Date();
var expiry = new Date("October 30, 2014 12:00:00")
if(current.getTime()>expiry.getTime()){
$('#div1').hide();
}
}, 3000);
$('#one').show();
You can get the day of the week, using Date.getDay(). Hide it for day 6 and 0 then.
First, use the JS Date object to get the day of the week
var DayOfTheWeek = new Date().getDay(); //0=Sun, 1=Mon, ..., 6=Sat
then, based on the day, show the element
if(DayOfTheWeek == 6 || DayOfTheWeek == 0){
$('#div1').hide();
} else {
$('#div1').show();
}
The function Date.getDay() will be your friend. It returns a number for a each day of the week. Sunday => 0; Monday => 1; ...
var d = new Date();
var n = d.getDay();
So you can easily check if the day is between 1 and 5. If yes then display your stuff :)
Use getDay function.
if(current.getDay() == 6 || current.getDay() == 0){
$('#div1').hide();
}
Here is a slightly more maintainable version. The element #div1 should be displayed by default and only hidden if the appropriate days are detected.
var days_to_hide = {
0 : "Sunday",
6 : "Saturday"
}
var today = new Date().getDay();
if( typeof days_to_hide[ today ] !== "undefined" ){
$('#div1').hide();
}
The reason that it is more maintainable is that you can freely edit the days_to_hide definition without having to modify the conditional expression that actually performs the hide() command.
Just for the LOLs, here's a one-liner demonstrating how you can call a jQuery function by (variable) name, and also use modulo arithmetic to avoid two separate calls to .getDay():
$('#div1')[(date.getDay() + 6) % 7 < 5 ? 'show' : 'hide']();
The modulo arithmetic works thus:
Sun = 0, + 6 = 6, mod 7 = 6
Mon = 1, + 6 = 7, mod 7 = 0
...
Fri = 5, + 6 = 11, mod 7 = 4
Sat = 6, + 6 = 12, mod 7 = 5
Hence Monday to Friday give 0 .. 4, and Saturday and Sunday give 5 and 6, allowing a single comparison to check for weekend vs weekday.
For posterity, here's a potentially useful helper function:
Object.defineProperty(Date.prototype, 'isWeekday', { value: function() {
return (this.getDay() + 6) % 7 <= 4;
}));
usage:
if (mydate.isWeekday()) {
...
}
try this code
var d = new Date();
if(d.getDay() == 6 || d.getDay() == 7)
{
$('#div1').hide();
}

Javascript Valid Date Checking does not work in IE8 (and Firefox)

I have tried two popular answers from Detecting an "invalid date" Date instance in JavaScript for checking valid dates. I tested both of them in IE8 – Unfortunately both are disappointing. See it here http://jsfiddle.net/Lijo/uzSU6/2/
Is there a better JavaScript code that will work in IE8 + Chrome + Firefox?
Note: To my surprise, it doesn't work well in Firefox too...
CONDITION
The date format is expected to be US date format with slashes (/)
CODE
isValidDateCheck2('12/33/2012') ;
isValidDateCheck1('12/12/2012') ;
function isValidDateCheck1(d)
{
alert(Object.prototype.toString.call(d));
if ( Object.prototype.toString.call(d) !== "[object Date]" )
{
alert('Not Valid');
}
if(!isNaN(d.getTime()))
{
alert(d.getTime());
}
}
function isValidDateCheck2(d)
{
var timestamp=Date.parse(d);
alert(timestamp);
if (isNaN(timestamp)==false)
{
var date=new Date(timestamp);
alert(date);
}
}
EDIT
#mplungjan approach (first suggested) is listed in http://jsfiddle.net/Lijo/uzSU6/7/. This was failed in IE8 for one scenario - http://jsfiddle.net/Lijo/uzSU6/12/.
You seem to be conflating two things here. Valid date objects and valid dates. These are not the same problem.
The question you linked to answers how to test for validity of date objects (whether a date object is an "invalid date" instance). Invalid date objects are generated when you use invalid parameters when constructing them: new Date('?')
What you want is to test if a date string conforms to a predefined date format. This is an entirely different problem that should not be solved by using only date objects.
Generally speaking, there are a couple of reasons for this; the first is that the browsers will helpfully compute overflow months/days/time to the correct date: new Date(2012,0,290) === Oct 06 2012.
Secondly because the parser may be locale dependent (mm/dd vs. dd/mm?). When the date is parsed by the browser my locale may cause it roll it to my timezone/DST thus skewing it and messing up detection (.getDate may now return next day over). Even worse, this may only occur across some timezones at certain parts of the year.
I strongly encourage using a library like date.js to handle this stuff because dates are much harder than you think! If you absolutely must validate by hand, then I recommend doing it in detail like this:
function isValidDate (str) {
// parse to numbers
const rm = str.split('/');
const m = 1 * rm[0];
const d = 1 * rm[1];
const y = 1 * rm[2];
if (isNaN(m * d * y)) {
return false;
}
// day can't be 0
if (d < 1) {
return false;
}
// month must be 1-12
if (m < 1 || m > 12) {
return false;
}
// february
if (m === 2) {
const isLeapYear = ((y % 4 === 0) && (y % 100 !== 0)) || (y % 400 === 0);
// leap year
if (isLeapYear && d > 29) {
return false;
}
// non-leap year
if (!isLeapYear && d > 28) {
return false;
}
}
// test any other month
else if (
((m === 4 || m === 6 || m === 9 || m === 11) && d > 30) ||
((m === 1 || m === 3 || m === 5 || m === 7 || m === 8 || m === 10 || m === 12) && d > 31)) {
return false;
}
return true;
}
As a jsFiddle: http://jsfiddle.net/3pMPp/1/
As a jsPerf: http://jsperf.com/silly-date-valiation
This will handle actual dates and give you the chance to find what part of the date was invalid - using the DATE OBJECT
NOTE: several browsers will happily parse what seems to be an invalid date and make a date object out of it. For example 02/29/2013 will parse as 1st of March 2013, hence my test to see if the parts entered made sense when used in an actual date.
DEMO
Tested in
Win7:
Chrome 23 (only one to give isNaN on the first date)
IE 9
Win XP:
FX 17
IE 8
Safari 5
Opera 11 and 12
function isValidDateCheck(dString) {
// test it is nn/nn/nnnn or nn/nn/nn
var dRe = /^(\d{1,2})([\-\/])(\d{1,2})\2(\d{4}|\d{2})$/
if (!dRe.exec(dString)) {
return false;
}
// make sure it parses as date
// replace this part if you do not allow dashes
dString.replace(/-/g,"/");
var date = new Date(dString); // create a date object
if (!isNaN(date)) { // it may give NaN - if not test the parts
var parts = dString.split("/"); // split on slash
var dd = parseInt(parts[1],10); // day number
var mm = parseInt(parts[0],10)-1; // month - JS months start at 0
var yyyy = parseInt(parts[2],10); // year
// return true if all parts match
return dd===date.getDate() && mm === date.getMonth() && yyyy===date.getFullYear();
}
// here the date was not parsed as a date
return false;
}
window.onload=function() {
document.getElementById("output").innerHTML+="<br/>12/33/2012: "+isValidDateCheck('12/33/2012');
document.getElementById("output").innerHTML+="<br/>12/12/2012: "+isValidDateCheck('12/12/2012') ;
document.getElementById("output").innerHTML+="<br/>02/29/2012: "+isValidDateCheck('02/29/2012') ;
document.getElementById("output").innerHTML+="<br/>02/29/2013: "+isValidDateCheck('02/29/2013') ;
document.getElementById("output").innerHTML+="<br/>01/01/2013A: "+isValidDateCheck('01/01/2013A') ;
}
Thanks to #mplungjan. I have upvoted that answer.
#mplungjan approach (first suggested) is listed in http://jsfiddle.net/Lijo/uzSU6/7/. This was failed in IE8 for one scenario - http://jsfiddle.net/Lijo/uzSU6/12/.
So I have used a slightly different approach after referring How to validate a date?. See it here http://jsfiddle.net/Lijo/uzSU6/20/
EDIT
Please refer http://jsfiddle.net/uzSU6/37/ for scenarios that handle blank spaces
Feel free to give your suggestions/ challenges with this approach.
References
Check whether white spaces exist without using trim
Which equals operator (== vs ===) should be used in JavaScript comparisons?
How to validate a date?
CODE
function isValidDate(s)
{
var bits = s.split('/');
if(s.indexOf(' ') != -1)
{
//White space exists in the original date string
return false;
}
//Javascript month starts at zero
var d = new Date(bits[2], bits[0] - 1, bits[1]);
if ( isNaN( Number(bits[2]) ) )
{
//Year is not valid number
return false;
}
if ( Number(bits[2]) < 1 )
{
//Year should be greater than zero
return false;
}
//1. Check whether the year is a Number
//2. Check whether the date parts are eqaul to original date components
//3. Check whether d is valid
return d && ( (d.getMonth() + 1) == bits[0]) && (d.getDate() == Number(bits[1]) );
}
​

How do I display all the leap years between two year in javascript

How do I create an HTML page which accepts user input into the text field as integer between 1900 and 2012. When the user presses the “Display” button, the function created in JavaScript should able to display all the leap year between the inputted integer and 2012.
example:
When user enters in "1970" in the text field then the result is:
1972
1976
1980
1984
1988
1992
1996
2000
2004
2008
I have code like this
var str = '';
var i;
for ( i = 1970; i < 2012; i += 1 ) {
if ( new Date( i, 1, 29 ).getMonth() === 1 ) {
str += '<p>' + i + '</p>';
}
}
document.body.innerHTML = str;
I don't understand how to tie this function to the button?
​
I assume that you want to calculate what years a leap years in the Gregorian Calendar, introduced 1582. In the Gregorian calendar there are 97 leap years in 400 years.
Every year that is evenly divisible by 4, but not 100, but 400 is a leap year. 1600 and 2000 is, but not 1700, 1800, 1900.
Here is a solution that takes into account all the rules for leap years in the Gregorian calendar:
for (var i=1890; i < 2010; ++i) {
if (!(i%4)&&(i%100)||!(i%400) ) console.log(i);
}
The rule can also be written as
( ( (year % 4) == 0) && ( (year % 100) !== 0)) || ( (year % 400) ==0)
To be able to bind this to a button you must put it inside a function:
function printLeapYears() {
//Do your thing here
}
Then you must bind it to your button. For example
<button type="button" onclick="printLeapYears()">print leap years</button>
There are other ways to bind the function to the button. Since this is a homework question and I don't know if you are familiar with ids and document.getElementById yet, this solution will probably be enough.
Just for fun, here's an approach that just tests years divisible by four:
function getLeapYears(start, end) {
var startYear = Math.ceil(start / 4) * 4;
var endYear = Math.floor(end / 4) * 4;
var leapYears = [];
if (isNaN(startYear) || isNaN(endYear)) return ['Invalid input'];
while (startYear <= endYear) {
if ( startYear % 100 || !(startYear % 400)) {
leapYears.push(startYear);
}
startYear += 4;
}
return leapYears.length? leapYears : ['None'];
}
And here's one way (some might say not "best practice") to put it in a page:
Start year: <input id="i0"><br>
End year: <input id="i1"><br>
<button onclick="
var start = document.getElementById('i0');
var end = document.getElementById('i1');
var el = document.getElementById('s0');
if (start && end && el) {
el.innerHTML = getLeapYears(start.value, end.value).join('<br>');
}
">List leapyears</button><br>
<span id="s0"></span>

javascript to find leap year

How can I get the code below to work when I have a month of february? Currently it is getting to the day and then stopping before getting to the if to determine whether it is a leap year.
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 +'/' + '';
}
}
It's safer to use Date objects for datetime stuff, e.g.
isLeap = new Date(year, 1, 29).getMonth() == 1
Since people keep asking about how exactly this works, it has to do with how JS calculates the date value from year-month-day (details here). Basically, it first calculates the first of the month and then adds N -1 days to it. So when we're asking for the 29th Feb on a non-leap year, the result will be the 1st Feb + 28 days = 1st March:
> new Date(2015, 1, 29)
< Sun Mar 01 2015 00:00:00 GMT+0100 (CET)
On a leap year, the 1st + 28 = 29th Feb:
> new Date(2016, 1, 29)
< Mon Feb 29 2016 00:00:00 GMT+0100 (CET)
In the code above, I set the date to 29th Feb and look if a roll-over took place. If not (the month is still 1, i.e. February), this is a leap year, otherwise a non-leap one.
Compared to using new Date() this is is around 100 times faster!
Update:
This latest version uses a bit test of the bottom 3 bits (is it a multiple of 4), as well as a check for the year being a multiple of 16 (bottom 4 bits in binary is 15) and being a multiple of 25.
ily = function(y) {return !(y & 3 || !(y % 25) && y & 15);};
http://jsperf.com/ily/15
It is slightly faster again than my previous version (below):
ily = function(yr) {return !((yr % 4) || (!(yr % 100) && (yr % 400)));};
http://jsperf.com/ily/7
It is also 5% faster, compared to the already fast conditional operator version by broc.seib
Speed Test results: http://jsperf.com/ily/6
Expected logic test results:
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)
...subtraction by one should work even faster than compare on most CPU architectures.
Correct and Fast:
ily = function(yr) { return (yr%400)?((yr%100)?((yr%4)?false:true):false):true; }
If you are in a loop or counting the nanoseconds, this is two magnitudes faster than running your year through a new Date() object. Compare the performance here: http://jsperf.com/ily
Better historical computation of leap years.
The code below takes into account that leap years were introduced in 45BC with the Julian calendar, and that the majority of the Western world adopted the Gregorian calendar in 1582CE, and that 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;
};
Britain and its colonies adopted the Gregorian calendar in 1752, so if you are more Anglo centric this version is better (We'll assume Britain adopted the Julian calendar with Roman conquest starting in 43CE).
isLeap = function(yr) {
if (yr > 1752) return !((yr % 4) || (!(yr % 100) && (yr % 400)));
if (yr >= 43) return !(yr % 4);
return false;
};
JavaScript is expected to be getting a new Date/Time API which exposes a new global object - Temporal. This global object provides JS devs with a nicer way to deal with dates/times. It is currently a stage 3 proposal and should hopefully be available for use shortly.
The temporal api exposes a nice property for checking for leap years - inLeapYear. This returns true if a particular date is a leap year, otherwise false. Below we're using with() to convert the date returned by plainDateISO to one with our particular year:
const isLeap = year => Temporal.now.plainDateISO().with({year}).inLeapYear;
console.log(isLeap(2020)); // true
console.log(isLeap(2000)); // true
console.log(isLeap(1944)); // true
console.log(isLeap(2021)); // false
console.log(isLeap(1999)); // false
If you just want to check if your current system date time is a leap year, you can omit the .with():
// true if this year is a leap year, false if it's not a leap year
const isLeap = Temporal.now.plainDateISO().inLeapYear;
I use this because I hate having to keep referring to January as 0 and February as 1.
To me and PHP and readable dates, February=2. I know it doesn't really matter as the number never changes but it just keeps my brain thinking the same across different code.
var year = 2012;
var isLeap = new Date(year,2,1,-1).getDate()==29;
You can easily make this to work calling .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>
all in one line 😉
const isLeapYear = (year) => (year % 100 === 0 ? year % 400 === 0 : year % 4 === 0);
console.log(isLeapYear(2016)); // true
console.log(isLeapYear(2000)); // true
console.log(isLeapYear(1700)); // false
console.log(isLeapYear(1800)); // false
console.log(isLeapYear(2020)); // true
function isLeap(year) {
if ( (year % 4 === 0 && year % 100 !== 0) || (year % 4 === 0 && year % 100 === 0 && year % 400 === 0) ) {
return 'Leap year.'
} else {
return 'Not leap year.';
}
}
Pseudo code
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 )
}
Using the above code insures you do only one check per year if the year is not divisible by 4
Just by adding the brackets you save 2 checks per year that is not divisible by 4
Another alternative is to see if that year has the date of February 29th. If it does have this date, then you know it is a leap year.
ES6
// Months are zero-based integers between 0 and 11, where Febuary = 1
const isLeapYear = year => new Date(year, 1, 29).getDate() === 29;
Tests
> isLeapYear(2016);
< true
> isLeapYear(2019);
< false
function leapYear(year){
if((year%4==0) && (year%100 !==0) || (year%400==0)){
return true;
}
else{
return false;
}
}
var result = leapYear(1700);
console.log(result);
Alternative non-conditionals solution:
const leapYear = y => (y % 4 === 0) + (y % 100 !== 0) + (y % 400 === 0) === 2
Use this:
Date.prototype.isLeap = function() {
return new Date(this.getFullYear(), 1, 29).getMonth() == 1;
};
Date.prototype.isLeap = function() {
return new Date(this.getFullYear(), 1, 29).getMonth() == 1;
};
console.log(new Date("10 Jan 2020").isLeap()); // True
console.log(new Date("10 Jan 2022").isLeap()); // False

Categories