ChangeMyName
ChangeMyName

Reputation: 7428

Solution doesn't work for number of days between two dates

I know this question has been asked a few times, and I'm asking again because I've got issues with existing solutions on SO.

My goal is to find number of days between 1900-01-01 and a given date. The date will be in the format as yyyy-mm-dd and the type is std::string.

The solution I've followed is https://stackoverflow.com/a/14219008/2633803

And below is my version:

std::string numberOfDaysSince1900v2(std::string aDate)
{
    string year, month, day;
    year = aDate.substr(0, 4);
    month = aDate.substr(5, 2);
    day = aDate.substr(8, 2);

    struct std::tm a = { 0,0,0,1,1,100 }; /* Jan 1, 2000 */
    struct std::tm b = { 0,0,0,std::stoi(day),std::stoi(month),std::stoi(year) - 1900 };

    std::time_t x = std::mktime(&a);
    std::time_t y = std::mktime(&b);

    double difference;
    if (x != (std::time_t)(-1) && y != (std::time_t)(-1))
    {
        difference = std::difftime(y, x) / (60 * 60 * 24) + 36526; //36526 is number of days between 1900-01-01 and 2000-01-01
    }

    return std::to_string(difference);
}

It worked fine until the given date comes to 2019-01-29 and 2019-02-01. In both cases, the output is 43494. And for the whole Feb, the output is 3 days less than expected. Then, when it comes to March 2019, the output is back to normal again. Another case is 2019-09-03, the output is 43710, whilst the expected output is 43711.

Why would this happen to these specific dates? I ran the solution step by step and closely watched the variables in the memory but couldn't explain it.

Any suggestion is appreciated. Thanks.

Upvotes: 0

Views: 111

Answers (1)

john
john

Reputation: 88092

The month should be represented as an integer between 0 and 11, not 1 and 12.

So

struct std::tm a = { 0,0,0,1,0,100 }; /* Jan 1, 2000 */
struct std::tm b = { 0,0,0,std::stoi(day),std::stoi(month)-1,std::stoi(year) - 1900 };

I would say there are other problems with your code. You cannot reliably initialise a tm like that (the order of fields within the struct is not guaranteed). Neither does difftime necessarily return a number of seconds (which you are assuming).

Upvotes: 3

Related Questions