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
|
/* options for text editors
|
||||||
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
|
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
|
||||||
vim: expandtab:ts=4:sw=4
|
vim: expandtab:ts=4:sw=4
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
|
|
||||||
/*! \defgroup manip Manipulation routines.
|
/*! \defgroup manip Manipulation routines.
|
||||||
|
|
||||||
This set of functions is useful for converting dates and times into formats understood by humans,
|
This set of functions is useful for performing arithmetic etc. on dates. It uses
|
||||||
and vice versa.
|
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
|
/* options for text editors
|
||||||
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
|
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
|
||||||
|
|
|
@ -159,6 +159,7 @@ void usage(void)
|
||||||
"Operators:\n"
|
"Operators:\n"
|
||||||
" + (date, period) Advance date by elapsed time, push date.\n"
|
" + (date, period) Advance date by elapsed time, push date.\n"
|
||||||
" - (date, period) Regress 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 second.\n"
|
||||||
" <= (date, date) Prints 1 if first date less than or equal to second.\n"
|
" <= (date, date) Prints 1 if first date less than or equal to second.\n"
|
||||||
" == (date, date) Prints 1 if dates equal.\n"
|
" == (date, date) Prints 1 if dates equal.\n"
|
||||||
|
@ -177,8 +178,7 @@ int parse_command(char* cmd)
|
||||||
struct iso8601_elapsed period;
|
struct iso8601_elapsed period;
|
||||||
double period_d;
|
double period_d;
|
||||||
char date_str[40];
|
char date_str[40];
|
||||||
|
int ret = 0, sign;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
cmd = strtok(cmd, " \n");
|
cmd = strtok(cmd, " \n");
|
||||||
while(cmd) {
|
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, "<")) {
|
} else if(!strcmp(cmd, "<")) {
|
||||||
if(date_stack_pop_date(&date, &details) || date_stack_pop_date(&date2, &details2)) {
|
if(date_stack_pop_date(&date, &details) || date_stack_pop_date(&date2, &details2)) {
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
Loading…
Reference in New Issue