MATLAB Answers

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

1.224 views (last 30 days)
asad jaffar
asad jaffar on 28 Mar 2019
Edited: Rik on 20 Nov 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

  17 Comments

Aman Gupta
Aman Gupta on 26 Jun 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.

SOLUTION IS HERE

function valid = valid_date(year,month,day)
t = (isscalar(year) && isscalar(month) && isscalar(day));
if (t == 0);
valid = t;
else
T = ((nargin == 3) && (year>0) && ((month > 0) && (month <=12)) && ((day > 0) && (day<=31)));
if T
persistent Div_by_Four;
persistent Div_by_FHun;
persistent div_by_hund;
persistent leap_year;
leap_year=0;
Div_by_Four = rem(year,4);
Div_by_FHun = rem(year,400);
div_by_hund = rem(year,100);
if (Div_by_Four == 0)
leap_year = 1;
end
if (div_by_hund == 0)
leap_year = 0;
end
if (Div_by_FHun == 0)
leap_year = 1;
end
if (leap_year == 1 && month == 2)
valid = day<=29;
elseif (month<=7)
if(month == 2)
valid = day<=28;
elseif (rem(month,2) == 0)
valid = day<=30;
else
valid = day<=31;
end
else
if (rem(month,2) == 0)
valid = day<=31;
else
valid = day<=30;
end
end
else
valid = T
end
end
Mohd Sharique  Khan
Mohd Sharique Khan on 27 Jun 2019
ans
function valid = valid_date(year,month,day)
%check the input are positive integer or not
if ~isscalar(year) || year<1 || year ~= fix(year)
valid = false;
return
end
%find out wether it is leapyear or not
if ~mod(year,4)
if ~mod(year,100)
if ~mod(year,400)
leap = 1;
else
leap = 0;
end
else
leap = 1;
end
else
leap = 0;
end
month_verification = [31 28+leap 31 30 31 30 31 31 30 31 30 31 ];
if ~isscalar(month) || ~(month>0 && month<=12) || month ~= fix(month)
valid = false;
return
end
if ~isscalar(day) || ~(day>0 && day<=month_verification(month)) || day ~= fix(day)
valid = false;
return
end
valid = true;
Jan
Jan on 28 Jun 2019
@Aman Gupta: There is no need to declare the variables as persistent.
@Mohd Sharique Khan: Please post answers in the section for answers.

Sign in to comment.

Answers (11)

Jan
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

  17 Comments

Jan
Jan on 6 Sep 2019
Chech Joseph about 3 hours ago
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
Walter Roberson
Walter Roberson on 6 Sep 2019
mod(year,400) is 0 if the year is a multiple of 400. ~mod(year,400) is 1 if mod(year,400) is 0 . Thus ~mod(year,400) is true if the year is a multiple of 400, and is the same as mod(year,400) == 0

Sign in to comment.


Jan
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.

  27 Comments

Walter Roberson
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
  1. validate that the inputs are positive integer scalars, and that month number is not too much, and return false if they are not
  2. assignment of number of days of month
  3. test for leap year. Assignment of new value to number of days for february if so.
  4. 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
  5. otherwise return false
asad jaffar
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.


Oleksandr Koreiba
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

  6 Comments

Show 3 older comments
Jan
Jan on 30 Mar 2019
@Oleksandr: Your code worked correctly already, I just simplified it a little bit. This looks nicer and shorter code is less prone to typos.
Jan
Jan on 10 Jun 2019
@samhitha sree: Seriously? You find several working codes in this thread already. Just copy&paste them.

Sign in to comment.


Parth Patel
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

  2 Comments

Walter Roberson
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 ?

Sign in to comment.


Aditi Sinha
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

  1 Comment

Walter Roberson
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.


Roshan Singh
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
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.


Doga Savas
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
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

Sign in to comment.


VIKAS JAIN
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

Sign in to comment.



Marwan Hammad
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

Show 2 older comments
Guillaume
Guillaume on 20 Nov 2019
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
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.

Sign in to comment.


Yefferson Rodríguez
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

Rik
Rik on 20 Nov 2019
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
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.

Sign in to comment.

Sign in to answer this question.