Difference Between Two Dates in C – mktime() and difftime()

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

  1. 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.
  2. Fill a struct tm: zero it with memset(), then set the day, month, and year. Two famous off-by-one traps live here: tm_mon runs 0–11 (January is 0), and tm_year counts from 1900.
  3. Convert with mktime(): it turns the broken-down date into a time_t — seconds since January 1, 1970 — applying all calendar rules in the process.
  4. Subtract with difftime(): returns the difference in seconds as a double; 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 plain y % 4 == 0 check miscounts every date range crossing 1900 or 2100.
  • Why the 1902–2037 range check? On systems where time_t is 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_t is 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 tm and its off-by-one fields — months from 0, years from 1900
  • mktime() / 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

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;
    }
    }

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>