argamanza
argamanza

Reputation: 1142

Trying to calculate difference between two dates using time.h library

I'm trying to calculate the exact difference between two dates i give using my own Date struct, i'm now testing the functions which returns the difference:

Date dateDifference(Date a, Date b){
    time_t rawtime,timeA,timeB;
    struct tm* tA,*tB;
    double difference;

    time(&rawtime);
    tA = tB = localtime(&rawtime);

    tA->tm_mday = 20;
    tA->tm_mon = 1;
    tA->tm_year = 115;

    tB->tm_mday = 3;
    tB->tm_mon = 10;
    tB->tm_year = 89;

    timeA = mktime(tA);
    timeB = mktime(tB);

    difference = difftime(timeA, timeB);
}

As you can see i gave some manual numbers into the two 'tm' structs to test it. When i debug i get the exact same value in both "timeA" and "timeB". I'm not really familiar with the time.h functions and therefore i'm doing it using knowledge i find on the web, and this is the best i succeeded achieving.

What am i doing wrong?

Upvotes: 1

Views: 4279

Answers (3)

chux
chux

Reputation: 153488

Both tA and tB should used a struct tmand not a pointer as in struct tm *. That way they each have their own memory to manipulate.

The original code used pointers to the same memory location. So changing one also changed the other.

Date dateDifference(Date a, Date b){
    time_t rawtime,timeA,timeB;
    // struct tm* tA,*tB;
    struct tm tA, tB;
    double difference;

    time(&rawtime);
    // tA = tB = localtime(&rawtime);
    tA = tB = *localtime(&rawtime);

    tA.tm_mday = 20;
    tA.tm_mon = 1;
    tA.tm_year = 115;

    tB.tm_mday = 3;
    tB.tm_mon = 10;
    tB.tm_year = 89;

    timeA = mktime(&tA);
    timeB = mktime(&tB);

    difference = difftime(timeA, timeB);
    ...
}

Code likely has another subtle problem. Assuming the following is today's day, there is an off-by-1 error

    tA.tm_mday = 20;
    // tA.tm_mon = 1;
    tA.tm_mon = 1 - 1;  // months since January
    tA.tm_year = 115;   // years since 1900

Upvotes: 1

Weather Vane
Weather Vane

Reputation: 34585

The two problems you have are:

localtime() returns a pointer to a structure in its own static memory. You should copy the structure before you call localtime() again.

You did't allocate any memory for the two tm structures - I have changed them from pointers to simple structures.

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

int main()
{
    time_t timeA, timeB;
    struct tm tA, tB, *tptr;
    double difference;

    time(&timeA);
    time(&timeB);
    tptr = localtime(&timeA);
    tA = *tptr;
    tptr = localtime(&timeB);
    tB = *tptr;

    tA.tm_mday = 20;
    tA.tm_mon = 1;
    tA.tm_year = 115;

    tB.tm_mday = 3;
    tB.tm_mon = 10;
    tB.tm_year = 89;

    timeA = mktime(&tA);
    timeB = mktime(&tB);

    difference = difftime(timeA, timeB);
    printf ("Difference is %.0f seconds\n", difference);
    return 0;
}

Program output:

Difference is 798336000 seconds

Upvotes: 3

Sebastian
Sebastian

Reputation: 8164

One could think, that this is caused by

tA = tB = localtime(&rawtime);

However, this is only half of the truth, because separating this into

tA = localtime(&rawtime);
tB = localtime(&rawtime);

leads also to the result, that tA and tB both point to the same address. This is stated in the manpage of localtime (man 3 localtime): "The return value points to a statically allocated string which might be overwritten by subsequent calls to any of the date and time functions."

Therefore, you have to copy one of the two to a newly allocated struct tm.

Upvotes: 1

Related Questions