From 3efa05ac7900fb0c82149a63848114dd96ddd253 Mon Sep 17 00:00:00 2001 From: Florian <fprill@gmx.de> Date: Mon, 13 May 2019 09:31:52 +0200 Subject: [PATCH] added wrapper function divideTimedelta. --- include/mtime_timedelta.h | 5 + src/mtime_timedelta.c | 430 ++++++++++++++++++++++---------------- 2 files changed, 255 insertions(+), 180 deletions(-) diff --git a/include/mtime_timedelta.h b/include/mtime_timedelta.h index 72a90165..ec2e6b76 100644 --- a/include/mtime_timedelta.h +++ b/include/mtime_timedelta.h @@ -58,6 +58,7 @@ struct _timedelta struct _divisionquotienttimespan { int64_t quotient; ///< Quotient of two timedeltas. + int64_t remainder_days; ///< Remainder in days of two timedeltas division. int64_t remainder_in_ms; ///< Remainder in milli seconds of two timedeltas division. }; @@ -85,6 +86,10 @@ timeDeltaToJulianDelta(struct _timedelta *td, struct _datetime *dt, struct _juli struct _timedelta* julianDeltaToTimeDelta(struct _juliandelta* jd, struct _datetime *dt, struct _timedelta* td_return); +struct _divisionquotienttimespan* +divideTimeDelta(struct _timedelta* dividend, struct _timedelta* divisor, + struct _datetime* base_dt, struct _divisionquotienttimespan* quo_ret); + struct _divisionquotienttimespan* divideTimeDeltaInSeconds(struct _timedelta* dividend, struct _timedelta* divisor, struct _datetime* base_dt, struct _divisionquotienttimespan* quo_ret); diff --git a/src/mtime_timedelta.c b/src/mtime_timedelta.c index e665d5f1..e709d556 100644 --- a/src/mtime_timedelta.c +++ b/src/mtime_timedelta.c @@ -1,11 +1,11 @@ /** * @file mtime_timedelta.c - * + * * @brief TimeDelta and some operations supported on TimeDelta. - * + * * @author Luis Kornblueh, Rahul Sinha. MPIM. * @date March 2013 - * + * */ #include <stdio.h> @@ -14,6 +14,7 @@ #include <inttypes.h> #include <time.h> #include <math.h> +#include "int_div.h" #include "mtime_timedelta.h" @@ -36,7 +37,7 @@ * A pointer to char. The string should contain parameters with which TimeDelta is to be created. * * @return td - * A pointer to a filled TimeDelta. + * A pointer to a filled TimeDelta. */ struct _timedelta* @@ -52,7 +53,7 @@ newTimeDelta(const char* tds) if ( ((duration_type_flag = verify_string_duration(tds, isoDuration)) != DURATION_MATCH_STD) - && + && (duration_type_flag != DURATION_MATCH_LONG) ) { @@ -83,7 +84,7 @@ newTimeDelta(const char* tds) //Cleanup. deallocate_iso8601_duration(isoDuration); - isoDuration = NULL; + isoDuration = NULL; return td; } @@ -96,7 +97,7 @@ newTimeDelta(const char* tds) * @brief Construct new TimeDelta using 'raw' numerical values. * * @param _sign - * An char value denoting positive('+') or negative('-') TimeDelta. + * An char value denoting positive('+') or negative('-') TimeDelta. * @param _year * An "int64_t" value denoting the year part of TimeDelta. * @param _month @@ -113,14 +114,14 @@ newTimeDelta(const char* tds) * An "int" value denoting the milli-second part of TimeDelta. * * @return td - * A pointer to a filled TimeDelta. + * A pointer to a filled TimeDelta. */ struct _timedelta * newRawTimeDelta(char _sign, int64_t _year, int _month, int _day, int _hour, int _minute, int _second, int _ms) { struct _timedelta* td; - + td = (struct _timedelta *) calloc(1, sizeof(struct _timedelta)); if (td == NULL ) { @@ -135,7 +136,7 @@ newRawTimeDelta(char _sign, int64_t _year, int _month, int _day, int _hour, int { td->flag_std_form = false; } - + td->sign = _sign; td->year = _year; td->month = _month; @@ -144,7 +145,7 @@ newRawTimeDelta(char _sign, int64_t _year, int _month, int _day, int _hour, int td->minute = _minute; td->second = _second; td->ms = _ms; - + return td; } @@ -152,10 +153,10 @@ newRawTimeDelta(char _sign, int64_t _year, int _month, int _day, int _hour, int * @brief Copy the values and construct a new TimeDelta. * * @param td - * A pointer to struct _timedelta. Values of td are used to initialize the new timedelta being created. + * A pointer to struct _timedelta. Values of td are used to initialize the new timedelta being created. * * @return _td - * A pointer to an initialized TimeDelta object. + * A pointer to an initialized TimeDelta object. */ struct _timedelta* @@ -215,7 +216,7 @@ deallocateTimeDelta(struct _timedelta* td) * A pointer to struct _timedelta. * * @return boolean - * if (td1 > td2), return greater_than. If (td1 == td2), return equal_to. If (td1 < td2), return less_than. + * if (td1 > td2), return greater_than. If (td1 == td2), return equal_to. If (td1 < td2), return less_than. * Return compare_error indicating error. */ @@ -234,12 +235,12 @@ compareTimeDelta(struct _timedelta* td1, struct _timedelta* td2) compare_return_val boolean = compare_error; - /* + /* * add special case for seconds larger than 59 by creating - * temporary/-ies, otherwise proceed with normal processing + * temporary/-ies, otherwise proceed with normal processing */ - if ( (td1->second < 59) && td2->second < 59) - { + if ( (td1->second < 59) && td2->second < 59) + { if(td1->year == td2->year) { if(td1->month == td2->month) @@ -281,7 +282,7 @@ compareTimeDelta(struct _timedelta* td1, struct _timedelta* td2) else if(td1->minute < td2->minute) { boolean = less_than; - } + } } else if(td1->hour > td2->hour) { @@ -298,7 +299,7 @@ compareTimeDelta(struct _timedelta* td1, struct _timedelta* td2) } else if(td1->day < td2->day) { - boolean = less_than; + boolean = less_than; } } else if (td1->month > td2->month) @@ -327,7 +328,7 @@ compareTimeDelta(struct _timedelta* td1, struct _timedelta* td2) if ( (td1->month == 0) && (td2->month == 0)) { int second; - + td1_tmp.day = td1->day; td1_tmp.hour = td1->hour; td1_tmp.minute = td1->minute; @@ -389,7 +390,7 @@ compareTimeDelta(struct _timedelta* td1, struct _timedelta* td2) else if(td1_tmp.minute < td2_tmp.minute) { boolean = less_than; - } + } } else if(td1_tmp.hour > td2_tmp.hour) { @@ -406,7 +407,7 @@ compareTimeDelta(struct _timedelta* td1, struct _timedelta* td2) } else if(td1_tmp.day < td2_tmp.day) { - boolean = less_than; + boolean = less_than; } } else @@ -416,16 +417,16 @@ compareTimeDelta(struct _timedelta* td1, struct _timedelta* td2) } else { - return compare_error; + return compare_error; } } - + if (td1->sign == '+' && td2->sign == '+' ) return boolean; else if (td1->sign == '-' && td2->sign == '-' ) return boolean*(-1); } - + return compare_error; } @@ -435,7 +436,7 @@ compareTimeDelta(struct _timedelta* td1, struct _timedelta* td2) * * Routine replaceTimeDelta copies the contents of source TimeDelta into a Destination TimeDelta object. * - * @param tdsrc + * @param tdsrc * A pointer to struct _timedelta. Copy "FROM" TimeDelta object. * * @param tddest @@ -469,14 +470,14 @@ else } -static +static struct _juliandelta* localTimeDeltaToJulianDelta_NonStandardTimeDelta(struct _timedelta* td, struct _datetime* base_dt, struct _juliandelta* jd_return) { if ( td->sign == '-' ) { - /* Negative TimeDelta. A negative juliandelta is represented in the following + /* Negative TimeDelta. A negative juliandelta is represented in the following way: -P01DT00.500S = jd2->sign = '-', jd2->day = -30, jd2->ms = -500. */ jd_return->sign = '-'; @@ -564,7 +565,7 @@ localTimeDeltaToJulianDelta_StandardTimeDelta_CalType360OR365(struct _timedelta* if ( td->sign == '-' ) { - /* Negative TimeDelta. A negative juliandelta is represented in the following + /* Negative TimeDelta. A negative juliandelta is represented in the following way: -P01DT00.500S = jd2->sign = '-', jd2->day = -30, jd2->ms = -500. */ jd_return->sign = '-'; @@ -628,21 +629,21 @@ localTimeDeltaToJulianDelta_StandardTimeDelta_CalTypeGREGORIAN(struct _timedelta /* In final year, the crucial point is the month of february. */ if ( - ( - (testYearIsLeapYear(base_dt->date.year + td->year + 1) ) - && - (base_dt->date.month >= 3) + ( + (testYearIsLeapYear(base_dt->date.year + td->year + 1) ) + && + (base_dt->date.month >= 3) ) || - ( - (testYearIsLeapYear(base_dt->date.year + td->year)) - && - (base_dt->date.month < 3) + ( + (testYearIsLeapYear(base_dt->date.year + td->year)) + && + (base_dt->date.month < 3) ) ) { - /* If the (base year + delta year) is a year before a leap year and base month is >= 3 - OR + /* If the (base year + delta year) is a year before a leap year and base month is >= 3 + OR base year + delta year is a leap year and month is < 3 => An addition of leap-year specific delta for each month. */ @@ -671,9 +672,9 @@ localTimeDeltaToJulianDelta_StandardTimeDelta_CalTypeGREGORIAN(struct _timedelta ((testYearIsLeapYear(i)) && (base_dt->date.month < 3)) ) { - /* If the next year is a leap year and month is >= 3 OR - this year is a leap year and month is less than 3 - => delta of 1 year corresponds to 366 day julian delta. + /* If the next year is a leap year and month is >= 3 OR + this year is a leap year and month is less than 3 + => delta of 1 year corresponds to 366 day julian delta. */ jd_return->day = jd_return->day + NO_OF_DAYS_IN_A_LEAP_YEAR; } @@ -684,17 +685,17 @@ localTimeDeltaToJulianDelta_StandardTimeDelta_CalTypeGREGORIAN(struct _timedelta } } - jd_return->day = jd_return->day + msdinm[base_dt->date.month - 1][td->month] + jd_return->day = jd_return->day + msdinm[base_dt->date.month - 1][td->month] + td->day; - jd_return->ms = (int64_t)td->hour * NO_OF_MS_IN_A_HOUR - + (int64_t)td->minute * NO_OF_MS_IN_A_MINUTE - + (int64_t)td->second * NO_OF_MS_IN_A_SECOND + jd_return->ms = (int64_t)td->hour * NO_OF_MS_IN_A_HOUR + + (int64_t)td->minute * NO_OF_MS_IN_A_MINUTE + + (int64_t)td->second * NO_OF_MS_IN_A_SECOND + td->ms; } else if ( td->sign == '-' ) { - /* A negative juliandelta is represented in the following way: + /* A negative juliandelta is represented in the following way: -P01DT00.500S = jd2->sign = '-', jd2->day = -30, jd2->ms = -500. */ jd_return->sign = '-'; @@ -705,8 +706,8 @@ localTimeDeltaToJulianDelta_StandardTimeDelta_CalTypeGREGORIAN(struct _timedelta || ((testYearIsLeapYear(base_dt->date.year - td->year)) && (base_dt->date.month >= 3))) { - /* If the (base year - delta year) is a year after leap year and base month is < 3 - OR + /* If the (base year - delta year) is a year after leap year and base month is < 3 + OR base year - delta year is a leap year and month is >= 3 => A substraction of leap-year specific delta for each month. */ @@ -735,9 +736,9 @@ localTimeDeltaToJulianDelta_StandardTimeDelta_CalTypeGREGORIAN(struct _timedelta ((testYearIsLeapYear(i)) && (base_dt->date.month >= 3)) ) { - /* If the previous year is a leap year and month is < 3 OR - this year is a leap year and month is >= 3 - => delta of 1 year corresponds to 366 day julian delta. + /* If the previous year is a leap year and month is < 3 OR + this year is a leap year and month is >= 3 + => delta of 1 year corresponds to 366 day julian delta. */ jd_return->day = jd_return->day - NO_OF_DAYS_IN_A_LEAP_YEAR; } @@ -750,9 +751,9 @@ localTimeDeltaToJulianDelta_StandardTimeDelta_CalTypeGREGORIAN(struct _timedelta jd_return->day = jd_return->day + (-1) * (ndiny - msdinm[base_dt->date.month - 1][NO_OF_MONTHS_IN_A_YEAR - td->month]) + (-1) * td->day; - jd_return->ms = (-1) * (int64_t)td->hour * NO_OF_MS_IN_A_HOUR - + (-1) * (int64_t)td->minute * NO_OF_MS_IN_A_MINUTE - + (-1) * (int64_t)td->second * NO_OF_MS_IN_A_SECOND + jd_return->ms = (-1) * (int64_t)td->hour * NO_OF_MS_IN_A_HOUR + + (-1) * (int64_t)td->minute * NO_OF_MS_IN_A_MINUTE + + (-1) * (int64_t)td->second * NO_OF_MS_IN_A_SECOND + (-1) * td->ms; } @@ -766,26 +767,26 @@ localTimeDeltaToJulianDelta_StandardTimeDelta_CalTypeGREGORIAN(struct _timedelta /* Internal function. */ -/* Converts TimeDelta value to a lib defined juliandelta value. Juliadelta depends on the calendar type. - Notice that TimeDelta is not uniquely defined but depends on the definition of corresponding DateTime +/* Converts TimeDelta value to a lib defined juliandelta value. Juliadelta depends on the calendar type. + Notice that TimeDelta is not uniquely defined but depends on the definition of corresponding DateTime (Referred to as Anchor date in the following). - The library assumes the following definition: Let A denote an anchor date and P a timedelta. For a - positive P, A + P = B where date B > A. Consequently, for a negative P, A + P = B where A > B. + The library assumes the following definition: Let A denote an anchor date and P a timedelta. For a + positive P, A + P = B where date B > A. Consequently, for a negative P, A + P = B where A > B. Also, when P is positive, a delta of 1 month has as many days as in the month of anchor DateTime; - a delta of 2 months corresponds to the number of days in the anchor date month and the next month and + a delta of 2 months corresponds to the number of days in the anchor date month and the next month and so on. When P is negative, a delta of 1 month corresponds to as many days as in the month before the anchor date month; a delta of 2 month corresponds to as many days as in the month before the - anchor date month and the month before that and so on. - + anchor date month and the month before that and so on. + For eg, TimeDelta of P01M, when the 'Anchor' DateTime is 2001-02-01T00:00:00.000 is equivalent to a - Julian Delta of positive 28 days ( #days in February ) and 0 ms. Also, TimeDelta of P02M, when the + Julian Delta of positive 28 days ( #days in February ) and 0 ms. Also, TimeDelta of P02M, when the 'Anchor' DateTime is 2001-02-01T00:00:00.000 is equivalent to a Julian Delta of positive 28+31 days - ( #days in February PLUS #days in March) and 0 ms. Similarly, a TimeDelta of -P01M with 'Anchor' - DateTime of 2001-02-01T00:00:00.000 is equivalent to a Julian Delta of negative 31 days - ( #days in January ) and 0 ms. Likewise, TimeDelta of -P02M with 'Anchor' DateTime of + ( #days in February PLUS #days in March) and 0 ms. Similarly, a TimeDelta of -P01M with 'Anchor' + DateTime of 2001-02-01T00:00:00.000 is equivalent to a Julian Delta of negative 31 days + ( #days in January ) and 0 ms. Likewise, TimeDelta of -P02M with 'Anchor' DateTime of 2001-02-01T00:00:00.000 is equivalent to a Julian Delta of negative 31+31 days ( #days in January - PLUS #days in December) and 0 ms. The same logic is used for all calendar types (with corresponding + PLUS #days in December) and 0 ms. The same logic is used for all calendar types (with corresponding days in months according to current calendar type.) */ @@ -804,7 +805,7 @@ timeDeltaToJulianDelta(struct _timedelta* td, struct _datetime* base_dt, struct { case YEAR_OF_365_DAYS: case YEAR_OF_360_DAYS: - + localTimeDeltaToJulianDelta_StandardTimeDelta_CalType360OR365(td, base_dt, jd_return); break; @@ -821,7 +822,7 @@ timeDeltaToJulianDelta(struct _timedelta* td, struct _datetime* base_dt, struct } } - return jd_return; + return jd_return; } else return NULL; @@ -829,26 +830,26 @@ timeDeltaToJulianDelta(struct _timedelta* td, struct _datetime* base_dt, struct /* Internal function. */ -/* Converts a lib defined Julian delta value to a TimeDelta value. TimeDelta depends on the calendar type. - Notice that TimeDelta is not uniquely defined but depends on the definition of corresponding DateTime +/* Converts a lib defined Julian delta value to a TimeDelta value. TimeDelta depends on the calendar type. + Notice that TimeDelta is not uniquely defined but depends on the definition of corresponding DateTime (Referred to as Anchor date in the following). - The library assumes the following definition: Let A denote an anchor date and P a timedelta. For a - positive P, A + P = B where date B > A. Consequently, for a negative P, A + P = B where A > B. + The library assumes the following definition: Let A denote an anchor date and P a timedelta. For a + positive P, A + P = B where date B > A. Consequently, for a negative P, A + P = B where A > B. Also, when P is positive, a delta of 1 month has as many days as in the month of anchor DateTime; - a delta of 2 months corresponds to the number of days in the anchor date month and the next month and + a delta of 2 months corresponds to the number of days in the anchor date month and the next month and so on. When P is negative, a delta of 1 month corresponds to as many days as in the month before the anchor date month; a delta of 2 month corresponds to as many days as in the month before the - anchor date month and the month before that and so on. + anchor date month and the month before that and so on. For eg, TimeDelta of P01M, when the 'Anchor' DateTime is 2001-02-01T00:00:00.000 is equivalent to a - Julian Delta of positive 28 days ( #days in February ) and 0 ms. Also, TimeDelta of P02M, when the + Julian Delta of positive 28 days ( #days in February ) and 0 ms. Also, TimeDelta of P02M, when the 'Anchor' DateTime is 2001-02-01T00:00:00.000 is equivalent to a Julian Delta of positive 28+31 days - ( #days in February PLUS #days in March) and 0 ms. Similarly, a TimeDelta of -P01M with 'Anchor' - DateTime of 2001-02-01T00:00:00.000 is equivalent to a Julian Delta of negative 31 days - ( #days in January ) and 0 ms. Likewise, TimeDelta of -P02M with 'Anchor' DateTime of + ( #days in February PLUS #days in March) and 0 ms. Similarly, a TimeDelta of -P01M with 'Anchor' + DateTime of 2001-02-01T00:00:00.000 is equivalent to a Julian Delta of negative 31 days + ( #days in January ) and 0 ms. Likewise, TimeDelta of -P02M with 'Anchor' DateTime of 2001-02-01T00:00:00.000 is equivalent to a Julian Delta of negative 31+31 days ( #days in January - PLUS #days in December) and 0 ms. The same logic is used for all calendar types (with corresponding + PLUS #days in December) and 0 ms. The same logic is used for all calendar types (with corresponding days in months according to current calendar type). */ @@ -887,8 +888,8 @@ julianDeltaToTimeDelta(struct _juliandelta* jd, struct _datetime* base_dt, struc if ( jd->sign == '-' ) { - /* Negative TimeDelta. A negative juliandelta is represented in the following - way: -P01DT00.500S = jd2->sign = '-', jd2->day = -30, jd2->ms = -500. */ + /* Negative TimeDelta. A negative juliandelta is represented in the following + way: -P01DT00.500S = jd2->sign = '-', jd2->day = -30, jd2->ms = -500. */ td_return->sign = '-'; @@ -1132,7 +1133,7 @@ julianDeltaToTimeDelta(struct _juliandelta* jd, struct _datetime* base_dt, struc } else if (jd->sign == '-') { - /* Negative TimeDelta. A negative juliandelta is represented in the following + /* Negative TimeDelta. A negative juliandelta is represented in the following way: -P01DT00.500S = jd2->sign = '-', jd2->day = -30, jd2->ms = -500. */ /* Negative delta. */ @@ -1160,7 +1161,7 @@ julianDeltaToTimeDelta(struct _juliandelta* jd, struct _datetime* base_dt, struc td_return->minute = ((-1)*(int) jd->ms - td_return->hour * NO_OF_MS_IN_A_HOUR) / NO_OF_MS_IN_A_MINUTE; td_return->second = ((-1)*(int) jd->ms - td_return->hour * NO_OF_MS_IN_A_HOUR - td_return->minute * NO_OF_MS_IN_A_MINUTE) / NO_OF_MS_IN_A_SECOND; td_return->ms = (-1)*(int) jd->ms - td_return->hour * NO_OF_MS_IN_A_HOUR - td_return->minute * NO_OF_MS_IN_A_MINUTE - td_return->second * NO_OF_MS_IN_A_SECOND; - } + } else return NULL; /* ERROR: Sign of julian delta not defined. */ @@ -1172,7 +1173,71 @@ else /*! \endcond */ -// WE REALLY NEED SOMETHING BETTER HERE! +struct _divisionquotienttimespan* +divideTimeDelta(struct _timedelta* dividend, struct _timedelta* divisor, + struct _datetime* base_dt, struct _divisionquotienttimespan* quo_ret) +{ + if ((dividend == NULL) || (divisor == NULL) || (quo_ret == NULL)) return NULL; + + /* convert dividend and divisor into _juliandelta data type. */ + struct _juliandelta* jd_dividend = newJulianDelta('+', 0, 0); + if ( jd_dividend == NULL ) return NULL; + jd_dividend = timeDeltaToJulianDelta(dividend, base_dt, jd_dividend); + if ( jd_dividend == NULL ) + { + deallocateJulianDelta(jd_dividend); + return NULL; + } + + struct _juliandelta* jd_divisor = newJulianDelta('+', 0, 0); + if ( jd_divisor == NULL ) return NULL; + jd_divisor = timeDeltaToJulianDelta(divisor, base_dt, jd_divisor); + if ( jd_divisor == NULL ) + { + deallocateJulianDelta(jd_divisor); + return NULL; + } + + /* perform large integer division. */ + t_int days1, day_fraction1, days2, day_fraction2; + t_int q_decimal = 0, remainder_days = 0, remainder_ms = 0; + + days1 = (t_int) jd_dividend->day; + day_fraction1 = (t_int) jd_dividend->ms; + days2 = (t_int) jd_divisor->day; + day_fraction2 = (t_int) jd_divisor->ms; + + int ret = divide_timespan(days1, day_fraction1, days2, day_fraction2, + &q_decimal, &remainder_days, &remainder_ms); + + quo_ret->quotient = (int64_t) 0; + quo_ret->remainder_days = (int64_t) 0; + quo_ret->remainder_in_ms = (int64_t) 0; + if (ret != 0) { + quo_ret->quotient = (int64_t) q_decimal; + quo_ret->remainder_days = (int64_t) remainder_days; + quo_ret->remainder_in_ms = (int64_t) remainder_ms; + } + + /* correct sign. */ + + /* TODO: maybe we should better remove negative time span division. Is it well-defined? */ + if (jd_dividend->sign != jd_divisor->sign) { + quo_ret->quotient *= -1; + quo_ret->remainder_days *= -1; + quo_ret->remainder_in_ms *= -1; + } + + deallocateJulianDelta(jd_dividend); + deallocateJulianDelta(jd_divisor); + + if (ret == 0) return NULL; + + return (quo_ret); +} + + +/* TODO: Remove the following subroutine? */ struct _divisionquotienttimespan* divideTimeDeltaInSeconds(struct _timedelta* dividend, struct _timedelta* divisor, struct _datetime* base_dt, struct _divisionquotienttimespan* quo_ret) { @@ -1192,10 +1257,10 @@ divideTimeDeltaInSeconds(struct _timedelta* dividend, struct _timedelta* divisor } intmax_t numerator = (intmax_t) (((int64_t) jd->day * NO_OF_MS_IN_A_DAY + jd->ms)); - intmax_t denominator = (intmax_t) (((int64_t) divisor->day * 86400 + - divisor->hour * 3600 + - divisor->minute * 60 + - divisor->second ) * 1000 + + intmax_t denominator = (intmax_t) (((int64_t) divisor->day * 86400 + + divisor->hour * 3600 + + divisor->minute * 60 + + divisor->second ) * 1000 + divisor->ms); deallocateJulianDelta(jd); @@ -1203,8 +1268,9 @@ divideTimeDeltaInSeconds(struct _timedelta* dividend, struct _timedelta* divisor return NULL; imaxdiv_t div = imaxdiv(numerator, denominator); - - quo_ret->quotient = (int64_t) div.quot; + + quo_ret->quotient = (int64_t) div.quot; + quo_ret->remainder_days = (int64_t) 0; quo_ret->remainder_in_ms = (int64_t) div.rem; return quo_ret; } @@ -1224,6 +1290,7 @@ divideTimeDeltaInSeconds(struct _timedelta* dividend, struct _timedelta* divisor * * @return result of division. NULL indicates error. */ +/* TODO: For the sake of simplicity, remove the following subroutine? */ struct _divisionquotienttimespan* divideDatetimeDifferenceInSeconds(struct _datetime* dt1, struct _datetime* dt2, struct _timedelta* divisor, struct _divisionquotienttimespan* quo_ret) { @@ -1243,14 +1310,15 @@ divideDatetimeDifferenceInSeconds(struct _datetime* dt1, struct _datetime* dt2, return NULL; struct _juliandelta* jd = newJulianDelta('+', 0, 0); - jd = substractJulianDay(jd1, jd2, jd); + jd = substractJulianDay(jd1, jd2, jd); intmax_t numerator = (intmax_t) (jd->day * 86400000 + jd->ms); - + imaxdiv_t div = imaxdiv(numerator, denominator); - - quo_ret->quotient = (int64_t) div.quot; + + quo_ret->quotient = (int64_t) div.quot; + quo_ret->remainder_days = (int64_t) 0; quo_ret->remainder_in_ms = (int64_t) div.rem; - + if (jd1 != NULL) deallocateJulianDay(jd1); if (jd2 != NULL) deallocateJulianDay(jd2); if (jd != NULL) deallocateJulianDelta(jd); @@ -1271,10 +1339,11 @@ divideDatetimeDifferenceInSeconds(struct _datetime* dt1, struct _datetime* dt2, * * @return result of division. NULL indicates error. */ +/* TODO: For the sake of simplicity, remove the following subroutine? */ struct _divisionquotienttimespan* divideTwoDatetimeDiffsInSeconds(struct _datetime* dt1_dividend, struct _datetime* dt2_dividend, struct _datetime* dt1_divisor, struct _datetime* dt2_divisor, int64_t* denominator_ret, struct _divisionquotienttimespan* quo_ret) { - if ((dt1_dividend != NULL) && (dt2_dividend != NULL) && + if ((dt1_dividend != NULL) && (dt2_dividend != NULL) && (dt1_divisor != NULL) && (dt2_divisor != NULL) && (quo_ret != NULL)) { // dividend @@ -1285,7 +1354,7 @@ divideTwoDatetimeDiffsInSeconds(struct _datetime* dt1_dividend, struct _datetime if (jd2_dividend != NULL) jd2_dividend = date2julian(dt2_dividend, jd2_dividend); struct _juliandelta* jd_dividend = newJulianDelta('+', 0, 0); - jd_dividend = substractJulianDay(jd1_dividend, jd2_dividend, jd_dividend); + jd_dividend = substractJulianDay(jd1_dividend, jd2_dividend, jd_dividend); intmax_t numerator = (intmax_t) (jd_dividend->day * 86400000 + jd_dividend->ms); // divisor @@ -1296,26 +1365,27 @@ divideTwoDatetimeDiffsInSeconds(struct _datetime* dt1_dividend, struct _datetime if (jd2_divisor != NULL) jd2_divisor = date2julian(dt2_divisor, jd2_divisor); struct _juliandelta* jd_divisor = newJulianDelta('+', 0, 0); - jd_divisor = substractJulianDay(jd1_divisor, jd2_divisor, jd_divisor); + jd_divisor = substractJulianDay(jd1_divisor, jd2_divisor, jd_divisor); intmax_t denominator = (intmax_t) (jd_divisor->day * 86400000 + jd_divisor->ms); - + imaxdiv_t div = imaxdiv(numerator, denominator); - - quo_ret->quotient = (int64_t) div.quot; + + quo_ret->quotient = (int64_t) div.quot; + quo_ret->remainder_days = (int64_t) 0; quo_ret->remainder_in_ms = (int64_t) div.rem; *denominator_ret = (int64_t) (denominator / 1000); - + if (jd1_dividend != NULL) deallocateJulianDay(jd1_dividend); if (jd2_dividend != NULL) deallocateJulianDay(jd2_dividend); if (jd_dividend != NULL) deallocateJulianDelta(jd_dividend); - + if (jd1_divisor != NULL) deallocateJulianDay(jd1_divisor); if (jd2_divisor != NULL) deallocateJulianDay(jd2_divisor); if (jd_divisor != NULL) deallocateJulianDelta(jd_divisor); - - return quo_ret; + + return quo_ret; } - else + else return NULL; } @@ -1323,17 +1393,17 @@ divideTwoDatetimeDiffsInSeconds(struct _datetime* dt1_dividend, struct _datetime * @brief Get the TimeDelta between two Dates d1 and d2 as (d1-d2). * * Routine getTimeDeltaFromDate 'substracts' two Dates and returns the TimeDelta between - * them. Internally, Dates are converted to DateTimes and then delta is calculated using + * them. Internally, Dates are converted to DateTimes and then delta is calculated using * getTimeDeltaFromDateTime(). - * - * This routine handles all supported Calendar types; i.e. the translation from Calendar date - * to Julian date and conversion from Julian Delta to normal TimeDetla is Calendar-type dependent. - * For eg. for Calendar type Gregorian, the TimeDelta between 2001-02-01 and 2001-01-01 will be 1 month. - * Similarly, for Calendar of type 360-Day-Calendar, the TimeDelta will be 1 month. It must be noted + * + * This routine handles all supported Calendar types; i.e. the translation from Calendar date + * to Julian date and conversion from Julian Delta to normal TimeDetla is Calendar-type dependent. + * For eg. for Calendar type Gregorian, the TimeDelta between 2001-02-01 and 2001-01-01 will be 1 month. + * Similarly, for Calendar of type 360-Day-Calendar, the TimeDelta will be 1 month. It must be noted * however, that the two dates differ by 31 and 30 days respectively. * * @param d1 - * A pointer to struct _date. + * A pointer to struct _date. * * @param d2 * A pointer to struct _date. @@ -1383,17 +1453,17 @@ else * * Routine getTimeDeltaFromDateTime 'substracts' two DateTime's and returns the TimeDelta between * them. Each datetime is converted to an equivalent Julian Date. Substraction is then performed - * on Julian axis. The "Julian delta" is finally converted back to normal calendar delta. - * - * This routine handles all supported Calendar types; i.e. the translation from Calendar date - * to Julian date and conversion from Julian Delta to normal TimeDetla is Calendar-type dependent. - * For eg. for Calendar type Gregorian, the TimeDelta between 2001-02-01T00:00:00.000 and - * 2001-01-01T00:00:00.000 will be 1 month. Similarly, for Calendar of type 360-Day-Calendar, - * the TimeDelta will be 1 month. It must be noted however, that the two dates differ by 31 and - * 30 days respectively. + * on Julian axis. The "Julian delta" is finally converted back to normal calendar delta. + * + * This routine handles all supported Calendar types; i.e. the translation from Calendar date + * to Julian date and conversion from Julian Delta to normal TimeDetla is Calendar-type dependent. + * For eg. for Calendar type Gregorian, the TimeDelta between 2001-02-01T00:00:00.000 and + * 2001-01-01T00:00:00.000 will be 1 month. Similarly, for Calendar of type 360-Day-Calendar, + * the TimeDelta will be 1 month. It must be noted however, that the two dates differ by 31 and + * 30 days respectively. * * @param dt1 - * A pointer to struct _datetime. + * A pointer to struct _datetime. * * @param dt2 * A pointer to struct _datetime. @@ -1409,7 +1479,7 @@ struct _timedelta* getTimeDeltaFromDateTime(struct _datetime* dt1, struct _datetime* dt2, struct _timedelta* td_return) { if ((dt1 != NULL )&& (dt2 != NULL) && (td_return != NULL) ){ - + /* Convert dt1 to Julian. */ struct _julianday* jd1 = newJulianDay(0, 0); if (jd1 == NULL) @@ -1455,9 +1525,9 @@ else /** * @brief Get total number of milliseconds in timedelta. * - * Routine getTotalMilliSecondsTimeDelta returns the total number of milliseconds in TimeDelta. - * Notice that TimeDelta is not uniquely defined but depends on the definition of corresponding - * DateTime. TimeDelta is first converted to corresponding delta on the Julian axis. Julian delta + * Routine getTotalMilliSecondsTimeDelta returns the total number of milliseconds in TimeDelta. + * Notice that TimeDelta is not uniquely defined but depends on the definition of corresponding + * DateTime. TimeDelta is first converted to corresponding delta on the Julian axis. Julian delta * is finally converted to the correct millisecond value. * * @param td @@ -1501,9 +1571,9 @@ else /** * @brief Get total number of seconds in timedelta. * - * Routine getTotalSecondsTimeDelta returns the total number of seconds in TimeDelta. Notice that TimeDelta + * Routine getTotalSecondsTimeDelta returns the total number of seconds in TimeDelta. Notice that TimeDelta * is not uniquely defined but depends on the definition of corresponding DateTime. Internally, number of seconds - * is calculated by calling the routine getTotalMilliSecondsTimeDelta() and then converting the millisecond value + * is calculated by calling the routine getTotalMilliSecondsTimeDelta() and then converting the millisecond value * to seconds by dividing it by 1000. * * @param td @@ -1554,7 +1624,7 @@ timedeltaToString(struct _timedelta* td, char* toStr) strcpy (toStr,"P"); else return NULL; /* ERROR: TD sign not set. Should never happen. */ - + if (td->year != 0) sprintf(&(toStr[strlen(toStr)]),"%" PRIi64 "Y",td->year); @@ -1613,14 +1683,14 @@ else /** * @brief Add timedelta to Date. * -* Routine addTimeDeltaToDate adds a timedelta to a Date and returns the new Date. Both Date +* Routine addTimeDeltaToDate adds a timedelta to a Date and returns the new Date. Both Date * and TimeDetla are first converted to corresponding values on the Julian axis. Addition is performed on -* the julian axis and the resulting Julian Date is converted back to the corrsponding Date. +* the julian axis and the resulting Julian Date is converted back to the corrsponding Date. * -* The library assumes the following definition: Let A denote an anchor date and P a timedelta. For a -* positive P, A + P = B where date B > A. Consequently, for a negative P, A + P = B where A > B. +* The library assumes the following definition: Let A denote an anchor date and P a timedelta. For a +* positive P, A + P = B where date B > A. Consequently, for a negative P, A + P = B where A > B. * Also, when P is positive, a delta of 1 month has as many days as in the month of anchor DateTime; -* a delta of 2 months corresponds to the number of days in the anchor date month and the next month and +* a delta of 2 months corresponds to the number of days in the anchor date month and the next month and * so on. When P is negative, a delta of 1 month corresponds to as many days as in the month before the * anchor date month; a delta of 2 month corresponds to as many days as in the month before the * anchor date month and the month before that and so on. @@ -1676,14 +1746,14 @@ addTimeDeltaToDate(struct _date* d, struct _timedelta* td, struct _date* d_retur /** * @brief Add timedelta to DateTime. * - * Routine addTimeDeltaToDateTime adds a timedelta to a DateTime and returns the new DateTime. Both DateTime + * Routine addTimeDeltaToDateTime adds a timedelta to a DateTime and returns the new DateTime. Both DateTime * and TimeDetla are first converted to corresponding values on the Julian axis. Addition is performed on * the julian axis and the resulting Julian Date is converted back to the corrsponding DateTime. * - * The library assumes the following definition: Let A denote an anchor date and P a timedelta. For a - * positive P, A + P = B where date B > A. Consequently, for a negative P, A + P = B where A > B. + * The library assumes the following definition: Let A denote an anchor date and P a timedelta. For a + * positive P, A + P = B where date B > A. Consequently, for a negative P, A + P = B where A > B. * Also, when P is positive, a delta of 1 month has as many days as in the month of anchor DateTime; - * a delta of 2 months corresponds to the number of days in the anchor date month and the next month and + * a delta of 2 months corresponds to the number of days in the anchor date month and the next month and * so on. When P is negative, a delta of 1 month corresponds to as many days as in the month before the * anchor date month; a delta of 2 month corresponds to as many days as in the month before the * anchor date month and the month before that and so on. @@ -1758,10 +1828,10 @@ addTimeDeltaToDateTime(struct _datetime* dt, struct _timedelta* td, struct _date * @brief Get the timedelta between current_dt and start_dt plus next integral-multiple-of-timestep (timedelta). * * Routine moduloTimeDeltaFromDateTime returns the timedelta between the current DateTime (current_dt) and the event's next-trigger time. - * The next trigger time is defined as the the Anchor DateTime (start_dt) + N * TimeDelta(timestep) - * where N is the minimum positive integer for which this sum is >= Current DateTime. In case + * The next trigger time is defined as the the Anchor DateTime (start_dt) + N * TimeDelta(timestep) + * where N is the minimum positive integer for which this sum is >= Current DateTime. In case * Anchor DateTime > Current DateTime, TimeDelta is calculated as start_dt - current_dt. - * + * * Notice that this TimeDelta will always be positive. * * @param start_dt @@ -1774,7 +1844,7 @@ addTimeDeltaToDateTime(struct _datetime* dt, struct _timedelta* td, struct _date * A pointer to struct _datetime. The Current Date time. * * @param modulo_td - * A pointer to struct _timedelta. The timedelta between 'current datetime' and 'Start Datetime plus next + * A pointer to struct _timedelta. The timedelta between 'current datetime' and 'Start Datetime plus next * integral-multiple-of-timestep' is copied here. * * @return modulo_td @@ -1832,7 +1902,7 @@ moduloTimeDeltaFromDateTime(struct _datetime* start_dt, struct _timedelta* times * A pointer to struct _timedelta. The element-wise product of lambda and base_td is stored here. * * @return scaled_td - * A pointer to struct _timedelta. The filled structure containing the scaled timedelta values. + * A pointer to struct _timedelta. The filled structure containing the scaled timedelta values. */ struct _timedelta* elementwiseScalarMultiplyTimeDelta(struct _timedelta* base_td, int64_t lambda, struct _timedelta* scaled_td) @@ -1865,14 +1935,14 @@ elementwiseScalarMultiplyTimeDelta(struct _timedelta* base_td, int64_t lambda, s scaled_td->ms -= NO_OF_MS_IN_A_SECOND; scaled_td->second += 1; } - + scaled_td->second += (int) lambda*base_td->second; while ( scaled_td->second >= 60 ) - { + { scaled_td->second -= 60; scaled_td->minute += 1; } - + scaled_td->minute += (int) lambda*base_td->minute; while ( scaled_td->minute >= 60 ) { @@ -1894,7 +1964,7 @@ elementwiseScalarMultiplyTimeDelta(struct _timedelta* base_td, int64_t lambda, s scaled_td->year = 0; return scaled_td; - + } else return NULL; @@ -1922,7 +1992,7 @@ elementwiseScalarMultiplyTimeDelta(struct _timedelta* base_td, int64_t lambda, s * A pointer to struct _timedelta. The element-wise product of lambda and base_td is stored here. * * @return scaled_td - * A pointer to struct _timedelta. The filled structure containing the scaled timedelta values. + * A pointer to struct _timedelta. The filled structure containing the scaled timedelta values. */ struct _timedelta* elementwiseScalarMultiplyTimeDeltaDP(struct _timedelta* base_td, double lambda, struct _timedelta* scaled_td) @@ -1972,8 +2042,8 @@ elementwiseScalarMultiplyTimeDeltaDP(struct _timedelta* base_td, double lambda, * @brief Return the element-wise sum of two timedeltas. * * elementwiseAddTimeDeltatoTimeDelta adds two timedeltas elementwise and returns the result. - * Timedeltas being added must be of the same sign; Substraction is not supported. - * The timedelta can not have days,months or years however: Only Timedeltas upto hours should call this routine. + * Timedeltas being added must be of the same sign; Substraction is not supported. + * The timedelta can not have days,months or years however: Only Timedeltas upto hours should call this routine. * Also td_return->hour >= 24 will lead to an error. * * @@ -1987,7 +2057,7 @@ elementwiseScalarMultiplyTimeDeltaDP(struct _timedelta* base_td, double lambda, * A pointer to struct _timedelta. The element-wise sum of td1 and td2 is stored here. * * @return td_return - * A pointer to struct _timedelta. The filled structure containing the added timedelta values. + * A pointer to struct _timedelta. The filled structure containing the added timedelta values. */ struct _timedelta* elementwiseAddTimeDeltatoTimeDelta(struct _timedelta* td1, struct _timedelta* td2, struct _timedelta* td_return) @@ -2000,13 +2070,13 @@ elementwiseAddTimeDeltatoTimeDelta(struct _timedelta* td1, struct _timedelta* td /*Reset td_return to 0.*/ memset(td_return,0,sizeof(struct _timedelta)); - + if(td1->sign == td2->sign) { /* If signs match, do add. */ td_return->sign = td1->sign; - td_return->ms += (td1->ms + td2->ms); + td_return->ms += (td1->ms + td2->ms); if ( td_return->ms >= NO_OF_MS_IN_A_SECOND ) { td_return->ms -= NO_OF_MS_IN_A_SECOND; @@ -2037,22 +2107,22 @@ elementwiseAddTimeDeltatoTimeDelta(struct _timedelta* td1, struct _timedelta* td td_return->day = 0; td_return->month = 0; td_return->year = 0; - } + } else { /* Substraction not supported. */ - return NULL; + return NULL; } return td_return; - } + } else return NULL; } /** - * @brief Returns the remainder of timedelta a modulo timedelta p + * @brief Returns the remainder of timedelta a modulo timedelta p * * moduloTimedelta(struct _timedelta *a, struct _timdelta *p) returns the remainder of * a modulo p. The function is restricted to input timedeltas less than 29 days. @@ -2066,7 +2136,7 @@ elementwiseAddTimeDeltatoTimeDelta(struct _timedelta* td1, struct _timedelta* td * @param p * on return contains the quotient * - * @return rem + * @return rem * returns remainder of the division of the numerator a by * the denominator p. quotient * p + rem shall equal a. */ @@ -2075,15 +2145,15 @@ int64_t moduloTimedelta(struct _timedelta *a, struct _timedelta *p, int64_t *quot) { struct _datetime *dt = newDateTime("0001-01-01"); - + struct _juliandelta *jdd1 = newJulianDelta('+', (int64_t) 0, (int64_t) 0); struct _juliandelta *jdd2 = newJulianDelta('+', (int64_t) 0, (int64_t) 0); - + jdd1 = timeDeltaToJulianDelta(a, dt, jdd1); jdd2 = timeDeltaToJulianDelta(p, dt, jdd2); int64_t d1, d2; - + d1 = (int64_t) 86400000 * jdd1->day + jdd1->ms; d2 = (int64_t) 86400000 * jdd2->day + jdd2->ms; @@ -2098,7 +2168,7 @@ moduloTimedelta(struct _timedelta *a, struct _timedelta *p, int64_t *quot) /** * @brief Return a PT String corresponding to arbitrary number of milliseconds. * - * getPTStringFromMS() translates ms values to ISO 8601 compliant timedelta string. + * getPTStringFromMS() translates ms values to ISO 8601 compliant timedelta string. * Conversion of ms >= 86400000 and ms <= -86400000 not supported. * * @param _ms @@ -2108,16 +2178,16 @@ moduloTimedelta(struct _timedelta *a, struct _timedelta *p, int64_t *quot) * A pointer to char. Translated string is written here. * * @return PTstr - * A pointer to char. The translated TimeDelta string. + * A pointer to char. The translated TimeDelta string. */ char* getPTStringFromMS(int64_t _ms, char* PTstr) { /* Reuse the juliandelta to TimeDelta conversion routine. */ - + /* Create a _juliandelta object and copy the _ms to the jd->ms. */ - struct _juliandelta* jd = NULL; + struct _juliandelta* jd = NULL; /* if ((_ms >= NO_OF_MS_IN_A_DAY) || (_ms <= ((-1)*NO_OF_MS_IN_A_DAY))) */ /* { */ /* /\* ERROR: Conversion greater than 23:59:59:999 not supported. *\/ */ @@ -2125,17 +2195,17 @@ getPTStringFromMS(int64_t _ms, char* PTstr) /* } */ if (_ms >= 0) - jd = newJulianDelta('+', 0, _ms); + jd = newJulianDelta('+', 0, _ms); else jd = newJulianDelta('-', 0, _ms); /* Create dummy variables for julianDeltaToTimeDelta() */ struct _datetime* dumm_base_dt = newDateTime(initDummyDTString); struct _timedelta* dummy_td_return = newTimeDelta(initDummyTDString); - + /* Get the translated TimeDelta and return the corresponding string. */ PTstr = timedeltaToString(julianDeltaToTimeDelta(jd, dumm_base_dt, dummy_td_return), PTstr); - + deallocateDateTime(dumm_base_dt); deallocateTimeDelta(dummy_td_return); if(jd) @@ -2148,7 +2218,7 @@ getPTStringFromMS(int64_t _ms, char* PTstr) /** * @brief Return a PT String corresponding to arbitrary number of seconds. * - * getPTStringFromSeconds() translates second values to ISO 8601 compliant timedelta string. + * getPTStringFromSeconds() translates second values to ISO 8601 compliant timedelta string. * Conversion of s >= 86400 and s <= -86400 not supported. * * @param _s @@ -2158,7 +2228,7 @@ getPTStringFromMS(int64_t _ms, char* PTstr) * A pointer to char. Translated string is written here. * * @return PTstr - * A pointer to char. The translated TimeDelta string. + * A pointer to char. The translated TimeDelta string. */ char* @@ -2171,7 +2241,7 @@ getPTStringFromSeconds(int64_t _s, char* PTstr) /** * @brief Return a PT String corresponding to arbitrary number of seconds. * - * getPTStringFromSecondsFloat() translates second values to ISO 8601 compliant timedelta string. + * getPTStringFromSecondsFloat() translates second values to ISO 8601 compliant timedelta string. * Conversion of s >= 86400 and s <= -86400 not supported. Returned PT string has a precision of 3 * digits. * @@ -2182,7 +2252,7 @@ getPTStringFromSeconds(int64_t _s, char* PTstr) * A pointer to char. Translated string is written here. * * @return PTstr - * A pointer to char. The translated TimeDelta string. + * A pointer to char. The translated TimeDelta string. */ char* @@ -2195,7 +2265,7 @@ getPTStringFromSecondsFloat(float _s, char* PTstr) /** * @brief Return a PT String corresponding to arbitrary number of seconds. * - * getPTStringFromSecondsDouble() translates second values to ISO 8601 compliant timedelta string. + * getPTStringFromSecondsDouble() translates second values to ISO 8601 compliant timedelta string. * Conversion of s >= 86400 and s <= -86400 not supported. Returned PT string has a precision of 3 digits. * * @param _s @@ -2205,7 +2275,7 @@ getPTStringFromSecondsFloat(float _s, char* PTstr) * A pointer to char. Translated string is written here. * * @return PTstr - * A pointer to char. The translated TimeDelta string. + * A pointer to char. The translated TimeDelta string. */ char* @@ -2218,7 +2288,7 @@ getPTStringFromSecondsDouble(double _s, char* PTstr) /** * @brief Return a PT String corresponding to arbitrary number of minutes. * - * getPTStringFromMinutes() translates minutes values to ISO 8601 compliant timedelta string. + * getPTStringFromMinutes() translates minutes values to ISO 8601 compliant timedelta string. * Conversion of m >= 1440 and m <= -1440 not supported. * * @param _m @@ -2228,7 +2298,7 @@ getPTStringFromSecondsDouble(double _s, char* PTstr) * A pointer to char. Translated string is written here. * * @return PTstr - * A pointer to char. The translated TimeDelta string. + * A pointer to char. The translated TimeDelta string. */ char* @@ -2241,7 +2311,7 @@ getPTStringFromMinutes(int64_t _m, char* PTstr) /** * @brief Return a PT String corresponding to arbitrary number of Hours. * - * getPTStringFromHours() translates hour values to ISO 8601 compliant timedelta string. + * getPTStringFromHours() translates hour values to ISO 8601 compliant timedelta string. * Conversion of h >= 24 and ms <= -24 not supported. * * @param _h @@ -2251,7 +2321,7 @@ getPTStringFromMinutes(int64_t _m, char* PTstr) * A pointer to char. Translated string is written here. * * @return PTstr - * A pointer to char. The translated TimeDelta string. + * A pointer to char. The translated TimeDelta string. */ char* -- GitLab