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.

137 visualizzazioni (ultimi 30 giorni)
Hi Folks,
I have tried and ended up in errors. For example(valid_date(2018, 4, 1) failed,The last day of every month
Variable valid has an incorrect value. valid_date(2000, 1, 31) failed..., Random leap years
Variable valid has an incorrect value. valid_date(1624, 2, 29) failed..., Random dates
Variable valid has an incorrect value. valid_date(1433, 6, 28) failed...)
Kindly point out the errors I have made!
function valid = valid_date(year,month,day)
if (nargin==3)
if (fix(valid_date)&&isscalar(valid_date))
if((rem(year,4)==0||rem(year,400)==0) && rem(year,100)~=0)
if((month==1||3||5||7||9||11) && 0<day<32)
valid=true;
elseif(month==2 && 0<day<30)
valid=true;
elseif((month==4||6||8||10||12) && 0<day<31)
valid=true;
else
valid=false;
end
else
if((month==1||3||5||7||9||11) && 0<day<32)
valid=true;
elseif((month==4||6||8||10||12) && 0<day<31)
valid=true;
elseif(month==2 && 0<day<29)
valid=true;
else
valid=false;
end
end
else
valid=false;
end
else
valid=false;
end
  4 Commenti
Rakeshwar Elango
Rakeshwar Elango il 28 Giu 2019
Thank you Stephen and Guillaume as the newly invented statement of me didn't through any error so I was wandering wheather where it went wrong. Thank you for your suggesion!

Accedi per commentare.

Risposta accettata

James Tursa
James Tursa il 27 Giu 2019
Looks like you are taking the same class as Rahul. Rather than repeat my answer here, I will simply direct you to the link:
  3 Commenti
Karina Medina Barzola
Karina Medina Barzola il 8 Giu 2021
function valid = valid_date(year,month,day)
if (isscalar(year)&&isscalar(month)&&isscalar(day))&&(isinteger(year/4) || ~isinteger(year/4)) && ((month == 1) || (month == 3) || (month == 5) || (month == 7) || (month == 8) || (month == 10) || (month == 12)) && (day>0 && day<=31)
valid = true;
elseif (isscalar(year)&&isscalar(month)&&isscalar(day))&&(isinteger(year/4) || ~isinteger(year/4)) && ((month == 4) || (month == 6) || (month == 9) || (month == 11)) && (day>0 && day<=30)
valid = true;
elseif (isscalar(year)&&isscalar(month)&&isscalar(day))&&mod(year, 400) == 0 && month == 2 && (day>0 && day<=29)
valid = true;
elseif (isscalar(year)&&isscalar(month)&&isscalar(day))&&mod(year, 4) == 0 && mod(year, 100) ~= 0 && month == 2 && (day>0 && day<=29)
valid = true;
elseif (isscalar(year)&&isscalar(month)&&isscalar(day))&&~(mod(year, 400) == 0) && month == 2 && (day>0 && day<=28)
valid = true;
elseif (isscalar(year)&&isscalar(month)&&isscalar(day))&&~(mod(year, 4) == 0 && mod(year, 100) ~= 0) && month == 2 && (day>0 && day<=28)
valid = true;
else
valid = false;
end
Divyanshu Gupta
Divyanshu Gupta il 3 Lug 2022
Hello I tried floowing code but its not working can anyone tell why?
function valid = valid_date(year,month,day)
if isinteger(year) && year>0 && isinteger(month) && month==1||month==3||month==5||month==7||month==8||month==10||month==12 && day < 32 && isinteger(day) && day>0
valid = true;
elseif isinteger(year) && year>0 && isinteger(month) && month==4||month==6||month==9||month==11 && day <31 && isinteger(day) && day>0
valid = true;
elseif isinteger(year) && year>0 && isinteger(year/4) && isinteger(year/400) && isinteger(month) && month == 2 && isinteger(day) && day>0 && day < 30
valid = true;
elseif isinteger(year) && year>0 && ~isinteger(year/4) && isinteger(month) && month == 2 && isinteger(day) && day>0 && day < 29
valid = true;
else
valid = false;
end

Accedi per commentare.

Più risposte (14)

Martín Avalos Postigo
Martín Avalos Postigo il 28 Giu 2021
function valid = valid_date(year,month,day)
if sum(rem([year,month,day],1))==0 && sum([year,month,day]>0)==3
if ismember(month,[1,3,5,7,8,10,12]) && day<32
valid=true;
elseif ismember(month,[4,6,9,11]) && day<31
valid=true;
elseif month==2 && ismember(sum(rem(year,[4,100,400])==0),[1,3]) && day<30
valid=true;
elseif month==2 && ismember(sum(rem(year,[4,100,400])==0),[0,2]) && day<29
valid=true;
else
valid=false;
end
else
valid=false;
end
  3 Commenti
Alexandar
Alexandar il 29 Giu 2022
Can you please explain what
sum(rem([year,month,day],1))==0
does? Is it trying to say if there is a remainder of 1 then it is false?
Walter Roberson
Walter Roberson il 4 Ago 2022
rem() of something with 1 is 0 if the item is integer, and is non-zero if the item has a fraction. So the rem([year,month,day],1) is creating a vector of fractions (possibly 0) for year, month, day. Those fractions are summed, and the sum is compared to 0. The hypothesis is that if the fractions are all 0 then the sum of fractions are 0, and if any of the fractions are non-zero, then the sum of the fractions would be non-zero.
However, the code has a bug:
sum(rem([-3.2,4.2,5],1))
ans = 0
compare to
sum(mod([-3.2,4.2,5],1))
ans = 1

Accedi per commentare.


Jatan Shah
Jatan Shah il 5 Ago 2021
Modificato: Walter Roberson il 4 Ago 2022
function valid = valid_date (year, month, day)
if nargin<3
valid = false;
elseif ~isscalar(year) || year<1 || year~=fix(year)
valid = false;
elseif ~isscalar(month) || month<1 || month~=fix(month) || month>12
valid = false;
elseif ~isscalar(day) || 1>day || day~=fix(day) || day>31
valid = false;
elseif (month==4 || month==6 || month==9 || month==11) && day>30
valid = false;
elseif month==2 && day>29
valid = false;
elseif month==2 && day>28 && (year/4) ~= fix(year/4)
valid = false;
elseif (year/100)==fix(year/100) && (year/400)~=fix(year/400)
valid = false;
else
valid = true;
end

Abhinav Gadge
Abhinav Gadge il 31 Lug 2022
Modificato: Abhinav Gadge il 31 Lug 2022
%works correctly for all cases
function valid=valid_date(y,m,d)
days=[31,28,31,30,31,30,31,31,30,31,30,31]
if (mod(y,4)==0 & mod(y,100) ~=0) | mod(y,400)==0
days(2)=29
end
if (isscalar(y) & isscalar(m) & isscalar(d)) & y>1 & (m>=1 & m<=12) & (d>=1 & d<=days(m))
valid=true
else
valid=false
end
end

VIGNESH B S
VIGNESH B S il 13 Ott 2021
Modificato: DGM il 21 Feb 2023
function [valid] = valid_date(year,month,day)
Entered = 0;
if isscalar(year) == 0
valid = logical(0);
Entered = 1;
elseif isscalar(month) == 0
valid = logical(0);
Entered = 1;
elseif isscalar(day) == 0
valid = logical(0);
Entered = 1;
end
if year <= 0
valid = logical(0);
Entered = 1;
elseif month <= 0
valid = logical(0);
Entered = 1;
elseif day <= 0
valid = logical(0);
Entered = 1;
end
leap_year = 0;
if(mod(year,4) == 0)
leap_year = 1;
if mod(year,100) == 0
if mod(year,400) == 0
leap_year = 1;
else
leap_year = 0;
end
end
end
if [leap_year,month,day] == [0,2,29]
valid = logical(0);
Entered = 1;
end
if [leap_year,month,day] == [1,2,29]
valid = logical(1);
end
if month == 1
if day >= 32
valid = (0>1);
Entered = 1;
end
elseif month == 10
if day >= 32
valid = (0>1);
Entered = 1;
end
elseif month == 8
if day >= 32
valid = (0>1);
Entered = 1;
end
elseif month == 7
if day >= 32
valid = (0>1);
Entered = 1;
end
elseif month == 5
if day >= 32
valid = (0>1);
Entered = 1;
end
elseif month == 3
if day >= 32
valid = (0>1);
Entered = 1;
end
elseif month == 12
if day >= 32
valid = (0>1);
Entered = 1;
end
elseif month == 4
if day >= 31
valid = logical(0);
Entered = 1;
end
elseif month == 9
if day >= 31
valid = logical(0);
Entered = 1;
end
elseif month == 6
if day >= 31
valid = logical(0);
Entered = 1;
end
elseif month == 11
if day >= 31
valid = logical(0);
Entered = 1;
end
end
if month == 2
if day >= 30
Entered = 1;
valid = logical(0);
end
end
if month >= 13
Entered = 1;
valid = logical(0);
end
if Entered == 0
valid = logical(1);
end
end
%A HELL LINES OF CODES!!!!!!! BUT IT WORKED OUT !!

Aramis
Aramis il 5 Feb 2024
The best answer
function valid = valid_date(year,month,day)
if not(isscalar(year))|| not(isscalar(month)) || not(isscalar(day))|| min([year month day]) <1 || month>12 || day>31 || nargin<3
valid = false;
elseif month == 2
if mod(year,4) == 0 && not(mod(year,100) == 0) || mod(year,400) == 0
valid = day<30;
else
valid = day<29;
end
elseif max(month == [4 6 9 11])
valid = day<31;
else
valid = true;
end
end

S HARIPRAKASH
S HARIPRAKASH il 25 Ago 2021
valid date or not
function valid=valid_date(year,month,day)
%check whether the given input is scalar positive integer or not
%1<=day<=31
%1<=month<=12
if((~isscalar(year))||(~isscalar(month))||(~isscalar(day))||(year<=0)||(month<=0)||(day<=0)||(month>12)||(day>31)||(~(year==fix(year)))||(~(month==fix(month)))||(~(day==fix(day))))
valid=false;
return
end
%february has 29 days in leap year and 28 days in non leap year
if (month==2)
if((mod(year,4)==0 && mod(year,100)~=0)||(mod(year,400)==0))
if day<30
valid=true;
return
else
valid=false;
return
end
else
if day<29
valid=true;return
else
valid=false;return
end
end
%check whether the number of given days is within the limit of days that particular month has.
else
month_days=[31,28,31,30,31,30,31,31,30,31,30,31];
if day<=month_days(month)
valid=true;
return
else
valid=false;
return
end
end
end

Fazal Hussain
Fazal Hussain il 19 Gen 2022
Modificato: DGM il 21 Feb 2023
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

Erikc Anderson Cortez Benites
function valid = valid_date(year, month, day)
if isscalar(year) && isscalar(month) && isscalar(day)
if month < 1 || month > 12
valid = false;
else
if month == 2 && isleapyear(year)
valid = day <= 29 && day>0 ;
elseif sum(month == [1,3,5,7,8,10,12])
valid = day <= 31 && day>0;
else
valid = day <= 30 && day>0;
end
end
else
valid = false;
end
function re = isleapyear(year)
if mod(year,400) == 0
re = 1;
elseif (mod(year,4) == 0) && (mod(year,100)) ~= 0
re = 1;
else
re = 0;
end

Ravleen Kaur
Ravleen Kaur il 19 Mag 2022
function valid = valid_date(year,month,day)
if (isscalar(year) && (year>=1) && year==fix(year)) && (isscalar(month) && ((1<=month)&&(month<=12)) && (month==fix(month))) && (isscalar(day) && ((1<=day)) && (day==fix(day)))
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) && day<32
valid = true;
elseif ( month == 4 || month == 6 || month == 7 || month == 9 || month == 11) && day<31
valid = true;
else
valid = false;
end
if (month == 2)
if day<29
valid = true; return
elseif day<30 && rem(year,4)==0 && rem(year,100)~=0 || rem(year,400)==0
valid = true; return
else
valid = false; return
end
end
else
valid = false; return
end

David Goh
David Goh il 20 Giu 2022
function valid = valid_date(year,month,day)
if isscalar(year) == 1 && isscalar(month) == 1 && isscalar(day) == 1 && year > 0 && month > 0 && day > 0
if month <= 12
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)
if day <= 31
valid = true;
else
valid = false;
end
elseif month == 2
if (rem(year,4)==0 || rem(year,400)==0) && (rem(year,400)~=100 && rem(year,400)~=200 && rem(year,400)~=300)
if day <= 29
valid = true;
else
valid = false;
end
else
if day <= 28
valid = true;
else
valid = false;
end
end
else
if day <= 30
valid = true;
else
valid = false;
end
end
else
valid = false;
end
else
valid = false;
end

Muhammad
Muhammad il 25 Lug 2022
function valid =valid_date(year,month,day)
if isscalar(year)&&isscalar(month)&&isscalar(day)&& (isinteger((year/4)==0) || ~isinteger((year/400==0))) && ((month==1) || (month==3) || (month==5) || (month==7) ||(month==8) || (month==10 )|| (month==12 )) && (day>=1 && day<=31)
valid=true;
elseif isscalar(year)&&isscalar(month)&&isscalar(day)&& (isinteger((year/4)==0) || ~isinteger((year/400==0))) && ((month==4) || (month==6) || (month==9) || (month==11))&&(day>=1 && day<=30)
valid=true;
elseif isscalar(year)&&isscalar(month)&&isscalar(day)&& (mod(year,4)==0)&& mod(year,100)~=0 && month==2 && (day>=1 && day<=29)
valid=true;
elseif isscalar(year)&&isscalar(month)&&isscalar(day)&& (mod(year,400)==0) && (month==2) && (day>=1 && day<=29)
valid=true;
elseif isscalar(year)&&isscalar(month)&&isscalar(day)&& (mod(year,400)~=0) && month==2 &&(day>=1 && day<=28)
valid=true;
elseif isscalar(year)&&isscalar(month)&&isscalar(day)&& (mod(year,4)~=0) && month==2 &&(day>=1 && day<=28)
valid=true;
else
valid=false;
end
  2 Commenti
Walter Roberson
Walter Roberson il 25 Lug 2022
It is not efficient to keep checking isscalar()
I think you should check the documentation about the relative priority of the two short-circuit logic operators. I do not recommend chaining them together without using () to make the interpretation clear to people reading the code
Muhammad
Muhammad il 25 Lug 2022
Thanks for pointing that out. I'll definitely revisit the relative priority of the two short-circuit logic operators

Accedi per commentare.


ARYA
ARYA il 18 Ott 2022
function valid= valid_date(year,month,day)
flag=0;
if(month<=0||month>12||day<=0||day>31)
flag=0;
else
if(month==4||month==6||month==9||month==11)
if day<=30
flag=1;
else
flag=0;
end
elseif month==2
if (mod(year,4)==0&&mod(year,100)~=0)||(mod(year,400)==0)&& day<=29
flag=1;
elseif (day<=28)
flag=1;
else
flag=0;
end
else
if day<=31
flag=1;
else
flag=0;
end
end
end
if(~isscalar(year)||~isscalar(month)||~isscalar(day))
flag=0;
end
if(flag==0)
valid=false;
else
valid=true;
end

Paul
Paul il 17 Mag 2023
Modificato: DGM il 23 Ago 2023
function valid = valid_date(y,m,d);
if ~isscalar(y)||~isscalar(m)||~isscalar(d)||y~=fix(y)||m~=fix(m)||d~=fix(d);
valid = false;
else
if y > 0 && (m == 12 || m == 1 || m == 3 || m == 5|| m == 7 || m == 8 || m == 10) && d >= 1 && d <= 31;
valid = true;
elseif (m== 4 || m == 6 || m ==9 || m == 11) && d >=1 && d <= 30;
valid = true;
elseif m==2 && d>=1 && d<=28;
valid = true;
elseif ((mod(y,4)==0 && mod(y,100)~=0)||mod(y,400)==0) && m==2 && d>=1 && d<=29;
valid = true;
else
valid = false;
end
end
end
  1 Commento
DGM
DGM il 23 Ago 2023
This fails for negative years. When you have a control structure with a single output and you have multiple cases where the output is identical, that's a good sign that you need to simplify things. Similarly, see how many times you're checking that d>=1.
I can't fault you too much, since your example is at least relatively compact already, but it still squarely fits the theme of giant tangled salads of undocumented inline logic in nested control structures. It's easy to miss certain cases when you can't really even read the logic or understand how it's responding to the inputs. You can make it easier on yourself if you use logical variables to describe the aspects of the input, and then simply calculate the output based on a logical combination of those variables. That way you can easily see whether things are being evaluated correctly.

Accedi per commentare.


DGM
DGM il 23 Ago 2023
Modificato: DGM il 23 Ago 2023
Instead of a giant undocumented salad of inline logic, use logical variables to clearly describe the input conditions as they pertain to the relevant concepts.
function valid = valid_date(y,m,d)
% VALID = VALID_DATE(Y,M,D)
% Synopsis goes here blah blah blah
% basic input validation
scalarinput = isscalar(y) && isscalar(m) && isscalar(d);
integerinput = ~mod(y,1) && ~mod(m,1) && ~mod(d,1);
nonsenseinput = y<1 || m<1 || m>12 || d<1 || d>31;
acceptableinput = scalarinput && integerinput && ~nonsenseinput;
% three classes of month length
isleapyear = ~mod(y,4) && (mod(y,100) || ~mod(y,400));
validmonthA = ismember(m,[1 3 5 7 8 10 12]) && d<=31;
validmonthB = ismember(m,[4 6 9 11]) && d<=30;
validmonthC = m==2 && d<=(28 + isleapyear); % implicit casting of logicals to numeric!
% assemble the output based on those conditions
valid = acceptableinput && (validmonthA || validmonthB || validmonthC)
end
The variable names are self-explanatory, and tell you exactly what's being tested on each line. At a glance, you know that the output is only true when the given inputs are scalar, integer, within sensible ranges, and together describe one of three classes of month (31 days, 30 days, and February).
This example leans heavily on implicit casting behaviors in MATLAB. The use of comparision or negation operators will make sure the numeric output of mod() is always logical. Similarly, adding a logical to a numeric value treats the logical as either zero or one.
Could this be made more efficient using an if-else structure? Yes, though for scalar inputs, I doubt that the benefit of early returns are even measurable. The reason I did it this way is simply for emphasis.
Did I miss something? I don't know. I'm not the one taking the online course.

Community Treasure Hunt

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

Start Hunting!

Translated by