Add iso8601_difference()
This commit is contained in:
parent
4deda83c58
commit
f49b80de01
|
@ -98,6 +98,38 @@ void iso8601_subtract_elapsed(struct iso8601_date* date, const struct iso8601_el
|
|||
|
||||
|
||||
|
||||
void iso8601_difference(const struct iso8601_date* d1, const struct iso8601_date* d2,
|
||||
struct iso8601_elapsed* per, int* sign)
|
||||
{
|
||||
const struct iso8601_date* e1, * e2;
|
||||
|
||||
/* compute sign */
|
||||
if(iso8601_lt(d1, d2)) {
|
||||
if(sign) *sign = -1;
|
||||
e1 = d2;
|
||||
e2 = d1;
|
||||
} else {
|
||||
if(sign) *sign = 1;
|
||||
e1 = d1;
|
||||
e2 = d2;
|
||||
}
|
||||
|
||||
if(!per) return;
|
||||
|
||||
/* compute difference, knowing that e1 >= e2 */
|
||||
per->sec = (e1->day - e2->day) * 86400
|
||||
+ iso8601_leap_elapsed(e2, e1 /* start, end */)
|
||||
+ (e1->sec - e2->sec);
|
||||
if(e1->nsec < e2->nsec) {
|
||||
--per->sec;
|
||||
per->nsec = BILLION + e1->nsec - e2->nsec;
|
||||
} else {
|
||||
per->nsec = e1->nsec - e2->nsec;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* options for text editors
|
||||
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
|
||||
vim: expandtab:ts=4:sw=4
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
|
||||
/*! \defgroup manip Manipulation routines.
|
||||
|
||||
This set of functions is useful for converting dates and times into formats understood by humans,
|
||||
and vice versa.
|
||||
This set of functions is useful for performing arithmetic etc. on dates. It uses
|
||||
struct iso8601_elapsed to represent the magnitude of time differences.
|
||||
|
||||
*/
|
||||
/*!@{*/
|
||||
|
@ -73,6 +73,23 @@ void iso8601_subtract_elapsed(struct iso8601_date* date, const struct iso8601_el
|
|||
|
||||
|
||||
|
||||
/*! \brief Find difference between dates.
|
||||
|
||||
\param d1 First date.
|
||||
\param d2 Second date.
|
||||
\param[out] per Magnitude of period elapsed between two dates. Pointer may be 0.
|
||||
\param[out] sign Set to sign of difference (-1 or +1). Pointer may be 0.
|
||||
|
||||
This function will perform the calculation <code>|d1 - d2|</code>, storing the result in \a per (if
|
||||
it is not a null pointer). The sign of the result is stored in \a sign (if it is not a null
|
||||
pointer), i.e. -1 if \a d2 > \a d1 or +1 if \a d2 <= \a d1.
|
||||
|
||||
*/
|
||||
void iso8601_difference(const struct iso8601_date* d1, const struct iso8601_date* d2,
|
||||
struct iso8601_elapsed* per, int* sign);
|
||||
|
||||
|
||||
|
||||
/*!@}*/
|
||||
/* options for text editors
|
||||
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
|
||||
|
|
|
@ -159,6 +159,7 @@ void usage(void)
|
|||
"Operators:\n"
|
||||
" + (date, period) Advance date by elapsed time, push date.\n"
|
||||
" - (date, period) Regress date by elapsed time, push date.\n"
|
||||
" dp (date, date) Compute difference, print elapsed time.\n"
|
||||
" < (date, date) Prints 1 if first date less than second.\n"
|
||||
" <= (date, date) Prints 1 if first date less than or equal to second.\n"
|
||||
" == (date, date) Prints 1 if dates equal.\n"
|
||||
|
@ -177,8 +178,7 @@ int parse_command(char* cmd)
|
|||
struct iso8601_elapsed period;
|
||||
double period_d;
|
||||
char date_str[40];
|
||||
|
||||
int ret = 0;
|
||||
int ret = 0, sign;
|
||||
|
||||
cmd = strtok(cmd, " \n");
|
||||
while(cmd) {
|
||||
|
@ -209,6 +209,19 @@ int parse_command(char* cmd)
|
|||
|
||||
}
|
||||
|
||||
} else if(!strcmp(cmd, "dp")) {
|
||||
if(date_stack_pop_date(&date, &details) || date_stack_pop_date(&date2, &details2)) {
|
||||
ret = 1;
|
||||
|
||||
} else {
|
||||
iso8601_difference(&date2, &date, &period, &sign);
|
||||
printf("Difference: %c %lu.%09lu\n",
|
||||
(sign < 0) ? '-' : '+',
|
||||
(unsigned long)period.sec,
|
||||
(unsigned long)period.nsec);
|
||||
|
||||
}
|
||||
|
||||
} else if(!strcmp(cmd, "<")) {
|
||||
if(date_stack_pop_date(&date, &details) || date_stack_pop_date(&date2, &details2)) {
|
||||
ret = 1;
|
||||
|
|
Loading…
Reference in New Issue