Reputation: 1878
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
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
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 datetime
s. 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