Asked by asad jaffar
on 28 Mar 2019

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

Answer by Jan
on 30 Mar 2019

Edited by 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

Jan
on 2 May 2019

I'm fine, asad jaffar. Do the posted solutions work for you now?

Jan
on 6 Sep 2019

Walter Roberson
on 6 Sep 2019

Sign in to comment.

Answer by Jan
on 28 Mar 2019

Edited by 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.

Walter Roberson
on 29 Mar 2019

I am not referring to the code I posted that fixed the "end" problem. I posted a completely different algorithm for you to follow. Give up on your existing code and write following the outline I showed. It is going to look like

- validate that the inputs are positive integer scalars, and that month number is not too much, and return false if they are not
- assignment of number of days of month
- test for leap year. Assignment of new value to number of days for february if so.
- test if the day provided is less than the number of days per month indexed at the month number, and return true if it is
- otherwise return false

asad jaffar
on 29 Mar 2019

okay i will try it tomorrow ,its night here ,i am going to sleep.

asad jaffar
on 30 Mar 2019

i am giving up , i have tried all ofyou guys code ,they all run but dont give desire result,i have done a lot of assignment but this one is confusing as hell.

any last hope???

Sign in to comment.

Answer by 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

Jan
on 30 Mar 2019

samhitha sree
on 9 Jun 2019

can anyone please send me the correct and exact code please

Jan
on 10 Jun 2019

Sign in to comment.

Answer by Parth Patel
on 1 Jun 2019

Edited by 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

Walter Roberson
on 1 Jun 2019

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

It is not obvious why you have a month test with your year tests? You do not know yet that m is a scalar.

(isscalar(m) && m>0 && m~=0)

That re-tests m~=0 for no apparent reason?

Could you give an example of an m that could pass the m>0 test but fail m~=0 ?

Parth Patel
on 1 Jun 2019

apparently not

Sign in to comment.

Answer by 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

Walter Roberson
on 17 Jun 2019

Could you give an example of a year that could pass the year>0 test but fail year~=0 ?

Sign in to comment.

Answer by 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

Guillaume
on 21 Aug 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?

Sign in to comment.

Answer by 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

Chech Joseph
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

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

Sign in to comment.

Answer by 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

Sign in to comment.

Answer by Marwan Hammad
on 19 Nov 2019 at 22:11

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

Marwan Hammad
on 20 Nov 2019 at 9:44

It works with me man with any date you want

Guillaume
on 20 Nov 2019 at 10:10

It works with me

Again, have you tested it?

>> month = pi;

>> if (month== 1||3||5||7||8||10||12), disp('valid month'); else disp('invalid month'); end

valid month

>> month = -123456;

>> if (month== 1||3||5||7||8||10||12), disp('valid month'); else disp('invalid month'); end

valid month

Does it look like it's working correctly to you?

Rik
on 20 Nov 2019 at 10:20

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.

Sign in to comment.

Answer by Yefferson Rodríguez
on 20 Nov 2019 at 16:31

Edited by Yefferson Rodríguez
on 20 Nov 2019 at 16:31

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

Rik
on 20 Nov 2019 at 16:45

This is not an answer, but a question. Read the comments on other people posting here for further hints (or complete working solutions).

You might also try these three test cases:

valid_date(2016, 2, 29)

valid_date(2016, 2, 30)

valid_date(2016, -2, 25)

Jan
on 20 Nov 2019 at 17:35

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.

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 17 Comments

## Geoff Hayes (view profile)

## 이 댓글에 대한 바로 가기 링크

https://kr.mathworks.com/matlabcentral/answers/453107-how-can-i-solve-this-can-anyone-provide-me-with-code-whats-wrong-with-my-code#comment_687170

## Geoff Hayes (view profile)

## Direct link to this comment

https://www.mathworks.com/matlabcentral/answers/453107-how-can-i-solve-this-can-anyone-provide-me-with-code-whats-wrong-with-my-code#comment_687173

## asad jaffar (view profile)

## 이 댓글에 대한 바로 가기 링크

https://kr.mathworks.com/matlabcentral/answers/453107-how-can-i-solve-this-can-anyone-provide-me-with-code-whats-wrong-with-my-code#comment_687182

## asad jaffar (view profile)

## 이 댓글에 대한 바로 가기 링크

https://kr.mathworks.com/matlabcentral/answers/453107-how-can-i-solve-this-can-anyone-provide-me-with-code-whats-wrong-with-my-code#comment_687183

## asad jaffar (view profile)

## Direct link to this comment

https://www.mathworks.com/matlabcentral/answers/453107-how-can-i-solve-this-can-anyone-provide-me-with-code-whats-wrong-with-my-code#comment_687190

## Geoff Hayes (view profile)

## Direct link to this comment

https://www.mathworks.com/matlabcentral/answers/453107-how-can-i-solve-this-can-anyone-provide-me-with-code-whats-wrong-with-my-code#comment_687230

## Geoff Hayes (view profile)

## Direct link to this comment

https://www.mathworks.com/matlabcentral/answers/453107-how-can-i-solve-this-can-anyone-provide-me-with-code-whats-wrong-with-my-code#comment_687231

## asad jaffar (view profile)

## Direct link to this comment

https://www.mathworks.com/matlabcentral/answers/453107-how-can-i-solve-this-can-anyone-provide-me-with-code-whats-wrong-with-my-code#comment_687237

## Walter Roberson (view profile)

## Direct link to this comment

https://www.mathworks.com/matlabcentral/answers/453107-how-can-i-solve-this-can-anyone-provide-me-with-code-whats-wrong-with-my-code#comment_687240

## Geoff Hayes (view profile)

## 이 댓글에 대한 바로 가기 링크

https://kr.mathworks.com/matlabcentral/answers/453107-how-can-i-solve-this-can-anyone-provide-me-with-code-whats-wrong-with-my-code#comment_687241

## asad jaffar (view profile)

## Direct link to this comment

https://www.mathworks.com/matlabcentral/answers/453107-how-can-i-solve-this-can-anyone-provide-me-with-code-whats-wrong-with-my-code#comment_687471

## asad jaffar (view profile)

## Direct link to this comment

https://www.mathworks.com/matlabcentral/answers/453107-how-can-i-solve-this-can-anyone-provide-me-with-code-whats-wrong-with-my-code#comment_687474

## asad jaffar (view profile)

## Direct link to this comment

https://www.mathworks.com/matlabcentral/answers/453107-how-can-i-solve-this-can-anyone-provide-me-with-code-whats-wrong-with-my-code#comment_687477

## Jan (view profile)

## Direct link to this comment

https://www.mathworks.com/matlabcentral/answers/453107-how-can-i-solve-this-can-anyone-provide-me-with-code-whats-wrong-with-my-code#comment_687490

## Aman Gupta (view profile)

## Direct link to this comment

https://www.mathworks.com/matlabcentral/answers/453107-how-can-i-solve-this-can-anyone-provide-me-with-code-whats-wrong-with-my-code#comment_718731

## SOLUTION IS HERE

## Mohd Sharique Khan (view profile)

## Direct link to this comment

https://www.mathworks.com/matlabcentral/answers/453107-how-can-i-solve-this-can-anyone-provide-me-with-code-whats-wrong-with-my-code#comment_719161

## Jan (view profile)

## Direct link to this comment

https://www.mathworks.com/matlabcentral/answers/453107-how-can-i-solve-this-can-anyone-provide-me-with-code-whats-wrong-with-my-code#comment_719348

Sign in to comment.