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.

145 visualizaciones (últimos 30 días)
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 comentarios
Rakeshwar Elango
Rakeshwar Elango el 28 de Jun. de 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!

Iniciar sesión para comentar.

Respuesta aceptada

James Tursa
James Tursa el 27 de Jun. de 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 comentarios
Karina Medina Barzola
Karina Medina Barzola el 8 de Jun. de 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 el 3 de Jul. de 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

Iniciar sesión para comentar.

Más respuestas (14)

Martín Avalos Postigo
Martín Avalos Postigo el 28 de Jun. de 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 comentarios
Alexandar
Alexandar el 29 de Jun. de 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 el 4 de Ag. de 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

Iniciar sesión para comentar.


Jatan Shah
Jatan Shah el 5 de Ag. de 2021
Editada: Walter Roberson el 4 de Ag. de 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 el 31 de Jul. de 2022
Editada: Abhinav Gadge el 31 de Jul. de 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 el 13 de Oct. de 2021
Editada: DGM el 21 de Feb. de 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 el 5 de Feb. de 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 el 25 de Ag. de 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 el 19 de En. de 2022
Editada: DGM el 21 de Feb. de 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
Erikc Anderson Cortez Benites el 3 de Abr. de 2022
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 el 19 de Mayo de 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 el 20 de Jun. de 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 el 25 de Jul. de 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 comentarios
Walter Roberson
Walter Roberson el 25 de Jul. de 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 el 25 de Jul. de 2022
Thanks for pointing that out. I'll definitely revisit the relative priority of the two short-circuit logic operators

Iniciar sesión para comentar.


ARYA
ARYA el 18 de Oct. de 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 el 17 de Mayo de 2023
Editada: DGM el 23 de Ag. de 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 comentario
DGM
DGM el 23 de Ag. de 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.

Iniciar sesión para comentar.


DGM
DGM el 23 de Ag. de 2023
Editada: DGM el 23 de Ag. de 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.

Categorías

Más información sobre Logical en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by