From 99d82935f3f97baebf58e3d364d79b1e26c8d0e8 Mon Sep 17 00:00:00 2001 From: Thomas Jahns <jahns@dkrz.de> Date: Fri, 15 Jun 2018 11:37:25 +0200 Subject: [PATCH] Fix incorrect iteration direction. * + timedelta incorrectly used descending, - timedelta ascending iteration through leap years. --- src/mtime_timedelta.c | 90 ++++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/src/mtime_timedelta.c b/src/mtime_timedelta.c index d1f18630..a45d80d5 100644 --- a/src/mtime_timedelta.c +++ b/src/mtime_timedelta.c @@ -895,9 +895,9 @@ julianDeltaToTimeDelta(struct _juliandelta* jd, struct _datetime* base_dt, struc /* No of days in the final year */ int64_t delta_final_year; int64_t days = (-1)*jd->day; - /* Set counter to base year and then jump forward to get to the final year. - For each loop forward, increment year by 1. - */ + /* Set counter to base year and then iterate backward to get to the final year. + For each loop forward, increment year by 1. + */ int64_t j = base_dt->date.year; /* Initialize to 0. */ td_return->year = 0; @@ -921,16 +921,16 @@ julianDeltaToTimeDelta(struct _juliandelta* jd, struct _datetime* base_dt, struc /* The crucial point is month of february. */ delta_final_year = days; if ( - ( (testYearIsLeapYear(j + 1)) && (base_dt->date.month >= 3) ) - || - ( (testYearIsLeapYear(j)) && (base_dt->date.month < 3) ) - ) + ( (testYearIsLeapYear(j)) && (base_dt->date.month >= 3) ) + || + ( (testYearIsLeapYear(j-1)) && (base_dt->date.month < 3) ) + ) { - /* If next year is leap year and base 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 year is leap year and base month is >= 3 + OR + next year is a leap year and month is < 3 + => delta of 1 year corresponds to 366 day julian delta. + */ days = days - NO_OF_DAYS_IN_A_LEAP_YEAR; } else @@ -939,27 +939,30 @@ julianDeltaToTimeDelta(struct _juliandelta* jd, struct _datetime* base_dt, struc days = days - NO_OF_DAYS_IN_A_YEAR_FOR_CAL_TYPE365; } td_return->year++; - j++; - }while (days >= 0); + j--; + } while (days >= 0); + /* The loop ran one time too much. */ + if (days < 0) { td_return->year--; - j--; + j++; } /* In final year, the crucial point is the month of february. */ + if ( - ((testYearIsLeapYear(j + 1)) && (base_dt->date.month >= 3)) - || - ((testYearIsLeapYear(j)) && (base_dt->date.month < 3)) - ) + ((testYearIsLeapYear(j)) && (base_dt->date.month >= 3)) + || + ((testYearIsLeapYear(j-1)) && (base_dt->date.month < 3)) + ) { - /* If final year's next year is a leap year and base month is >= 3 - OR - final year is a leap year and month is < 3 - => An addition of leap-year specific delta for each month. - */ + /* If final year is a leap year and base month is >= 3 + OR + year preceding final year is a leap year and month is < 3 + => An addition of leap-year specific delta for each month. + */ msdinm = monthSpecificDeltaInMonthsLeapyear; ndiny = NO_OF_DAYS_IN_A_LEAP_YEAR; } @@ -1020,15 +1023,15 @@ julianDeltaToTimeDelta(struct _juliandelta* jd, struct _datetime* base_dt, struc /* The crucial point is month of february. */ delta_final_year = days; if ( - ((testYearIsLeapYear(j - 1)) && (base_dt->date.month < 3)) - || - ((testYearIsLeapYear(j)) && (base_dt->date.month >= 3)) - ) + ((testYearIsLeapYear(j+1)) && (base_dt->date.month >= 3)) + || + ((testYearIsLeapYear(j)) && (base_dt->date.month < 3)) + ) { - /* If previous year is leap year and base 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 next year is leap year and base month is < 3 + OR + this year is a leap year and month is < 3 + => delta of 1 year corresponds to 366 day julian delta. */ days = days - NO_OF_DAYS_IN_A_LEAP_YEAR; } @@ -1039,26 +1042,27 @@ julianDeltaToTimeDelta(struct _juliandelta* jd, struct _datetime* base_dt, struc } td_return->year++; - j--; - }while (days >= 0); + j++; + } while (days >= 0); + /* The loop ran one time too much. */ if (days < 0) { td_return->year--; - j++; + j--; } /* In final year, the crucial point is the month of february. */ if ( - ((testYearIsLeapYear(j - 1)) && (base_dt->date.month < 3)) - || - ((testYearIsLeapYear(j)) && (base_dt->date.month >= 3)) - ) + ((testYearIsLeapYear(j+1)) && (base_dt->date.month >= 3)) + || + ((testYearIsLeapYear(j)) && (base_dt->date.month < 3)) + ) { - /* If final year is a leap year and base month is >= 3 - OR - final year's previous year is a leap year and month is < 3 - => An addition of leap-year specific delta for each month. + /* If final year is a leap year and base month is >= 3 + OR + final year's previous year is a leap year and month is < 3 + => An addition of leap-year specific delta for each month. */ msdinm = monthSpecificDeltaInMonthsLeapyear; ndiny = NO_OF_DAYS_IN_A_LEAP_YEAR; -- GitLab