If condition - Date older than...

Hello,
recently I wanted to add some warning message when imputing date (DD.MM.YY) is older than some pre-set value.

1
2
3
4
5
day     DD
month   MM
year    YY

pre-set date    21.7.2014


The condition I have is
1
2
3
4
5
if((YY <  2014) ||
   (YY == 2014  && MM <  7) || 
   (YY == 2014  && MM == 7  && DD < 21){
//warning message
}


Now I was just curious if there is easier way to implement this condition. To use less code. When I extend the condition to hour:minute:second the code would only grow fast.

Also I know I should not use "magic numbers" but it is only for the demonstration.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
std::tuple<int, int, int> date1 {/*year*/, /*month*/, /*day*/};
std::tuple<int, int, double> time1 {/*hour*/, /*minute*/, /*second*/};

std::tuple<int, int, int> date2 {/*year, /*month*/, /*day*/};
std::tuple<int, int, double> time2 {/*hour, /*minute*/, /*second*/};

if(date1 < date2)
{
    //...
}

if(time1 < time2)
{
    //...
}

if(std::tie(date1, time1) < std::tie(date2, time2))
{
    //...
}
http://www.cplusplus.com/reference/tuple/
http://en.cppreference.com/w/cpp/utility/tuple
Last edited on
I hate cramming multiple things into an if condition with &&s and ||s. It typically makes the code messy and hard to follow.

I suggest writing a function which compares two dates, then you can just call it whenever you need to do this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// give 2 dates.. 'a' and 'b'.
//   returns < 0 if 'a' is before 'b'...
//   returns > 0 if 'a' is after 'b'...
//   returns 0 if 'a' == 'b'

int compareDates( int YYa, int MMa, int DDa,
                  int YYb, int MMb, int DDb )
{
    if(YYa < YYb)       return -1;
    if(YYa > YYb)       return  1;
    if(MMa < MMb)       return -1;
    if(MMa > MMb)       return  1;
    if(DDa < DDb)       return -1;
    if(DDa > DDb)       return  1;
    
    return 0;
}

///////////////////////////////
// To use:

if( compareDates(YY,MM,DD,2014,7,21) < 0 )
{
    // warning message
}



Though that is still a little clunky. Here, you could use a struct to hold the Date/Time, then tweak the function to take two DateTime objects rather than passing the year/month/date to the function individually:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
struct DateTime
{
    int year;
    int month;
    int date;

    int compare(const DateTime& d) const
    {
        if(year < d.year)       return -1;
        if(year > d.year)       return  1;
        if(month < d.month)     return -1;
        if(month > d.month)     return  1;
        if(date < d.date)       return -1;
        if(date > d.date)       return  1;
        
        return 0;
    }
};

/////////////////////////////////
// To use:
DateTime user = getDateFromUser();

DateTime fixed = {2014,7,21};

if(fixed.compare(user) < 0)
{
    // warn
}



And... if you want to get REALLY fancy... you can overload ctors and comparison operators so that doing this is even more intuitive:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
struct DateTime
{
    int year;
    int month;
    int date;

    DateTime(int yy=0, mm=0, dd=0)
       : year(yy)
       , month(mm)
       , date(dd)
    {}
    
    int compare(const DateTime& d) const
    {
        if(year < d.year)       return -1;
        if(year > d.year)       return  1;
        if(month < d.month)     return -1;
        if(month > d.month)     return  1;
        if(date < d.date)       return -1;
        if(date > d.date)       return  1;
        
        return 0;
    }
    
    bool operator <  (const DateTime& rhs) const   { return compare(rhs) <  0;  }
    bool operator <= (const DateTime& rhs) const   { return compare(rhs) <= 0;  }
    bool operator >  (const DateTime& rhs) const   { return compare(rhs) >  0;  }
    bool operator >= (const DateTime& rhs) const   { return compare(rhs) >= 0;  }
    bool operator == (const DateTime& rhs) const   { return compare(rhs) == 0;  }
    bool operator != (const DateTime& rhs) const   { return compare(rhs) != 0;  }
};


/////////////////////////////////
// To use:
DateTime user = getDateFromUser();

if(user < DateTime(2014,7,21))
{
    // warn
}




EDIT: LB's suggestion is much simpler. Hah.
Last edited on
Thanks,
the tuple solution works great.

Disch: Actually I like the first solution. With the use of multiple return statements. I don't know why I didn't think of it myself.
Because when I compare (MMa < MMb) then there is implitcitly (YYa == YYb).
Topic archived. No new replies allowed.