Valid_date function

5 ビュー (過去 30 日間)
Denise Gobbo
Denise Gobbo 2020 年 5 月 18 日
コメント済み: Rik 2021 年 9 月 22 日
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 件のコメント
the cyclist
the cyclist 2020 年 5 月 18 日
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 2020 年 5 月 18 日
編集済み: Adam Danz 2020 年 5 月 18 日
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

サインインしてコメントする。

回答 (6 件)

Thyagharajan K K
Thyagharajan K K 2020 年 6 月 2 日
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 件のコメント
Walter Roberson
Walter Roberson 2021 年 3 月 21 日
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

サインインしてコメントする。


the cyclist
the cyclist 2020 年 5 月 18 日
編集済み: the cyclist 2020 年 5 月 18 日
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 2020 年 5 月 18 日
"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 2020 年 9 月 6 日
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 件のコメント
Rik
Rik 2020 年 9 月 6 日
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 2021 年 3 月 21 日
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

サインインしてコメントする。


Ahmed Saleh
Ahmed Saleh 2021 年 3 月 21 日
編集済み: Ahmed Saleh 2021 年 3 月 21 日
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 件のコメント
Walter Roberson
Walter Roberson 2021 年 3 月 21 日
Rik, please leave this one, as my unit tests are instructive.
Rik
Rik 2021 年 3 月 21 日
@Walter Roberson I agree, and have consequently remove the flag.

サインインしてコメントする。


Kabir Puri
Kabir Puri 2021 年 9 月 22 日
% 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 件のコメント
Rik
Rik 2021 年 9 月 22 日
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

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeDates and Time についてさらに検索

タグ

Community Treasure Hunt

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

Start Hunting!

Translated by