Peter
Peter

Reputation: 1878

Calculate datetime difference in C

I need a function that can calculate the difference between two datetime (year, month, day, hours, minute, seconds). and then return the difference in the same format.

int main (){

    struct datetime dt_from;
    init_datetime(&dt_from, 1995, 9, 15, 10, 40, 15);

    struct datetime dt_to;
    init_datetime(&dt_to, 2004, 6, 15, 10, 40, 20);

    struct datetime dt_res;

    datetime_diff(&dt_from, &dt_to, &dt_res);

    return 0;

}

void datetime_diff(struct datetime *dt_from, struct datetime *dt_to
, struct datetime *dt_res) {

    //What can I do here to calculate the difference, and get it in the dt_res?

}

Upvotes: 1

Views: 1427

Answers (2)

Niklas Rosencrantz
Niklas Rosencrantz

Reputation: 26647

Please have a look and try this example which uses time.h and should be portable. It calculates the difference in days between the dates in your question. You can change the program a little so that it works the way you want.

#include <stdio.h>
#include <time.h>
#include <math.h>

int main() {
    time_t start_daylight, start_standard, end_daylight, end_standard;;
    struct tm start_date = {0};
    struct tm end_date = {0};
    double diff;

    printf("Start date: ");
    scanf("%d %d %d", &start_date.tm_mday, &start_date.tm_mon, &start_date.tm_year);
    printf("End date: ");
    scanf("%d %d %d", &end_date.tm_mday, &end_date.tm_mon, &end_date.tm_year);

    /* first with standard time */
    start_date.tm_isdst = 0;
    end_date.tm_isdst = 0;
    start_standard = mktime(&start_date);
    end_standard = mktime(&end_date);
    diff = difftime(end_standard, start_standard);

    printf("%.0f days difference\n", round(diff / (60.0 * 60 * 24)));

    /* now with daylight time */
    start_date.tm_isdst = 1;
    end_date.tm_isdst = 1;
    start_daylight = mktime(&start_date);
    end_daylight = mktime(&end_date);
    diff = difftime(end_daylight, start_daylight);

    printf("%.0f days difference\n", round(diff / (60.0 * 60 * 24)));

    return 0;
}

Test

Start date: 15 9 1995
End date: 15 6 2004
3195 days difference

Or even simpler for non-interactive code and with standard or daylight savings time:

#include <stdio.h>
#include <time.h>
#include <math.h>
int main()
{
    time_t start_daylight, start_standard, end_daylight, end_standard;;
    struct tm start_date = {0};
    struct tm end_date = {0};
    double diff;

    start_date.tm_year = 1995;
    start_date.tm_mon = 9;
    start_date.tm_mday = 15;
    start_date.tm_hour = 10;
    start_date.tm_min = 40;
    start_date.tm_sec = 15;

    end_date.tm_mday = 15;
    end_date.tm_mon = 6;
    end_date.tm_year = 2004;
    end_date.tm_hour = 10;
    end_date.tm_min = 40;
    end_date.tm_sec = 20;

    /* first with standard time */
    start_date.tm_isdst = 0;
    end_date.tm_isdst = 0;
    start_standard = mktime(&start_date);
    end_standard = mktime(&end_date);
    diff = difftime(end_standard, start_standard);

    printf("%.0f days difference\n", round(diff / (60.0 * 60 * 24)));

    /* now with daylight time */
    start_date.tm_isdst = 1;
    end_date.tm_isdst = 1;
    start_daylight = mktime(&start_date);
    end_daylight = mktime(&end_date);
    diff = difftime(end_daylight, start_daylight);

    printf("%.0f days difference\n", round(diff / (60.0 * 60 * 24)));

    return 0;
}

Upvotes: 1

muXXmit2X
muXXmit2X

Reputation: 2765

Here is the basic idea:

Convert your datetime into an integral type (preferable long long or unsigned long long) which represents your datetime value as it's smallest unit (second in your case). How to achieve that? Easy transform the single values into seconds and add everything together. (seconds + minutes * 60 + hours * 3600 ...)

Do this for both values and then subtract the integer values.

Now convert the single integer value, the time difference, back to a datetime. How? Start with the biggest unit (years) and divide the difference by the amount of seconds within one year (60 * 60 * 24 * 365). Now you know how many years are in between your two datetimes. Take the rest and divide it by the amount of seconds per month, and so on...

(Obviously I ignored everything rather complicated, like daylight saving time for example)


However I would highly recommend using struct tm from time.h as mentioned in the comments. It is portable and you can use difftime.

Upvotes: 0

Related Questions