Search code examples
c#classconventionsaccessormutators

Proper way to set up Date class with validation


I have a class as follows:

class Date
{
    // Field variables
    private int day;
    private int month;
    private int year;

    // Default constructor
    public Date()
    {
        year = 2015;
        day = 0;
        month = 0;
    }

    // Overloaded constructor
    public Date(int _day, int _month, int _year)
    {
        setDay(_day);
        setMonth(_month);
        setYear(_year);
    }

    // Accessors
    public int getDay()
    {
        return day;
    }

    public int getMonth()
    {
        return month;
    }

    public int getYear()
    {
        return year;
    }

    // Mutators
    public void setMonth(int _month)
    {
        if (_month > 0 && _month <= 12)
        {
            month = _month;
        }
    }

    public void setYear(int _year)
    {
        if (_year >= 1700 && _year <= 2015)
        {
            year = _year;
        }
    }

    public void setDay(int _day)
    {
        if (_day > 0 && _day <= DateTime.DaysInMonth(year, month))
        {
            day = _day;
        }
    }

The part that is not working is validating my day inside the setDay() method. DateTime.DaysInMonth(year, month) (The method checks how many days are in a particular month in a given year to account for leap years and February) is calling from the default constructor value of 0 for months before the users/application data passes through to assign it something between 1 and 12. I can not use DateTime to validate the whole thing because the application is set up so users can enter in 0 values for day or month, which in turn doesn't print out a day or month in the final format.

One suggestion was to make my setters private, and make one public setDate method for users that will allow them to set the day, month, and year in any order... But I can't seem to implement that correctly:

public void setDate(int _day, int _month, int _year)
{
    day = _day;
    month = _month;
    year = _year;
}

because this just skips my validation in my private setters.

I can honestly find plenty of ways to get this to work with non-convetional methods, but I just need help cleaning it all up to fit proper class design convention..


Solution

  • You are calling setDay (in your Overloaded constructor) before you call setMonth and setYear. Since you need year and month to use DayaInMonth, you need to call those setters in your constructor first.