# how can i solve this ,can anyone provide me with code? whats wrong with my code ?

328 views (last 30 days)

Show older comments

Write a function called valid_date that takes three positive integer scalar inputs year, month, day. If these three represent a valid date, return a logical true, otherwise false. The name of the output argument is valid. If any of the inputs is not a positive integer scalar, return false as well. Note that every year that is exactly divisible by 4 is a leap year, except for years that are exactly divisible by 100. However, years that are exactly divisible by 400 are also leap years. For example, the year 1900 was not leap year, but the year 2000 was. Note that your solution must not contain any of the date related built-in MATLAB functions.

function [valid]=valid_date(year, month, day)

if isscalar(year) && year>0 && year~=0 && isscalar(month) && month>0 && month~=0 && isscalar(day) && day>0 && ar

if mod(year,4) == 0 && mod(year, 100)~= 0 || mod(year,400)==0 && month==2 && days<=29

%for february

valid=true;

else

valid=false;

end

%for rest of the months

if month==4 || month==6 || month==9 || month==11 && day<=30

valid=true;

elseif month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month== 12 && day<=31

valid=true;

else

valid=false;

end

%not a leap year

if month==2 && day>28

valid=false;

end

%rest of the months

if month==4 || month==6 || month==9 || month==11 && day<=30

valid=true;

elseif month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month== 12 && day<=31

valid=true;

else

valid=false;

end

else

valid=false;

end

##### 21 Comments

Jan
on 29 Jul 2020

Edited: Jan
on 29 Jul 2020

@Husein Mammadli: Which error message do you get? This message reveals the problems usually.

Your code does not check if the inputs are scalars or have positive integer values. The code distinguishes two cases for Frebrurary:

- ((mod(year,100)==0) && (mod(year,400)~=0))
- (mod(year,4)==0)

This is not useful. You need to detect leap years only:

~mod(year, 4) && mod(year, 100) || ~mod(year, 400)

You can simplify your code:

function valid = valid_date(year,month,day)

if month == 2 % Month 2

if mod(year, 4)==0 && mod(year, 100) || ~mod(year, 400) % Leap year

valid = (day < 30);

else % Not leap year

valid = (day < 29);

end

elseif any(month = [1,3,5,7,8,10,12]) % Months with 31 days

valid = (day < 32);

else % Months with 30 days

valid = (day < 31);

end

end

But the error checks of the inputs are still missing.

### Answers (19)

Jan
on 30 Mar 2019

Edited: Jan
on 6 Sep 2019

function valid = valid_date(year, month, day)

% scalar positive integer limit

if isscalar(year) && year > 0 && fix(year) == year && ...

isscalar(month) && month > 0 && fix(month) == month && month <= 12 && ...

isscalar(day) && day > 0 && fix(day) == day

% Leap year: multiple of 4, but not of 100, or of 400:

isLeap = (~mod(year, 4) && mod(year, 100) || ~mod(year, 400));

% Valid days:

% * month is 4,6,9,11 and days <= 30,

% * month is 2 and days <= 28 or 29 for leap years

% * other month and days <= 31

valid = (any(month == [4,6,9,11]) && day <= 30) || ...

(any(month == [1,3,5,7,8,10,12]) && day <= 31) || ...

(month == 2 && day <= 28 + isLeap);

else

valid = false;

end

end

Or:

function valid = valid_date(year, month, day)

% Anonymous function to check for positive integer scalar values:

ok = @(x) isscalar(x) && x > 0 && fix(x) == x;

valid = false; % Default answer

% Check if all inputs are clean:

if ok(year) && ok(month) && month <= 12 && ok(day)

% Check if it is a leap year:

isLeap = (~mod(year, 4) && mod(year, 100) || ~mod(year, 400));

% Number of days per month, consider leap year for februrary:

d = [31, 28+isLeap, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

% The actual comparison:

valid = (day <= d(month));

end

##### 19 Comments

Oleksandr Koreiba
on 30 Mar 2019

function valid = valid_date(year,month,day)

if isscalar(year)==true && year>0 && isscalar(month)==true && month>0 && 12>=month && isscalar(day)==true && day>0 %checks if input is correct

if (mod(year,4) == 0 && mod(year, 100)~= 0 || mod(year,400)==0) %checks if it's leap

isleap=true;

else

isleap=false;

end

if any(month == [4,6,9,11]) && day<=30 || any(month == [1,3,5,7,8,10,12]) && day<=31

valid = true;

elseif isleap == true && month == 2 && day<=29 || isleap == false && month ==2 && day<=28

valid=true;

else

valid=false;

end

else

valid=false;

end

end

Just beginner with matlab, had the same strugle. But with help from here managed to solve it. Maybe it will be helpful

##### 9 Comments

Walter Roberson
on 12 May 2020

If your first if fails then you do not set valid

Note: isscalar() already returns true or false; there is no need to compare the result to true.

if isscalar(year) && isscalar(month)

Jan
on 28 Mar 2019

Edited: Jan
on 28 Mar 2019

The code fails in the 2nd line, which ends with:

... isscalar(day) && day>0 && ar

What is the meaning of "ar"?

After checking month>0 there is no need to check for month~=0 because this is excluded already. But tis is not an error.

A problem is, that you check for a leap year at first:

if mod(year,4) == 0 && mod(year, 100)~= 0 || ...

mod(year,400)==0 && month==2 && days<=29

%for february

valid=true;

else

valid=false;

end

But afterwards this code runs also:

%not a leap year

if month==2 && day>28

valid=false;

end

This runs for leap years also and the former value of valid is overwritten.

Remember that the operator precedence (link) for && is higher than for ||. Then the test is equivalent to:

if (mod(year,4) == 0 && mod(year, 100)~= 0) || ...

(mod(year,400)==0 && month==2 && days<=29)

%for february

valid=true;

else

valid=false;

end

This sets valid to true for the inputs:

year = 2004;

month = 2;

days = 30;

because mod(year,4) == 0 && mod(year, 100)~= 0 is true already. You need to set the parentheses explicitly:

if (mod(year,4) == 0 && mod(year, 100)~= 0 || mod(year,400)==0) ...

&& month==2 && days<=29

I suggest to rewrite the code. Determine if it is a leap year at first:

isleap = (mod(year,4) == 0 && mod(year, 100)~= 0 || mod(year,400)==0);

Then check the validity for te months:

if any(month == [4,6,9,11]) % Nicer...

valid = (day<=30);

elseif ...

Then consider the leap year for the Februrary only.

##### 28 Comments

Parth Patel
on 1 Jun 2019

Edited: Parth Patel
on 1 Jun 2019

function valid = valid_date(y,m,d)

% check for positve scalar inputs

if (isscalar(y) && y>0 && y ~=0 ) && (isscalar(m) && m>0 && m~=0)&&(isscalar(d) && d>0 && d~=0)

% check for leap year

if mod(y,400) == 0

valid_leap = true;

elseif mod(y,4) == 0 && mod(y,100)~= 0

valid_leap = true;

else

valid_leap = false;

end

% check for february

if(valid_leap == true && m==2 && d <=29) || (valid_leap == false && m==2 && d<=28)

valid = true;

% check for rest of the months

elseif (m == 1 || m == 3 || m == 5 ||m == 7 ||m == 8 ||m == 10 ||m == 12 ) && d <= 31

valid= true;

elseif(m == 4 || m == 6 || m == 9 ||m == 11) && d <= 30

valid = true;

else

valid = false;

end

else

valid = false;

end

end

Aditi Sinha
on 17 Jun 2019

function [valid]=valid_date(year, month, day)

if isscalar(year)==1 && year>0 && year~=0 && isscalar(month)==1 && month>0 && month~=0 && isscalar(day)==1 && day>0 && month<=12

if mod(year,4)==0 && mod(year,100)~=0||mod(year,400)==0

if month==2

if day<=29

valid=true;

else

valid=false;

end

else if month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month== 12

if day<=31

valid=true;

else

valid=false;

end

else if month==4 || month==6 || month==9 || month==11

if day<=30

valid=true;

else

valid=false;

end

end

end

end

else

if month==2

if day<=28

valid=true;

else

valid=false;

end

else if month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month== 12

if day<=31

valid=true;

else

valid=false;

end

else if month==4 || month==6 || month==9 || month==11

if day<=30

valid=true;

else

valid=false;

end

end

end

end

end

else

valid=false;

end

##### 3 Comments

Rik
on 13 May 2020

Because those aren't elseifs, they are else followed by if.

if cond1

else if cond2

%some code

end

end

%this is equivalent to this:

if cond1

else

if cond2

%some code

end

end

Roshan Singh
on 21 Aug 2019

function valid=valid_date(year,month,day)

if (year>0 && month>0 && day>0 && month<13 && day<32 && isscalar(year)==1 && isscalar(month)==1 && isscalar(day)==1)

if (rem(year,400)==0)||((rem(year,4)==0)&&(rem(year,100)~=0))

switch month

case 1

if day<32

valid=true;

else

valid=false;

end

case 2

if day<30

valid=true;

else

valid=false;

end

case 3

if day<32

valid=true;

else

valid=false;

end

case 4

if day<31

valid=true;

else

valid=false;

end

case 5

if day<32

valid=true;

else

valid=false;

end

case 6

if day<31

valid=true;

else

valid=false;

end

case 7

if day<32

valid=true;

else

valid=false;

end

case 8

if day<32

valid=true;

else

valid=false;

end

case 9

if day<31

valid=true;

else

valid=false;

end

case 10

if day<32

valid=true;

else

valid=false;

end

case 11

if day<31

valid=true;

else

valid=false;

end

case 12

if day<32

valid=true;

else

valid=false;

end

end

else

switch month

case 1

if day<32

valid=true;

else

valid=false;

end

case 2

if day<29

valid=true;

else

valid=false;

end

case 3

if day<32

valid=true;

else

valid=false;

end

case 4

if day<31

valid=true;

else

valid=false;

end

case 5

if day<32

valid=true;

else

valid=false;

end

case 6

if day<31

valid=true;

else

valid=false;

end

case 7

if day<32

valid=true;

else

valid=false;

end

case 8

if day<32

valid=true;

else

valid=false;

end

case 9

if day<31

valid=true;

else

valid=false;

end

case 10

if day<32

valid=true;

else

valid=false;

end

case 11

if day<31

valid=true;

else

valid=false;

end

case 12

if day<32

valid=true;

else

valid=false;

end

end

end

else

valid=false

end

##### 1 Comment

Guillaume
on 21 Aug 2019

Edited: Guillaume
on 20 Nov 2019

Your code probably work (I haven't tested) but you need to learn look-up tables. That many case statements must have been a pain to write and would certainly be a pain to maintain.

Your code using a look-up table

%note that this code, like yours will not work properly with non-integer inputs

function valid=valid_date(year,month,day)

numdays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; %look-up table

if (year>0 && month>0 && day>0 && month<13 && day<32 && isscalar(year)==1 && isscalar(month)==1 && isscalar(day)==1)

monthday = numdays(month)

if (rem(year,400)==0)||((rem(year,4)==0)&&(rem(year,100)~=0)) && month==2

monthday = monthday + 1;

end

valid = day <= monthday

else

valid = false;

end

end

See how much simpler that is?

Doga Savas
on 23 Aug 2019

function a = valid_date(year,month,day)

if month > 12

a = false;

return

end

if ~isscalar(year) || year < 1 || year ~= fix(year)

a = false;

return

end

if ~isscalar(month) || month < 1 || month ~= fix(month)

a = false;

return

end

if ~isscalar(day) || day < 1 || day ~= fix(day)

a = false;

return

end

if month == 1 || month == 3 || month == 5 || month == 7 || month == 8 ...

|| month == 10 || month == 12

if day > 31

a = false;

return

end

end

if month == 4 || month == 6 || month == 9 || month == 11

if day > 30

a = false;

return

end

end

if month == 2

if rem(year,4) == 0 && rem(year,100) ~= 0

if day > 29

a = false;

return

end

elseif rem(year,400) == 0

if day > 29

a = false;

return

end

else

if day > 28

a = false;

return

end

end

end

a = true;

end

##### 1 Comment

Chech Joseph
on 6 Sep 2019

Hey Jan, really loved your very precise and explicit code, however I need some more clarifications. Could you please kindly comment out your code especially from the 'isLeap' output argument. ..Thanks

function valid = valid_date(year, month, day)

% scalar positive integer limit

if isscalar(year) && year > 0 && fix(year) == year && ...

isscalar(month) && month > 0 && fix(month) == month && month <= 12 && ...

isscalar(day) && day > 0 && fix(day) == day

isLeap = (~mod(year, 4) && mod(year, 100) || ~mod(year, 400));

valid = (any(month == [4,6,9,11]) && day <= 30) || ...

(any(month == [1,3,5,7,8,10,12]) && day <= 31) || ...

(month == 2 && day <= 28 + isLeap);

else

valid = false;

end

end

VIKAS JAIN
on 14 Sep 2019

function isvalid = valid_date(y, m, d)

% Check if the inputs are valid

% Check that they are scalars

if ~(isscalar(y) && isscalar(m) && isscalar(d))

isvalid = false;

% Check that inputs are positive

elseif ~all([y, m, d] > 0)

isvalid = false;

% Check that inputs are integers (not the data type)

elseif any(rem([y, m, d], 1))

isvalid = false;

% Check that m and d are below the max possible

elseif (m > 12) || (d > 31)

isvalid = false;

% The inputs could be a valid date, let's see if they actually are

else

% Vector of the number of days for each month

daysInMonth = [31 28 31 30 31 30 31 31 30 31 30 31];

% If leap year, change days in Feb

if isequal(rem(y, 4), 0) && (~isequal(rem(y, 100), 0) || isequal(rem(y, 400), 0)) daysInMonth(2) = 29;

end

maxDay = daysInMonth(m);

if d > maxDay

isvalid = false;

else

isvalid = true;

end

end

end

##### 0 Comments

Marwan Hammad
on 19 Nov 2019

function valid = valid_date(year, month, day)

if nargin ==3

valid1=true;

else

error('must have three input arguments');

valid=false;

end

if isscalar(year)==true && isscalar(month)==true && isscalar(day)==true && year==fix(year) && month==fix(month) && day==fix(day)

valid2=true;

else

error('inputs must be a postive integers.');

valid=false;

end

if year>0 && year<2019 && month>0 && month<=12 && day>0 && day<=31

valid3=true;

else

error ('Please enter a valid date.');

valid = false;

end

if ~mod(year,4)

if ~mod(year,100)

if ~mod(year,400)

leap_year = 1;

else

leap_year = 0;

end

else

leap_year = 1;

end

else

leap_year = 0;

end

if (month== 1||3||5||7||8||10||12 && day<=31) && (month== 4||6||9||11 && day<=30)

valid4=true;

elseif ((leap_year==1 && (month==2 && day<=29))||((month==2 && day<=28) && leap_year==0))

valid5=true;

else

error ('Please enter a valid date.');

valid = false;

end

if valid1==true && valid2==true && valid3==true && valid4==true

valid = true;

elseif valid1==true && valid2==true && valid3==true && valid5==true

valid=true;

else

error ('Please enter a valid date.');

valid = false;

return

end

##### 5 Comments

Rik
on 20 Nov 2019

Edited: Rik
on 20 Nov 2019

Let's try some:

valid_date(2016, 2, 29)

%returns true (correctly)

valid_date(2016, 2, 30)

%returns true (obviously incorrectly)

valid_date(2016, -2, 25)

%returns an error, instead of the logical false

And why did you decide to make 2019 as the last valid year?

So the conclusion is that your code only works for dates that are already valid, which is the thing this function is supposed to test. It will either error or it will return true if your date is not valid, so you can't distinguish valid dates from invalid ones with your implementation.

Yefferson RodrÃguez
on 20 Nov 2019

Edited: Yefferson RodrÃguez
on 20 Nov 2019

Hello,

Could someone help me with this?.

I wrote a code, which I think works fine when I try it on matlab.

but, once I summit it using the coursera system it says the opposite.

Thank you.

here is the code:

function valid = valid_date (year, month, day);

%Check if the input has 3 elements:

if nargin < 3;

error('The date must have 3 elements')

else

nargin==3;

validN=true;

end

%Check if the 3 elements are integer, scalars and positives:

%Also for month between 0 and 12.

%also fot days between 0 and 31.

if isscalar(year) && (not(mod(year,1))) == true && year>0

validY = true;

else

error('Year has to be integer, scalar and positive')

end

if isscalar(month) && (not(mod(month,1))) == true && month > 0 && month <= 12

validM = true;

else

error('Month has to be integer, scalar, positive and 0<m<=12')

end

if isscalar(day) && (not(mod(day,1))) == true && day > 0 && day <= 31

validD = true;

else

error('Day has to be integer, scalar, positive and 0<d<=31')

end

if (not(mod(year,4)) == true) && (not(mod(year,400)) == true)

if month == 1 || 3 || 5 || 7 || 8 || 10 || 12;

day <= 31;

elseif month == 2;

day <= 29;

elseif month == 3 || 4 || 6 || 9 || 11;

day <= 30;

end

else

if month == 1 || 3 || 5 || 7 || 8 || 10 || 12;

day <= 31;

elseif month == 2;

day <= 28;

elseif month == 3 || 4 || 6 || 9 || 11;

day <= 30;

end

end

if validN == true && validY == true && validM == true && validD == true

valid = true;

else

valid = false;

end

##### 2 Comments

Jan
on 20 Nov 2019

Edited: Jan
on 20 Nov 2019

Some comments to the code:

- Do not set the value of nargin: nargin==3;
- If year is not a scalar the code proceeds. Then it must fail in

if (not(mod(year,4)) == true) && (not(mod(year,400)) == true)

- This will not do, what you expect:

if month == 1 || 3 || 5 || 7 || 8 || 10 || 12;

It is evaluated from left to right: month == 1 replies true or false. Afterwards true||1 or false||1 replies true in both cases. You mean:

if month == 1 || month == 3 || month == 5 || month == 7 || ...

month == 8 || month == 10 || month == 12

The code

if validN == true && validY == true && validM == true && validD == true

valid = true;

else

valid = false;

end

can be abbreviated to:

valid = validN && validY && validM && validD;

Comparing a logical value with true replies true if it is true and false otherwise. So this comparison is a waste of time. Simply use the logical value directly. The if can be omitted also.

Sandesh V
on 15 Apr 2020

%Can anyone please point out what's wrong with this code?

function valid = valid_date(year,month,day)

if (isscalar(year)==true && year>0 && isscalar(month)==true && month>0 && month<=12 && isscalar(date)==true && date>0)

if (mod(year,4)==0 && mod(year,100)~=0 || mod(year,400)==0)

if ((month==2 && date<=29) || ((month==4 || month==6 || month==9 || month==11) && day<=30) || ((month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) && day<=31))

% Leap year with other dates

valid = true;

else

valid = false;

end

else

if ((month==2 && day<=28) || ((month==4 || month==6 || month==9 || month==11) && day<=30) || ((month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) && day<=31))

valid = true;

else

valid = false;

end

end

else

valid = false;

end

end

##### 2 Comments

Sandesh V
on 15 Apr 2020

SWAROOPA SHIGLI
on 19 Apr 2020

Can anyone tell me why is this wrong?

function valid=valid_date(year,month,day)

if isscalar(year) && isscalar(month) && isscalar(day)

if (year>0 && (month>0 && month<13))

if month == [1 3 5 7 8 10 12]

if day>0 && day<32

valid=true;

else

valid=false;

end

elseif month == [4 6 7 9 11]

if day>0 && day<31

valid=true;

else

valid=false;

end

elseif month == 2

if year/4==0 || year/400==0

yr=leap;

if year/100==0 && year/400==0

yr=leap;

else

yr=nonleap;

end

else

yr=nonleap;

end

if ((day>0 && day<30) && yr==leap) || ((day>0 && day<29) && yr==nonleap)

valid=true;

else

valid=false;

end

end

else

valid=false;

end

else

valid=false;

end

##### 2 Comments

Fazlul Haque
on 12 May 2020

function y= valid_date(a,b,c)

d31=[1 3 5 7 8 10 12];

d30=[4 6 9 11];

%for leap year

if (rem(a,4)==0 && rem(a,100)~=0) || rem(a,400)==0 LY=true;

else LY=false;

end

%for calculation

if sum(ismember(d31,b))==1 && c<=31

y=true;

elseif sum(ismember(d30,b))==1 && c<=30

y=true;

elseif b==2 && LY==false && c<=28

y=true;

elseif b==2 && LY==true && c<=29

y=true;

else y=false;

end

% for error check

if isscalar(a)==0 || isscalar(b)==0 || isscalar(c)==0 || nargin~=3

y=false;

return

end

if fix(a)~=a || fix(b)~=b || fix(c)~=c || a<1 ||b>12|| b<1 ||c>31||c<1

y=false;

end

what's wrong with this code?

##### 3 Comments

Fazlul Haque
on 12 May 2020

thanks brother, I get it now. I should've put the error check at the beginning

Hari Kiran Tirumaladasu
on 13 May 2020

Edited: Hari Kiran Tirumaladasu
on 15 May 2020

For people who are stuck with this problem, here's a simple and short solution by me. It works!!

CODE

function valid = valid_date(y,m,d)

% To check whether the inputs are scalar and correct