Computing the difference between two dates in C is a classic exercise that most tutorials get subtly wrong — hand-rolled day counting that forgets the century leap-year rules, so 1900 counts as a leap year when it wasn’t. The C standard library already solved this: convert each date to a time_t with mktime(), subtract with difftime(), and divide by 86,400 seconds per day. The library handles every leap-year rule, month length, and calendar quirk for you. This page shows the complete program — date validation included — in tested, warning-free C89, and explains the one trick (setting the time to noon) that makes the result immune to daylight-saving-time edge cases.
How It Works — Step by Step
- Validate each date first: reject month 13 or February 30 before doing any math. The leap-year check uses the full Gregorian rule: divisible by 4, except century years, unless divisible by 400. So 2024 and 2000 are leap years; 1900 and 2025 are not.
- Fill a
struct tm: zero it withmemset(), then set the day, month, and year. Two famous off-by-one traps live here:tm_monruns 0–11 (January is 0), andtm_yearcounts from 1900. - Convert with
mktime(): it turns the broken-down date into atime_t— seconds since January 1, 1970 — applying all calendar rules in the process. - Subtract with
difftime(): returns the difference in seconds as adouble; dividing by 86,400 gives days. We take the absolute value so the order you enter the dates doesn’t matter.
C Program to Find the Difference Between Two Dates
/* Difference between two dates in C using mktime() and difftime()
* Compile: gcc -ansi -Wall -Wextra date_diff.c -o date_diff */
#include <stdio.h>
#include <string.h>
#include <time.h>
static int is_leap(int y)
{
return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
}
static int days_in_month(int m, int y)
{
static const int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (m == 2 && is_leap(y)) {
return 29;
}
return days[m - 1];
}
static int valid_date(int d, int m, int y)
{
if (y < 1902 || y > 2037) {
return 0; /* keep within a safe range for time_t */
}
if (m < 1 || m > 12) {
return 0;
}
if (d < 1 || d > days_in_month(m, y)) {
return 0;
}
return 1;
}
static time_t to_time(int d, int m, int y)
{
struct tm date;
memset(&date, 0, sizeof date);
date.tm_mday = d;
date.tm_mon = m - 1; /* struct tm months run 0-11 */
date.tm_year = y - 1900; /* struct tm years count from 1900 */
date.tm_hour = 12; /* noon sidesteps DST boundary effects */
return mktime(&date);
}
int main(void)
{
int d1, m1, y1, d2, m2, y2;
double days;
printf("Enter the first date (dd mm yyyy): ");
if (scanf("%d %d %d", &d1, &m1, &y1) != 3 || !valid_date(d1, m1, y1)) {
fprintf(stderr, "Invalid date.\n");
return 1;
}
printf("Enter the second date (dd mm yyyy): ");
if (scanf("%d %d %d", &d2, &m2, &y2) != 3 || !valid_date(d2, m2, y2)) {
fprintf(stderr, "Invalid date.\n");
return 1;
}
days = difftime(to_time(d2, m2, y2), to_time(d1, m1, y1)) / 86400.0;
if (days < 0) {
days = -days;
}
printf("Difference between the two dates: %.0f days\n", days);
return 0;
}
How to Compile and Run
gcc -ansi -Wall -Wextra date_diff.c -o date_diff
./date_diff
Sample Input and Output
Test 1 — start of the year to end of July:
Enter the first date (dd mm yyyy): 01 01 2026 Enter the second date (dd mm yyyy): 31 07 2026 Difference between the two dates: 211 days
Test 2 — spanning a leap year (1948), dates given in reverse order:
Enter the first date (dd mm yyyy): 15 08 1947 Enter the second date (dd mm yyyy): 26 01 1950 Difference between the two dates: 895 days
Test 3 — invalid date is rejected (2025 is not a leap year):
Enter the first date (dd mm yyyy): 29 02 2025 Invalid date.
All outputs are real captured runs of the exact code above. Test 2 checks out by hand: 138 days left in 1947, plus 366 (1948 is a leap year), plus 365, plus 26 days of January 1950 = 895.
Code Explanation
- Why noon (
tm_hour = 12)?mktime()interprets the date in local time. If midnight falls exactly on a daylight-saving transition, a day can be 23 or 25 hours long and integer division by 86,400 can come up a day short. Noon is never on the boundary, so the division is always exact. - The century rule matters:
(y % 4 == 0 && y % 100 != 0) || y % 400 == 0— a plainy % 4 == 0check miscounts every date range crossing 1900 or 2100. - Why the 1902–2037 range check? On systems where
time_tis 32 bits, dates outside roughly 1901–2038 overflow. Modern 64-bit systems reach much further, but the check keeps the program correct everywhere it compiles. difftime()vs plain subtraction:time_tis an arithmetic type but the standard doesn’t say it counts seconds —difftime()is the portable way to get the difference in seconds.- Order-independent: taking the absolute value at the end means “difference between” works whichever date comes first — matching how people actually use the program.
What This Program Teaches
struct tmand its off-by-one fields — months from 0, years from 1900mktime()/difftime()— letting the library own calendar arithmetic instead of re-deriving it- Input validation before computation — rejecting February 30 beats debugging it
- The full Gregorian leap rule — 4, except 100, unless 400
Related C Programs
- Leap Year Check in C — the 4/100/400 rule on its own
- Day of the Week from a Date of Birth in C — same calendar math, different question
- Time Functions in C — time(), localtime(), strftime() and friends
- Convert Days to Years, Weeks and Days in C — the reverse direction
Test yourself: our free C Programming Quiz app for Android has 150+ questions with explanations for every answer.
Recommended Book
The C Programming Language by Kernighan & Ritchie remains the definitive reference for the standard library used here. We’ve solved all of the book’s exercises. Also on Amazon.com.
1 comment on “Difference Between Two Dates in C – mktime() and difftime()”
You are not taken the leap year extra day count in your dater() function.
If u see clearly: If let say year (which is not the reference one…means greater one is a leap year)
Try your code for dates: 16/05/2004 and 25/08/2012
Also rather than using condition "i%4" use a proper Isleapyear check,
For eg:
int Isleap(int year) {
if(((year % 4) == 0 && (year % 100) != 0) || (year % 400 == 0)) {
return 1;
}
else {
return 0;
}
}