Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing 2 dates in c++

Tags:

c++

I was wondering if there is any relatively easy and short date comparison functions in C++. My dates are of type char*, and have the following format: DD\MM\YYYY

Thanks.

like image 730
David Faizulaev Avatar asked Dec 09 '12 13:12

David Faizulaev


2 Answers

Parsing is usually done on streams, not strings, but you can use a stringstream.

std::istringstream date_s( "04\\10\\1984" );
struct tm date_c;
date_s >> std::get_time( &date_c, "%d\\%m\\%Y" );
std::time_t seconds = std::mktime( & date_c );

Now you can compare seconds using < to determine which was earlier.

Note, std::get_time is new in C++11. It is defined in terms of strptime, which is from POSIX but not part of the C99 standard. You can use strptime if a C++11 library is not available. If you're brave, you can also use the std::time_get facet… it's ugly though.

If you don't want to know anything about the dates other than which is earlier, you can use std::lexicographical_compare. It would be a one-liner but the function name is so long.

// return true if the date string at lhs is earlier than rhs
bool date_less_ddmmyyyy( char const *lhs, char const *rhs ) {
    // compare year
    if ( std::lexicographical_compare( lhs + 6, lhs + 10, rhs + 6, rhs + 10 ) )
        return true;
    if ( ! std::equal( lhs + 6, lhs + 10, rhs + 6 ) )
        return false;
    // if years equal, compare month
    if ( std::lexicographical_compare( lhs + 3, lhs + 5, rhs + 3, rhs + 5 ) )
        return true;
    if ( ! std::equal( lhs + 3, lhs + 5, rhs + 3 ) )
        return false;
    // if months equal, compare days
    return std::lexicographical_compare( lhs, lhs + 2, rhs, rhs+2 );
}

See also how to convert datetime to unix timestamp in c? .

like image 167
Potatoswatter Avatar answered Sep 21 '22 04:09

Potatoswatter


If this is really a fixed format, you can do it with simple C string comparison

int date_cmp(const char *d1, const char *d2)
{
    int rc;
    // compare years
    rc = strncmp(d1 + 6, d2 + 6, 4);
    if (rc != 0)
        return rc;

    // compare months
    rc = strncmp(d1 + 3, d2 + 3, 2);
    if (rc != 0)
        return rc;

    // compare days
    return strncmp(d1, d2, 2);
}

This works like strncmp. It returns a value less than 0, if d1 is earlier than d2, 0 if both are the same date, and a value greater than 0, if d1 is later than d2.

Another approach would be to convert it with strptime and mktime to time_t and compare these with difftime

struct tm tm;
time_t t1, t2;
strptime(d1, "%d\\%m\\%Y", &tm);
t1 = mktime(&tm);
// do the same with d2
double diff = difftime(t1, t2);
like image 28
Olaf Dietsche Avatar answered Sep 18 '22 04:09

Olaf Dietsche