diff --git a/include/mtime_timedelta.h b/include/mtime_timedelta.h index 55c1fdc4fdee7d4da9117882c4fbe15156e2ecf3..be6798836b5387b1eea3aecdab28c70d42baee8a 100644 --- a/include/mtime_timedelta.h +++ b/include/mtime_timedelta.h @@ -50,7 +50,7 @@ struct _timedelta /* Used only for storing division of two time-delta results. */ -struct _divisionquotienttimedelta +struct _divisionquotienttimespan { int64_t quotient; int64_t remainder_in_ms; @@ -82,8 +82,11 @@ struct _timedelta* julianDeltaToTimeDelta(struct _juliandelta* jd, struct _datetime *dt, struct _timedelta* td_return); /*! \endcond */ -struct _divisionquotienttimedelta* -divideTimeDeltaInSeconds(struct _timedelta* dividend, struct _timedelta* divisor, struct _divisionquotienttimedelta* quo_ret); +struct _divisionquotienttimespan* +divideTimeDeltaInSeconds(struct _timedelta* dividend, struct _timedelta* divisor, struct _divisionquotienttimespan* quo_ret); + +struct _divisionquotienttimespan* +divideDatetimeDifferenceInSeconds(struct _datetime* dt1, struct _datetime* dt2, struct _timedelta* divisor, struct _divisionquotienttimespan* quo_ret); struct _timedelta* getTimeDeltaFromDate(struct _date*, struct _date*, struct _timedelta*); diff --git a/src/libmtime.f90 b/src/libmtime.f90 index 2394c8a860efd38ff866686f7d91cd5e1a2ca6ca..48aabb791484ed330798117a0cfc6f91f7cb9186 100644 --- a/src/libmtime.f90 +++ b/src/libmtime.f90 @@ -1031,7 +1031,7 @@ module mtime_timedelta ! public :: max_timedelta_str_len public :: timedelta - public :: divisionquotienttimedelta + public :: divisionquotienttimespan public :: newTimedelta public :: deallocateTimedelta public :: getTimeDeltaFromDate @@ -1049,6 +1049,7 @@ module mtime_timedelta public :: elementwiseScalarMultiplyTimeDeltaInv_long public :: elementwiseAddTimeDeltatoTimeDelta public :: divideTimeDeltaInSeconds + public :: divideDatetimeDifferenceInSeconds public :: operator(+) public :: operator(-) public :: operator(*) @@ -1073,10 +1074,10 @@ module mtime_timedelta integer(c_int) :: ms end type timedelta ! - type, bind(c) :: divisionquotienttimedelta + type, bind(c) :: divisionquotienttimespan integer(c_int64_t) :: quotient; integer(c_int64_t) :: remainder_in_ms; - end type divisionquotienttimedelta + end type divisionquotienttimespan ! interface newTimedelta module procedure newtimedeltafromstring @@ -1283,6 +1284,16 @@ module mtime_timedelta type(c_ptr), value :: quotient end function my_divideTimeDeltaInSeconds ! + function my_divideDatetimeDifferenceInSeconds(dt1, dt2, divisor, quotient) result(ret_quotient) & + & bind(c,name='divideDatetimeDifferenceInSeconds') + import :: c_ptr + type(c_ptr) :: ret_quotient + type(c_ptr), value :: dt1 + type(c_ptr), value :: dt2 + type(c_ptr), value :: divisor + type(c_ptr), value :: quotient + end function my_divideDatetimeDifferenceInSeconds + ! end interface ! contains @@ -1625,11 +1636,20 @@ contains subroutine divideTimeDeltaInSeconds(dividend, divisor, quotient) type(timedelta), target, intent(in) :: dividend type(timedelta), target, intent(in) :: divisor - type(divisionquotienttimedelta), target, intent(out) :: quotient + type(divisionquotienttimespan), target, intent(out) :: quotient type(c_ptr) :: dummy_ptr dummy_ptr = my_dividetimedeltainseconds(c_loc(dividend), c_loc(divisor), c_loc(quotient)) end subroutine divideTimeDeltaInSeconds ! + subroutine divideDatetimeDifferenceInSeconds(dt1, dt2, divisor, quotient) + type(datetime), target, intent(in) :: dt1 + type(datetime), target, intent(in) :: dt2 + type(timedelta), target, intent(in) :: divisor + type(divisionquotienttimespan), target, intent(out) :: quotient + type(c_ptr) :: dummy_ptr + dummy_ptr = my_dividedatetimedifferenceinseconds(c_loc(dt1), c_loc(dt2), c_loc(divisor), c_loc(quotient)) + end subroutine divideDatetimeDifferenceInSeconds + ! end module mtime_timedelta !> !! @brief Definition of the basic event type and its methods. diff --git a/src/mtime_timedelta.c b/src/mtime_timedelta.c index a59495ffd14655d91fcf0da2a87dec1129974ce0..07968fbd495b86fd60ee0a4123fadd4b02b4e843 100644 --- a/src/mtime_timedelta.c +++ b/src/mtime_timedelta.c @@ -1067,16 +1067,18 @@ else /*! \endcond */ -struct _divisionquotienttimedelta* -divideTimeDeltaInSeconds(struct _timedelta* dividend, struct _timedelta* divisor, struct _divisionquotienttimedelta* quo_ret) +struct _divisionquotienttimespan* +divideTimeDeltaInSeconds(struct _timedelta* dividend, struct _timedelta* divisor, struct _divisionquotienttimespan* quo_ret) { if ((dividend != NULL) && (divisor != NULL) && (quo_ret != NULL)) { if ((dividend->year == 0) && (dividend->month == 0) && (divisor->year == 0) && (divisor->month == 0)) { - intmax_t numerator = (intmax_t) (((int64_t) dividend->day * 86400 + dividend->minute * 60 + dividend->second) * 1000 + dividend->ms); - intmax_t denominator = (intmax_t) (((int64_t) divisor->day * 86400 + divisor->minute * 60 + divisor->second ) * 1000 + divisor->ms); - + intmax_t numerator = (intmax_t) (((int64_t) dividend->day * 86400 + dividend->hour * 3600 + dividend->minute * 60 + dividend->second) * 1000 + dividend->ms); + intmax_t denominator = (intmax_t) (((int64_t) divisor->day * 86400 + divisor->hour * 3600 +divisor->minute * 60 + divisor->second ) * 1000 + divisor->ms); + + fprintf(stderr, "recalculated in ms: numerator %ld denominator %ld\n", numerator, denominator); + if (denominator == 0) /* Division by zero is illegal. */ return NULL; @@ -1085,12 +1087,68 @@ divideTimeDeltaInSeconds(struct _timedelta* dividend, struct _timedelta* divisor quo_ret->quotient = (int64_t) div.quot; quo_ret->remainder_in_ms = (int64_t) div.rem; + fprintf(stderr, "quotient %ld remainder %ld\n", quo_ret->quotient, quo_ret->remainder_in_ms); + return quo_ret; } else /* Only seconds supported */ + return NULL; + } + else + return NULL; +} + +/** + * @brief division by an interval given in of seconds. + * + * @param refdt + * Reference date (a pointer to struct _datetime). + * @param dt + * A pointer to struct _datetime. + * @param intvlsec + * Interval given in seconds. + * + * @return result of division. NULL indicates error. + */ +struct _divisionquotienttimespan* +divideDatetimeDifferenceInSeconds(struct _datetime* dt1, struct _datetime* dt2, struct _timedelta* divisor, struct _divisionquotienttimespan* quo_ret) +{ + if ((dt1 != NULL) && (dt2 != NULL) && (divisor != NULL) && (quo_ret != NULL)) + { + if ((divisor->year == 0) && (divisor->month == 0)) { - return NULL; + struct _julianday* jd1 = newJulianDay(0, 0); + if (jd1 != NULL) jd1 = date2julian(dt1, jd1); + + struct _julianday* jd2 = newJulianDay(0, 0); + if (jd2 != NULL) jd2 = date2julian(dt2, jd2); + + intmax_t denominator = (intmax_t) (((int64_t) divisor->day * 86400 + divisor->hour * 3600 +divisor->minute * 60 + divisor->second ) * 1000 + divisor->ms); + + if (denominator == 0) /* Division by zero is illegal. */ + return NULL; + + struct _juliandelta* jd = newJulianDelta('+', 0, 0); + jd = substractJulianDay(jd1, jd2, jd); + intmax_t numerator = (intmax_t) (jd->day * 86400000 + jd->ms); + + fprintf(stderr, "recalculated in ms: numerator %ld denominator %ld\n", numerator, denominator); + + imaxdiv_t div = imaxdiv(numerator, denominator); + + quo_ret->quotient = (int64_t) div.quot; + quo_ret->remainder_in_ms = (int64_t) div.rem; + + fprintf(stderr, "quotient %ld remainder %ld\n", quo_ret->quotient, quo_ret->remainder_in_ms); + + if (jd1 != NULL) deallocateJulianDay(jd1); + if (jd2 != NULL) deallocateJulianDay(jd2); + if (jd != NULL) deallocateJulianDelta(jd); + + return quo_ret; } + else + return NULL; } else return NULL;