It's a strange situation. Check out this Coliru code:
#include <iostream>
#include <utility>
#include <ctime>
using namespace std;
#define SEGS 60
#define MINS 60
#define HOURS 24
int days(tm* date1, tm* date2)
{ return (mktime(date1) - mktime(date2)) / SEGS / MINS / HOURS; }
tm mkdate(int day, int mon, int year)
{
tm date = {0, 0, 0};
date.tm_mday = day;
date.tm_mon = mon - 1;
date.tm_year = year - 1900;
return date;
}
int main()
{
tm date1 = mkdate(31, 12, 2030);
tm date2 = mkdate(1, 1, 2000);
cout << days(&date1, &date2) << endl;
// 11322... OK 30 * 365 (1/1/2000 - 1/1/2030)
// + 8 (leap years) + 364 (from 1/1/2030 - 31/12/2030).
date1 = mkdate(31, 12, 2030);
date2 = mkdate(1, 1, 1930);
cout << days(&date1, &date2) << endl;
// 36889... OK; but in my machine, it returns 36888.
date1 = mkdate(31, 12, 1943);
date2 = mkdate(1, 1, 1943);
cout << days(&date1, &date2) << endl;
// 364... OK: but in my machine, it returns 363.
date1 = mkdate(30, 6, 1943);
date2 = mkdate(1, 6, 1943);
cout << days(&date1, &date2) << endl;
// 29... OK; but in my machine, it returns 28.
date1 = mkdate(27, 6, 1943);
date2 = mkdate(26, 6, 1943);
cout << days(&date1, &date2) << endl;
// 1... OK; but in my machine, it returns 0.
return 0;
}
The comments after each example are those from Coliru and my laptop. The Coliru outputs are corrects, but my machine is who prints the wrong numbers.
If you read the code, the difference between days is correctly computed (first example, from 1/1/2000 to 31/12/2030).
But if year 1943 is in the middle of a date interval, it seems a day is lost. Second example: 1/1/1930 - 31/12/2030.
After lots of tests, I found out the problem was in Juny/1943. Third example: 1/6/1943 - 30/6/1943, returning 28 days instead of 29.
More concretly, it seems 26th and 27th are the same day. Fourth example: 26/6/1943 - 27/6/1943, returning 0 days.
My machine is a Ubuntu 14.02.2 LTS with Linux 3.13.0-52-generic x86_64, using gcc (g++) 4.8.2.
What does the problem come from? Some kind of bug of GNU libc implementation?