The standard C library features for dates and times are pretty poor and loaded with caveats and limitations. If at all possible, use a library such as Gnome Lib, which provides GDate and many useful date and time functions . This includes g_date_days_between() to get the number of days between two dates.
The rest of this answer will be limited to the standard C library, but if you don't need to limit yourself to the standard, don't torture yourself. Dates are surprisingly hard.
Is there any data type for dates?
struct tm . Just leave the hour, minutes and seconds at 0.
The easiest way to ensure that all struct tm fields are populated correctly is to use strptime .
struct tm date; strptime( "2017-03-21", "%F", &date ); puts( asctime(&date) );
But this is a great way to store dates. It turns out that it is better to use Julian days (see below).
In C, we deal with time, are there any dates?
If you mean time_t , this also applies to dates. This is the number of seconds since the "era" , which is 1970-01-01 00:00:00 UTC on POSIX systems, but not necessarily others. Unfortunately, its safe range is only from 1970 to 2037, although any recent version of the operating system will greatly expand this range.
How can I calculate the difference between two dates?
Depends on what you want. If you want the number of seconds, you can convert struct tm to time_t using mktime and then use difftime , but this is limited by the valid time_t range from 1970-2037.
int main() { struct tm date1, date2; strptime( "2017-03-21", "%F", &date1 ); strptime( "2018-01-20", "%F", &date2 ); printf("%.0lf\n", difftime(mktime(&date1), mktime(&date2))); }
If you want the number of days, you convert the dates to Julian days , the number of days from November 24, 4714 BC and subtract. Although this may seem ridiculous, this relatively simple formula takes advantage of calendar cycles and uses only mathematical math.
// The formulas for a and m can be distilled down to these tables. int Julian_A[12] = { 1, 1, 0 }; int Julian_M[12] = { 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; int julian_day( struct tm *date ) { int a = Julian_A[date->tm_mon]; int m = Julian_M[date->tm_mon]; int y = date->tm_year + 1900 + 4800 - a; return date->tm_mday + ((153*m + 2) / 5) + 365*y + y/4 - y/100 + y/400 - 32045; } int main() { struct tm date1, date2; strptime( "2017-03-21", "%F", &date1 ); strptime( "2018-01-20", "%F", &date2 ); // 305 days printf("%d days\n", julian_day(&date2) - julian_day(&date1)); }
There are other simple formulas for converting between yuan dates and calendar dates.
Obtaining differences by year, month, and day is difficult because the number of days per month varies depending on the month and year and because it needs to be normalized. For example, you would not say 2 years, -1 month, 2 days. You say 1 year, 11 months, 29 days (or maybe 28, depends on the month). For this reason, do the math date on Julian Days whenever possible.
To get an idea of what is involved, PHP implements this as date_diff . See the amount of C code required .