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

60 views (last 30 days)
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
Huseyn Mammadli
Huseyn Mammadli on 27 Jul 2020
Someone can help me? Why This code giving error o submit?
function [valid] = valid_date(year,month,day)
% Month 2
if ((mod(year,100)==0) && (mod(year,400)~=0))&& (month == 2) && (day < 29)
valid = true;
elseif ((mod(year,100)==0) && (mod(year,400)~=0))&& (month == 2) && (day > 28)
valid = false;
elseif ((mod(year,100) == 0) && (mod(year,400)==0)) && (month == 2) && (day < 30)
valid = true;
elseif ((mod(year,100) == 0) && (mod(year,400)==0)) && (month == 2) && (day > 29)
valid = false;
elseif (mod(year,4)==0)&& (month == 2) && (day < 30)
valid = true;
elseif (mod(year,4)==0)&& (month == 2) && (day > 29)
valid = false;
elseif (mod(year,4) ~=0)&&(month==2) &&(day>28)
valid = false;
elseif (mod(year,4) ~=0)&&(month==2) &&(day<29)
valid = true;
end
% Month 31
if (month == 1 ||month == 3||month == 5||month == 7||month == 8||month == 10||month == 12)&& (day < 32)
valid=true;
else
valid = false;
end
% Month 30
if (month == 4 ||month == 6||month == 9||month == 11)&& (day < 31),valid=true;
else
valid = false;
end
Jan
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:
  1. ((mod(year,100)==0) && (mod(year,400)~=0))
  2. (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.

Sign in to comment.

Answers (19)

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
  19 Comments
Krashank Kulshrestha
Krashank Kulshrestha on 15 May 2020
Edited: Krashank Kulshrestha on 15 May 2020
@jan ur 1st code is way better than elseif one i tried previously. Thanks.

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
  9 Comments
Walter Roberson
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)

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.
  28 Comments
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.


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
  3 Comments
Rik
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

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

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

saud khan
saud khan on 9 Nov 2019
Thank you very much everyone.

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

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

Sign in to comment.


Sandesh V
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
Rik
Rik on 15 Apr 2020
The structure of the code is not clear. That is probably an important reason why you are unable to find the mistake (if there is one, I haven't run your code).
Make the steps in your program clear. Do one step at a time and write a comment explaining what happens.
In this case the readability will probably improve a lot if you use a vector for the number of days in a month. That will also reduce the chance of typos.
Have a look at what the other functions in this thread are doing. There are several complete working examples, so learn from them.
And next time post your question as a question instead of an answer. You can find guidelines for posting homework on this forum here.
Sandesh V
Sandesh V on 15 Apr 2020
I found the error, I have used date instead of day in line2. Thanks for the input and I also from now on I will follow the guidelines for posting homework.

Sign in to comment.


SWAROOPA SHIGLI
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
Rik
Rik on 19 Apr 2020
There are two things wrong with this post:
  1. it is not an answer, but a question
  2. you are checking for a leap year in an incorrect way. year/4 will not be equal to 0, unless year is 0, in which case that line will not be reached. You are also using leap and nonleap as variables or functions. You should use a logical scalar instead.

Sign in to comment.


Fazlul Haque
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

Sign in to comment.


Hari Kiran Tirumaladasu
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
if (isscalar(y) && y > 0 && y ~= 0 ) && (isscalar(m) && m > 0 && m <= 12) && (isscalar(d) && d > 0 && d <= 31)
valid = true;
else
valid = false;
return
end
% To check for Leap Year
if((mod(y,4) == 0 && mod(y,100) ~= 0) || mod(y,400) == 0) && (m == 2 && d <= 29)
valid = true;
% Check for month of February
elseif (m == 2 && d <= 28)
valid = true;
% Check for remaining 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

Sumit Kumar Sharma
Sumit Kumar Sharma on 24 May 2020
Edited: Sumit Kumar Sharma on 24 May 2020
%% I think this might help
function valid=valid_date(y,m,d)
if isscalar(y) && y>0 && fix(y)==y && isscalar(m) && m<=12 && m>0 && fix(m)==m && isscalar(d) && d>0 && fix(d)==d
x=leap_year(y);
if any(m==[1 3 5 7 8 10 12]) && d<=31
valid=true;
elseif any(m==[4 6 9 11]) && d<=30
valid=true;
elseif m==2 && d<=(28+x)
valid=true;
else
valid=false;
end
else
valid=false;
end
function z= leap_year(c)
if mod(c,4)==0
z=true;
if mod(c,100)==0
z=false;
if mod(c,400)==0
z=true;
end
end
else
z=false;
end

Eshwar Raja Sayinathababu
Eshwar Raja Sayinathababu on 30 Jul 2020
function [valid] = valid_date(year,month,day)
leap_year = 0;
if nargin < 3
valid = false;
end
if (nargin == 3)
if ~isscalar(year) || year < 1 || year ~= fix(year)
valid=false;
return;
end
if ~isscalar(month) || month < 1 || month ~= fix(month)
valid=false;
return;
end
if ~isscalar(day) || day < 1 || day ~= fix(day)
valid=false;
return;
end
end
if ((year == 0) || (month == 0) || (day == 0))
valid = false;
return;
elseif (((isscalar(year)) || (isscalar(month)) || (isscalar(month))) == 0)
valid = false;
return;
elseif (rem(year,4) == 0)
if ((rem(year,100) == 0))
if (rem(year,400)==0)
leap_year = 1;
end
else
leap_year = 1;
end
end
if leap_year == 1
if (month == 1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12)
if (day > 31)
valid = false;
else
valid = true;
end
elseif (month == 4 || month==6 || month==9 || month==11)
if (day > 30)
valid = false;
else
valid = true;
end
elseif (month == 2)
if (day >29)
valid = false;
else
valid = true;
end
else
valid = false;
end
else
if (month == 1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12)
if (day > 31)
valid = false;
else
valid = true;
end
elseif (month == 4 || month==6 || month==9 || month==11)
if (day > 30)
valid = false;
else
valid = true;
end
elseif (month == 2)
if (day >28)
valid = false;
else
valid = true;
end
else valid = false;
end
end
end
% This code will work
  1 Comment
Rik
Rik on 30 Jul 2020
This code may indeed work, but why did you decide to post it?
Also, why are you testing if the input is 0? If it is smaller than 1 the code will already return false before.
And why did you copy-paste the code for the leap year switch? Why don't you put an if in there only for February? This code is relatively simple, but for more complex code you will have trouble finding all the places to correct a bug. Use code only once. You could even do that for your input validation:
if nargin < 3
valid = false;
end
if (nargin == 3)
if ~isscalar(year) || year < 1 || year ~= fix(year)
valid=false;
return;
end
if ~isscalar(month) || month < 1 || month ~= fix(month)
valid=false;
return;
end
if ~isscalar(day) || day < 1 || day ~= fix(day)
valid=false;
return;
end
end
or:
if nargin==3
for item={year,month,day}
item=item{1};
if ~isscalar(item) || item<1 || item~=fix(item)
valid=false;return
end
end
else
valid=false;return
end

Sign in to comment.


Divya Prasad Singhdev
Divya Prasad Singhdev on 17 Aug 2020
function valid = valid_date (year, month, day)
if isscalar(year)==true && year>0 && isscalar(month)==true && month>0 && month<=12 && isscalar(day)==true && day>0 && day<32
%for leap year, feb = 29days
if (month == 2)
%we need to check whether the year is a centurial leap year or not
if ( mod(year,4) == 0 )
%since every year that is divisible by 4 is not a leap year, we need to check this
if (mod(year,100) == 0) && (mod(year,400) == 0)
%that is the centurial year is a leap year
if day <30
valid = true;
else
valid = false;
end
% since all the centurial years are not leap year we need to check the days
elseif (mod(year,100) == 0 ) && (mod(year,400) ~= 0 )
%that is the centurial year is not a leap year
if day <29
valid = true;
else
valid = false;
end
elseif day < 30 %any other year divisible by 4 which is not a centurial year is a leap year so it should have days < 30
valid = true;
else
valid = false;
end
elseif day <29
valid = true;
else
valid = false;
end
%since the rest of the months are not affected by the leap year
elseif any(month == [1,3,5,7,8,10,12] )
if day <32
valid = true;
else
valid = false;
end
elseif any(month == [4,6,9,11] )
if day <31
valid = true;
else
valid = false;
end
else
valid = false;
end
else
valid = false
end
end
  1 Comment
Jan
Jan on 18 Aug 2020
Some hints: if isscalar(year)==true does exactly the same as if isscalar(year). isscalar replies a logical value and comparing it with true replies the same logical value.
You can save a lot of lines, if you move the repeated line valid = false; to the top. Then:
function valid = valid_date (year, month, day)
valid = false;
if isscalar(year) && year>0 && isscalar(month) && month>0 && month<=12 && ...
isscalar(day) && day>0 && day<32
%for leap year, feb = 29days
if (month == 2)
%we need to check whether the year is a centurial leap year or not
if ( mod(year,4) == 0 )
%since every year that is divisible by 4 is not a leap year, we need to check this
if (mod(year,100) == 0) && (mod(year,400) == 0)
%that is the centurial year is a leap year
if day <30
valid = true;
end
% since all the centurial years are not leap year we need to check the days
elseif (mod(year,100) == 0 ) && (mod(year,400) ~= 0 )
%that is the centurial year is not a leap year
if day <29
valid = true;
end
elseif day < 30 %any other year divisible by 4 which is not a centurial year is a leap year so it should have days < 30
valid = true;
end
elseif day <29
valid = true;
end
%since the rest of the months are not affected by the leap year
elseif any(month == [1,3,5,7,8,10,12] )
if day <32
valid = true;
end
elseif any(month == [4,6,9,11] )
if day <31
valid = true;
end
end
end
end
Now the code is a little bit more clear. You can see e.g. this:
if ( mod(year,4) == 0 )
% ^^^^^^^^^^^^^^^^
if (mod(year,100) == 0) && (mod(year,400) == 0)
% ^^^^^^^^^^^^^^^^^^ repeated
if day <30
valid = true;
end
elseif (mod(year,100) == 0 ) && (mod(year,400) ~= 0 )
% ^^^^^^^^^^^^^^^^^^ impossible
While the condition on the top guarantees, that mod(year, 400) == 0, the second IF condition repeats the same test and the third cannot be true.
It would be easier to perfrom the check for a leap year in one step:
if (month == 2)
if (~mod(year, 4) && mod(year, 100) || ~mod(year, 400)) % This is a leap year
valid = (day < 30);
else
valid = (day < 29);
end
else ...
Note that valid = (day < 30) is shorter than:
if (day < 30)
valid = true;
end

Sign in to comment.


Dwight Celis
Dwight Celis on 2 Sep 2020
Edited: Dwight Celis on 2 Sep 2020
function valid= valid_date(y,m,d)
if isscalar(y) && isscalar(m) && isscalar(d) && y>0 && m>0 && d>0 && m<=12
if m==1||m==3||m==5||m==7||m==8||m==10||m==12 %for months with 31 days
if d<=31
valid=true;
else
valid=false;
end
elseif m==4||m==6||m==9||m==11 % for months with 30 days only
if d<=30
valid=true;
else
valid=false;
end
else %for february
if mod(y,4)==0 %conditions for leap years
if mod(y,100)==0
if mod(y,400)==0
if d<=29
valid=true;
else
valid=false;
end
else
if d<=28
valid=true;
else
valid=false;
end
end
else
if d<=29
valid=true;
else
valid=false;
end
end
else
if d<=28 %for non-leap years
valid=true;
else
valid=false;
end
end
end
else
valid=false;
end
  9 Comments
Jan
Jan on 7 Sep 2020
Edited: Jan on 7 Sep 2020
Let me take the chance to suggest some improvements of the code.
Avoid repeated code. Here you define "valid=false;" 7 times. Compare it with this version, where this line is moved to the top as deafult value. In addition
else
if d<=29
valid=true;
end
end
can be simpliefied by an elseif:
function valid= valid_date(y,m,d)
valid = false;
if isscalar(y) && isscalar(m) && isscalar(d) && y>0 && m>0 && d>0 && m<=12
if m==1||m==3||m==5||m==7||m==8||m==10||m==12 %for months with 31 days
if d<=31
valid=true;
end
elseif m==4||m==6||m==9||m==11 % for months with 30 days only
if d<=30
valid=true;
end
else %for february
if mod(y,4)==0 %conditions for leap years
if mod(y,100)==0
if mod(y,400)==0
if d<=29
valid=true;
end
elseif d<=28
valid=true;
end
elseif d<=29
valid=true;
end
elseif d<=28 %for non-leap years
valid=true;
end
end
end
19 lines shorter and easier to read. Now join the leap year detection:
function valid = valid_date(y,m,d)
valid = false;
if isscalar(y) && isscalar(m) && isscalar(d) && ...
y>0 && m>0 && d>0 && m<=12
if m==1||m==3||m==5||m==7||m==8||m==10||m==12 % months with 31 days
if d<=31
valid=true;
end
elseif m==4||m==6||m==9||m==11 % months with 30 days only
if d<=30
valid=true;
end
else % February
if (mod(year, 4) == 0 && mod(year, 100) ~= 0) || ...
mod(year, 400) == 0 % A leap year
if d<=29
valid=true;
end
elseif d<=28
valid=true;
end
end
end
Finally remember, that
if d<=29
valid=true;
end
is equivalent to:
valid = (d<=29);
Then:
function valid = valid_date(y,m,d)
valid = false;
if isscalar(y) && isscalar(m) && isscalar(d) && ...
y>0 && m>0 && d>0 && m<=12
if m==1||m==3||m==5||m==7||m==8||m==10||m==12 % months with 31 days
valid = (d <= 31);
elseif m==4||m==6||m==9||m==11 % months with 30 days only
valid = (d <= 30);
elseif (mod(year, 4) == 0 && mod(year, 100) ~= 0) || ...
mod(year, 400) == 0 % Februrary in a leap year
valid = (d <= 29);
elseif % Februrary, non-leap year
valid = (d <= 28);
end
end
13 lines (not counting the ... continuation) instead of 48. Note that other solutions check if m,d,y have integer values.
Experienced programmers like Rik see the potential for simplifications directly and after removing the redundancies, the solution is almost the same as other already posted solutions. But of course for beginners this equivalence is not obvious.
Rik's question about the reason of posting this answer is eligible. I'd suggest to edit the answer and add your explanation, that this is a version without any() and indexing methods. Finally, I think reading your answer and the discussion is useful, hopefully for you also.

Sign in to comment.

Categories

Find more on Data Type Conversion in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!