Valid_date function

13 Ansichten (letzte 30 Tage)
Denise Gobbo
Denise Gobbo am 18 Mai 2020
Kommentiert: Rik am 22 Sep. 2021
I am having some troubles with the logical operators in "day". What could I do to solve it?
function valid = valid_date(year, month, day)
if ~isinteger(year)
if ~isinteger(month)
if ~isinteger(day)
if ~isscalar(year)
if ~isscalar(month)
if ~isscalar(day)
valid = false;
elseif month == 2
if ((rem(year,4)== 0) && (rem(year,100) ~= 0)) || (rem(year,400)==0)
(1 <= day) && (day <= 28);
valid = true;
else
(1 <= day) && (day <= 29);
valid = true;
end
elseif month == 1 || 3 || 5 || 7 || 8 || 10 || 12
(1 <= day)&(day <= 31);
valid = true;
elseif month == 4 || 6 || 9 || 11
1 <= day <= 30;
valid = true;
else
valid = false;
end
end
end
end
end
end
end
  4 Kommentare
the cyclist
the cyclist am 18 Mai 2020
Personal preference, perhaps, but I actually like keeping the indenting of the isinteger if statements. To my mind, they are a logical grouping and easier to interpret as that group if they appear at the same level if indentation. Similarly, I usually write
for x = 1:10
for y = 1:10
% do something in x-y space
end
end
because x and y are "on equal footing" as spatial coordinates.
Of course, the point is moot because I'm pretty certain that all those if statements are the not the logic that OP is intending to implement.
Adam Danz
Adam Danz am 18 Mai 2020
Bearbeitet: Adam Danz am 18 Mai 2020
Thanks for sharing that perspective, @the cyclist . I can see how that grouping can be helpful when the conditional statements are fully nested. If there are additional lines of code outside of the nested structure, I bet it would become difficult to read, though.
eg
for x = 1:10
for y = 1:10
for z = 1:10
% do something in x-y-z space
end
% some code here
end
% some code here
end

Melden Sie sich an, um zu kommentieren.

Antworten (6)

Thyagharajan K K
Thyagharajan K K am 2 Jun. 2020
valid = valid_date(2019, 12, 1)
function valid = valid_date(year,month,day)
%check if either year, month, day is not a scalar
if ~isscalar(year) || ~isscalar(month) || ~isscalar(day)
valid =false
return
end
%check if either year, month, day is 0 or negative. check if month is >12
if year<=0 || month>12 || month <=0 ||day<=0
valid =false
return
end
A = [1 3 5 7 8 10 12]; %months with 31 days
B = [4 6 9 11]; %months with 30days
month_31d = sum(ismember(A,month));
%ismember() returns a logical array where element found will be marked as 1 & other positions will be 0
%so only one element in this logical array will be 1 and other elements will be 0 if month falls in this
%month_31d category. Hence sum will be 1 i.e month_31d will be true.
month_30d = sum(ismember(B,month)); %same as above to check whether month falls in the category month_30d
%check for leap year
if rem(year,400)==0
leap_year = true;
elseif rem(year,4)==0 && rem(year,100) ~=0
leap_year =true;
else
leap_year = false;
end
%Check the days for the conditions 28,29,30,31
if month_31d && day>31
valid = false;
elseif month_30d && day>30
valid = false;
elseif (leap_year && month==2 && day>29)||(~leap_year&&month==2&&day>28)
valid = false;
else
valid =true;
end
end
  1 Kommentar
Walter Roberson
Walter Roberson am 21 Mär. 2021
Needs improvement.
try valid_date(nan,nan,nan), catch ME; disp(ME.message); end
ans = logical
1
try valid_date(1234.56,1,7), catch ME; disp(ME.message); end
ans = logical
1
try valid_date(1234,1.23,7), catch ME; disp(ME.message); end
ans = logical
1
try valid_date(1234,1,7.89), catch ME; disp(ME.message); end
ans = logical
1
try valid_date(2021,2,7+3i), catch ME; disp(ME.message); end
ans = logical
1
try valid_date(inf,2,29), catch ME; disp(ME.message); end
ans = logical
0
function valid = valid_date(year,month,day)
%check if either year, month, day is not a scalar
if ~isscalar(year) || ~isscalar(month) || ~isscalar(day)
valid =false
return
end
%check if either year, month, day is 0 or negative. check if month is >12
if year<=0 || month>12 || month <=0 ||day<=0
valid =false
return
end
A = [1 3 5 7 8 10 12]; %months with 31 days
B = [4 6 9 11]; %months with 30days
month_31d = sum(ismember(A,month));
%ismember() returns a logical array where element found will be marked as 1 & other positions will be 0
%so only one element in this logical array will be 1 and other elements will be 0 if month falls in this
%month_31d category. Hence sum will be 1 i.e month_31d will be true.
month_30d = sum(ismember(B,month)); %same as above to check whether month falls in the category month_30d
%check for leap year
if rem(year,400)==0
leap_year = true;
elseif rem(year,4)==0 && rem(year,100) ~=0
leap_year =true;
else
leap_year = false;
end
%Check the days for the conditions 28,29,30,31
if month_31d && day>31
valid = false;
elseif month_30d && day>30
valid = false;
elseif (leap_year && month==2 && day>29)||(~leap_year&&month==2&&day>28)
valid = false;
else
valid =true;
end
end

Melden Sie sich an, um zu kommentieren.


the cyclist
the cyclist am 18 Mai 2020
Bearbeitet: the cyclist am 18 Mai 2020
This syntax
1 <= day <= 30
does not check if day is between 1 and 30. You need to do that as two separate checks:
(1 <= day) & (day <= 30);
as you did in the other sections.
Also, for this chain of if statements:
if ~isinteger(year)
if ~isinteger(month)
if ~isinteger(day)
if ~isscalar(year)
if ~isscalar(month)
if ~isscalar(day)
I think you probably actually want a single if statement:
if ~isinteger(year) || ~isinteger(month) || ~isinteger(day) ... and so on
valid = false
end
The way your code is written, if year is an integer, then your function will simply exit, never having evaluated the output variable valid.

Adam Danz
Adam Danz am 18 Mai 2020
"I am having some troubles with the logical operators in "day"."
That doesn't give us enough background infomation to know what the problem is. Does that mean you're getting an error? The wrong value? The wrong class? An empty output? Is it causing your compute to explode? etc. We can help you more quickly if you tell us what the problem is.
That being said, there are lots of problems with this code and the the problems I immediately see have nothing to do with the 'day' variable.
For example, let's say Year is an interger but Month is not. Read through your code and estimate what would happen. Hint: no output at all.
If you want to return a value of false when the inputs aren't in the correct format,
if ~isinteger(year) || ~isinteger(month) || . . . || ~isscalar(month)
valid = false;
else
% [main part of your code]
end
If you want to determine if the month is 1,3,5,7,8,10 or 12,
if ismember(month, [1 3 5. . .]);
If you want to define values based on differet sets of months,
switch month
case 2
% your code
case {1 3 5 . . .}
% your code
case {4 6 9 . . .}
% your code
otherwise
error('Month did not meet any of the case requrements.')
end

Himanshi Singh
Himanshi Singh am 6 Sep. 2020
function valid = valid_date (year, month, date)
if ~(isscalar(year) && isscalar(month) && isscalar(date))
valid=false;
elseif year ~= fix(year) || year<1
valid=false;
elseif month ~= fix(month) || month<1 || month>12
valid=false;
elseif date ~= fix(date) || date<1 || date>31
valid=false;
elseif (month == 4 || month == 6 || month == 9 || month == 11) && date>30
valid = false;
elseif month == 2 && ((year/4 ~= fix(year/4) || (year/100 == fix(year/100) && year/400 ~= fix(year/400))) || date>29)&&date>28
valid = false;
else
valid = true;
end
  2 Kommentare
Rik
Rik am 6 Sep. 2020
Why did you post a complete solution to a homework question without any explanation? Now your answer is only useful for people wanting to cheat.
Walter Roberson
Walter Roberson am 21 Mär. 2021
Better than some, but could still use improvement.
try valid_date(nan,nan,nan), catch ME; disp(ME.message); end
ans = logical
0
try valid_date(1234.56,1,7), catch ME; disp(ME.message); end
ans = logical
0
try valid_date(1234,1.23,7), catch ME; disp(ME.message); end
ans = logical
0
try valid_date(1234,1,7.89), catch ME; disp(ME.message); end
ans = logical
0
try valid_date(2021,2,7+3i), catch ME; disp(ME.message); end
ans = logical
1
try valid_date(inf,2,29), catch ME; disp(ME.message); end
ans = logical
1
function valid = valid_date (year, month, date)
if ~(isscalar(year) && isscalar(month) && isscalar(date))
valid=false;
elseif year ~= fix(year) || year<1
valid=false;
elseif month ~= fix(month) || month<1 || month>12
valid=false;
elseif date ~= fix(date) || date<1 || date>31
valid=false;
elseif (month == 4 || month == 6 || month == 9 || month == 11) && date>30
valid = false;
elseif month == 2 && ((year/4 ~= fix(year/4) || (year/100 == fix(year/100) && year/400 ~= fix(year/400))) || date>29)&&date>28
valid = false;
else
valid = true;
end
end

Melden Sie sich an, um zu kommentieren.


Ahmed Saleh
Ahmed Saleh am 21 Mär. 2021
Bearbeitet: Ahmed Saleh am 21 Mär. 2021
function valid = valid_date(year,month,day)
y= year;
m=month;
d=day;
days_1=[31 28 31 30 31 30 31 31 30 31 30 31];
if (fix(y/4)==(y/4) && fix(y/100)~=(y/100)) || (fix(y/4)==(y/4) && fix(y/100)==(y/100) && fix(y/400)==(y/400))
days_1(2)=29;
end
if ~isscalar(y) || ~isscalar(m) || ~isscalar(d)
valid= false;
return
elseif y<=0 || m<=0 || d<=0 || m>12 || d>31
valid = false;
return
elseif days_1(m)<d
valid=false;
return
else
valid=true;
end
  4 Kommentare
Walter Roberson
Walter Roberson am 21 Mär. 2021
Rik, please leave this one, as my unit tests are instructive.
Rik
Rik am 21 Mär. 2021
@Walter Roberson I agree, and have consequently remove the flag.

Melden Sie sich an, um zu kommentieren.


Kabir Puri
Kabir Puri am 22 Sep. 2021
% this is my answer
function valid = valid_date(year, month, day);
if day<=0 || month <=0 || ~isscalar(year) ||~isscalar(month)||~isscalar(day)||mod(day,1)~=0 ||mod(month,1)~=0||mod(year,1)~=0;
valid = false;
elseif month>12;
valid = false;
elseif (month==1 || month==3|| month==5||month==7||month==8||month==10||month==12)&& day>31;
valid = false;
elseif (month==4||month==6||month==9||month==11)&&day>30;
valid = false;
elseif (month == 2 && ((mod(year,4)==0 && mod(year,100)~=0)||(mod(year,400)==0)) ) && day>29
valid =false;
elseif month== 2 && ~((mod(year,4)==0 && mod(year,100)~=0)||(mod(year,400)==0)) && day>28;
valid= false;
else;
valid =true;
end;
  1 Kommentar
Rik
Rik am 22 Sep. 2021
I added an extra end to your function, but after that it passes almost all the unit tests by Walter (you only missed the complex-valued input) and you missed my addition (different datatype).
So now only the question remains why you decided to post this solution to a homework question?
try valid_date(nan,nan,nan), catch ME; disp(ME.message); end
ans = logical
0
try valid_date(1234.56,1,7), catch ME; disp(ME.message); end
ans = logical
0
try valid_date(1234,1.23,7), catch ME; disp(ME.message); end
ans = logical
0
try valid_date(1234,1,7.89), catch ME; disp(ME.message); end
ans = logical
0
try valid_date(2021,2,7+3i), catch ME; disp(ME.message); end
Arguments must be real.
try valid_date(inf,2,29), catch ME; disp(ME.message); end
ans = logical
0
try valid_date(struct,2,28), catch ME; disp(ME.message); end
Undefined function 'mod' for input arguments of type 'struct'.
function valid = valid_date(year, month, day);
if day<=0 || month <=0 || ~isscalar(year) ||~isscalar(month)||~isscalar(day)||mod(day,1)~=0 ||mod(month,1)~=0||mod(year,1)~=0;
valid = false;
elseif month>12
valid = false;
elseif (month==1 || month==3|| month==5||month==7||month==8||month==10||month==12)&& day>31
valid = false;
elseif (month==4||month==6||month==9||month==11)&&day>30
valid = false;
elseif (month == 2 && ((mod(year,4)==0 && mod(year,100)~=0)||(mod(year,400)==0)) ) && day>29
valid =false;
elseif month== 2 && ~((mod(year,4)==0 && mod(year,100)~=0)||(mod(year,400)==0)) && day>28
valid= false;
else
valid =true;
end
end

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Dates and Time finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by