I'm a beginner in C.
The standard C library options 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 numerous useful date and time functions. This includes g_date_days_between()
for getting the number of days between two dates.
The rest of this answer will restrict itself to the standard C library, but if you don't have to limit yourself to the standard, don't torture yourself. Dates are surprisingly hard.
Is there any datatype for dates?
struct tm
will serve. Just leave the hour, minutes, and seconds at 0.
Simplest way to ensure all the fields of struct tm
are properly populated is to use strptime
.
struct tm date;
strptime( "2017-03-21", "%F", &date );
puts( asctime(&date) ); // Mon Mar 21 00:00:00 2017
But that's not a great way to store dates. It turns out it's better to use Julian Days (see below).
In C we have for working with time, is there one for dates too?
If you're referring to time_t
, that is also for date-times. It's the number of seconds since "the epoch" which is 1970-01-01 00:00:00 UTC on POSIX systems, but not necessarily others. Unfortunately its safe range is only 1970 to 2037, though any recent version of an operating system will have greatly expanded that range.
How can I calculate difference between two dates?
Depends on what you want. If you want the number of seconds, you could convert the struct tm
to time_t
using mktime
and then use difftime
, but that's limited to the 1970-2037 safe range of time_t
.
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'd convert the dates into Julian days, the number of days since November 24, 4714 BC, and subtract. While that might seem ridiculous, this relatively simple formula takes advantage of calendar cycles and only uses integer 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 Julian Dates and calendar dates.
Getting diffs in years, months, and days is difficult because of the number of days in a month varies by month and year, and because it has to be normalized. For example, you wouldn't say 2 years, -1 months, 2 days. You'd say 1 year, 11 months, 29 days (or maybe 28, depends on the month). For this reason, do date math in Julian Days whenever possible.
To get an idea of what's involved, PHP implements this as date_diff
. Have a look at the amount of C code required.
Yes,the standard library C Time Library
contains structures and functions you want.You can use struct tm
to store date and difftime
to get the difference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With