2
\$\begingroup\$

I'm currently working on writing a date checker function in C and wondering how it can be improved upon.

Q: Write a function that is passed a month, day, and year and will determine if that date is valid. You can assume each parameter is passed in as an integer. Remember to check for leap year.

I currently have this and want to see if there are any beginner mistakes, if pointers could improve efficiency or redundancies in my code.

#include <stdio.h>
#include <stdbool.h>
bool is_valid_date(int month,int day ,int year) {
    //Validate year
    int days_on_month[]={31,28,31,30,31,30,31,31,30,31,30};
    if(year<0||year>2017) {
        //year not valid , stop validation , date is invalid
        return false;
    }
    bool isLeapYear;
    //Check for leap year , every 4 years there is a leap year
    if(year%4==0) {
        //if year is evenly divisble by 100 it must also be by 400
        if(year%100==0) {
            if(year%400==0) {
                isLeapYear=true;
            }else{
                isLeapYear=false;
            }
        }else{
            isLeapYear=true;
        }
    }
    //Validate months;
    if(month<1||month>12) {
        // not valid , stop validation , date is invalid
        return false;
    }
    //validate day
    if(month!=2) {
        //Valid Date
        if(day>=1&&day<=days_on_month[month-1]){return true;}
    }
    //February (changes no of days on leap year)
    else
    {
        if(isLeapYear) {
            if(day>=1&&day<=29){return true;}
        }else{
        if(day>=1&&day<=28){return false;}
        }
    }
    return false;
}

// test if function works
int main(void) {
    int day = 28;
    int month = 12;
    int year = 2012;
    printf("Is it true? Yes = 1 No = 0! = %d\n", is_valid_date(day, month, year));
    return 0;
}
\$\endgroup\$
1
  • \$\begingroup\$ You validate according to the Gregorian calendar. The first full year that calendar was in force for was 1583. No successor to the Gregorian calendar has been announced. So the year validity test should be year>=1583. If you knew the country the date applies to you could refine the validity test to when Gregorian was introduced in that country. \$\endgroup\$ – Gerard Ashton Apr 2 '17 at 12:42
2
\$\begingroup\$

Some quick formatting tips:

You use whitespace sparingly. In the example code, there is a lot of room for more whitespace that makes the code more readable. Something like:

if (year % 400 == 0) {
    isLeapYear = true;
}

It makes the code more easier to read.

Also, and this is not a recommendation but just an option you may want to consider, but you can move the if-else to a new line. I've always found that easier to read, and I've noticed that some (not all) teachers of mine tend to find that good formatting.

So for example:

if(year%400==0) {
    isLeapYear=true;
}else{
    isLeapYear=false;
}

This code can be rewritten as:

if(year%400==0) {
    isLeapYear=true;
}
else{
    isLeapYear=false;
}

**As an aside, upon receiving further advice from co-users on CodeReview in the comments, it is better to use curly braces, even if they are solely for one command in an if-statement, as it will help in detecting the scope of the if-statement with more ease.

\$\endgroup\$
3
  • 2
    \$\begingroup\$ Is this a C language thing? I usually hear people say to include curleys always to avoid mistakes. \$\endgroup\$ – Josh Apr 1 '17 at 2:44
  • \$\begingroup\$ @a That's why always using curleys is recommended. I didn't downvote you. \$\endgroup\$ – Josh Apr 2 '17 at 10:38
  • \$\begingroup\$ @Josh I always thought the less the better. Thanks :) \$\endgroup\$ – BusyProgrammer Apr 2 '17 at 11:19
0
\$\begingroup\$

You could format things nicely, or at least consistently.

Hardcoding in the current year is a bad idea.

if (year % 400 == 0) {
    isLeapYear = true;
} else if (year % 100 == 0) {
    isLeapYear = false;
} else if (year % 4 == 0) {
    isLeapYear = true;
}

You could put a day < 1 check once, before the other day checks.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.