Info
This question is locked. 編集または回答するには再度開いてください。
how can i solve this ,can anyone provide me with code? whats wrong with my code ?
5 ビュー (過去 30 日間)
古いコメントを表示
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 件のコメント
Huseyn Mammadli
2020 年 7 月 27 日
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
2020 年 7 月 29 日
編集済み: Jan
2020 年 7 月 29 日
@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:
- ((mod(year,100)==0) && (mod(year,400)~=0))
- (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.
回答 (19 件)
Jan
2019 年 3 月 30 日
編集済み: Jan
2019 年 9 月 6 日
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 件のコメント
Krashank Kulshrestha
2020 年 5 月 15 日
編集済み: Krashank Kulshrestha
2020 年 5 月 15 日
@jan ur 1st code is way better than elseif one i tried previously. Thanks.
Oleksandr Koreiba
2019 年 3 月 30 日
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 件のコメント
Walter Roberson
2020 年 5 月 12 日
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)
Jan
2019 年 3 月 28 日
編集済み: Jan
2019 年 3 月 28 日
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 件のコメント
Parth Patel
2019 年 6 月 1 日
編集済み: Parth Patel
2019 年 6 月 1 日
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 件のコメント
Walter Roberson
2019 年 6 月 1 日
(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 ?
Aditi Sinha
2019 年 6 月 17 日
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 件のコメント
Rik
2020 年 5 月 13 日
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
Roshan Singh
2019 年 8 月 21 日
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 件のコメント
Guillaume
2019 年 8 月 21 日
編集済み: Guillaume
2019 年 11 月 20 日
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?
Doga Savas
2019 年 8 月 23 日
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 件のコメント
Chech Joseph
2019 年 9 月 6 日
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
VIKAS JAIN
2019 年 9 月 14 日
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
0 件のコメント
Marwan Hammad
2019 年 11 月 19 日
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 件のコメント
Guillaume
2019 年 11 月 20 日
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
2019 年 11 月 20 日
編集済み: Rik
2019 年 11 月 20 日
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.
Yefferson Rodríguez
2019 年 11 月 20 日
編集済み: Yefferson Rodríguez
2019 年 11 月 20 日
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 件のコメント
Jan
2019 年 11 月 20 日
編集済み: Jan
2019 年 11 月 20 日
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.
Sandesh V
2020 年 4 月 15 日
%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 件のコメント
Rik
2020 年 4 月 15 日
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
2020 年 4 月 15 日
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.
SWAROOPA SHIGLI
2020 年 4 月 19 日
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 件のコメント
Rik
2020 年 4 月 19 日
There are two things wrong with this post:
- it is not an answer, but a question
- 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.
Fazlul Haque
2020 年 5 月 12 日
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?![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/292572/image.png)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/292572/image.png)
3 件のコメント
Fazlul Haque
2020 年 5 月 12 日
thanks brother, I get it now. I should've put the error check at the beginning
Hari Kiran Tirumaladasu
2020 年 5 月 13 日
編集済み: Hari Kiran Tirumaladasu
2020 年 5 月 15 日
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
2 件のコメント
Walter Roberson
2020 年 5 月 15 日
In your first if you test d>0 . Why do you re-test that in your second if ?
Hari Kiran Tirumaladasu
2020 年 5 月 15 日
編集済み: Hari Kiran Tirumaladasu
2020 年 5 月 15 日
Hi Walter, yeah, that wasn't necessary. I edited the code. Thanks!
Sumit Kumar Sharma
2020 年 5 月 24 日
編集済み: Sumit Kumar Sharma
2020 年 5 月 24 日
%% 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
0 件のコメント
Eshwar Raja Sayinathababu
2020 年 7 月 30 日
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 件のコメント
Rik
2020 年 7 月 30 日
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
Divya Prasad Singhdev
2020 年 8 月 17 日
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 件のコメント
Jan
2020 年 8 月 18 日
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
Dwight Celis
2020 年 9 月 2 日
編集済み: Dwight Celis
2020 年 9 月 2 日
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 件のコメント
Jan
2020 年 9 月 7 日
編集済み: Jan
2020 年 9 月 7 日
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.
This question is locked.
参考
カテゴリ
Help Center および File Exchange で Dates and Time についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!