Welcome to collectivesolver - Programming & Software Q&A with code examples. A website with trusted programming answers. All programs are tested and work.

Contact: aviboots(AT)netvision.net.il

Semrush - keyword research tool

Create your online store today with Shopify

Turn ChatGPT, Claude, Gemini, And CoPilot Into Your Personal Assistant, Business Coach, Content Creator, And More

AFFILIATE MARKETING Your all-in-one performance engine Manage affiliates, creators, and customer referrals in one unified platform—turning every partnership into measurable growth

Secure & Reliable Web Hosting, Free Domain, Free SSL, 1-Click WordPress Install, Expert 24/7 Support

Disclosure: My content contains affiliate links.

43,227 questions

56,129 answers

573 users

How to compare two dates in C

1 Answer

0 votes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

/*
    Compare two dates in C
    ----------------------
    This program demonstrates how to compare two dates using only the C standard library.
    It uses a modular design, clear comments, and a full test suite.

    Concepts:
        - Parsing dates safely (YYYY-MM-DD)
        - Representing dates with a struct
        - Comparing dates lexicographically (year → month → day)
        - Handling invalid formats
        - Edge‑case testing

    Architecture notes:
        - A dedicated function handles parsing.
        - Another function performs comparison.
        - Main runs multiple predefined test cases.
        - No dynamic memory allocation except small automatic buffers.
        - No external dependencies.

    Performance notes:
        - Comparisons are O(1).
        - Parsing is fast and predictable.
        - Memory usage is minimal.

    Pitfalls:
        - Invalid date strings must be handled.
        - Comparing raw strings is unsafe; always convert to a structured type.
        - No timezone logic here; this is pure date comparison.
*/

typedef struct {
    int year;
    int month;
    int day;
} Date;

/*
    Safely parse a date string in the format YYYY-MM-DD.

    Error handling:
        - Returns false if the date is invalid.
        - Writes parsed values into the Date struct when valid.
*/
bool parseDate(const char *s, Date *out) {
    int y, m, d;
    char dash1, dash2;

    if (sscanf(s, "%d%c%d%c%d", &y, &dash1, &m, &dash2, &d) != 5) {
        return false;
    }

    if (dash1 != '-' || dash2 != '-') {
        return false;
    }

    if (m < 1 || m > 12) return false;
    if (d < 1 || d > 31) return false; /* Simplified; not checking month lengths */

    out->year = y;
    out->month = m;
    out->day = d;
    
    return true;
}

/*
    Compare two Date objects.

    Returns:
        - "earlier"
        - "later"
        - "equal"
*/
const char* compareDates(const Date *a, const Date *b) {
    if (a->year < b->year) return "earlier";
    if (a->year > b->year) return "later";

    if (a->month < b->month) return "earlier";
    if (a->month > b->month) return "later";

    if (a->day < b->day) return "earlier";
    if (a->day > b->day) return "later";

    return "equal";
}

/*
    Run a single test case:
        - Parse both dates
        - Handle invalid input
        - Compare if valid
*/
void runTestCase(const char *d1, const char *d2) {
    Date a, b;

    bool ok1 = parseDate(d1, &a);
    bool ok2 = parseDate(d2, &b);

    if (!ok1 || !ok2) {
        printf("Compare '%s' vs '%s' → invalid date format\n", d1, d2);
        return;
    }

    const char *result = compareDates(&a, &b);
    printf("Compare '%s' vs '%s' → %s\n", d1, d2, result);
}

/*
    Main test suite:
        - Multiple test cases
        - Includes edge cases
        - Prints results cleanly
*/
int main(void) {
    printf("Date comparison tests:\n\n");

    const char *tests[][2] = {
        {"2024-01-01", "2024-01-02"},   /* earlier */
        {"2024-01-02", "2024-01-01"},   /* later */
        {"2024-01-01", "2024-01-01"},   /* equal */
        {"1999-12-31", "2000-01-01"},   /* millennium boundary */
        {"2024-02-29", "2024-03-01"},   /* leap year (not validated strictly) */
        {"2024-02-29", "2023-02-28"},   /* leap vs non-leap */
        {"2024-13-01", "2024-01-01"},   /* invalid month */
        {"2024-00-10", "2024-01-01"},   /* invalid month */
        {"2024-01-32", "2024-01-01"},   /* invalid day */
        {"abcd-ef-gh", "2024-01-01"},   /* invalid format */
        {"2024-01-01", "abcd-ef-gh"},   /* invalid format */
    };

    size_t count = sizeof(tests) / sizeof(tests[0]);

    for (size_t i = 0; i < count; ++i) {
        runTestCase(tests[i][0], tests[i][1]);
    }

    return 0;
}


/*
run:

Date comparison tests:

Compare '2024-01-01' vs '2024-01-02' → earlier
Compare '2024-01-02' vs '2024-01-01' → later
Compare '2024-01-01' vs '2024-01-01' → equal
Compare '1999-12-31' vs '2000-01-01' → earlier
Compare '2024-02-29' vs '2024-03-01' → earlier
Compare '2024-02-29' vs '2023-02-28' → later
Compare '2024-13-01' vs '2024-01-01' → invalid date format
Compare '2024-00-10' vs '2024-01-01' → invalid date format
Compare '2024-01-32' vs '2024-01-01' → invalid date format
Compare 'abcd-ef-gh' vs '2024-01-01' → invalid date format
Compare '2024-01-01' vs 'abcd-ef-gh' → invalid date format

*/

 



answered 16 hours ago by avibootz
...