Browse Source

HPCC-23124 Take DST into account in Std.Date functions DatesForWeek, AdjustCalendar, and DatesForMonth

In the full time structure, dates are forced to midnight for these functions.  Changes in DST (specifically when "falling back" an hour) between the beginning and ending dates could cause a computed date to be one off.

Signed-off-by: Dan S. Camper <dan.camper@lexisnexisrisk.com>
Dan S. Camper 5 years ago
parent
commit
7c01515ab8
2 changed files with 8 additions and 0 deletions
  1. 3 0
      ecllibrary/teststd/Date/TestDate.ecl
  2. 5 0
      plugins/timelib/timelib.cpp

+ 3 - 0
ecllibrary/teststd/Date/TestDate.ecl

@@ -258,6 +258,7 @@ EXPORT TestDate := MODULE
     ASSERT(Date.AdjustCalendar(20170201, month_delta:=24) = 20190201);
     ASSERT(Date.AdjustCalendar(20000229, year_delta:=1) = 20010228);
     ASSERT(Date.AdjustCalendar(20000229, year_delta:=4) = 20040229);
+    ASSERT(Date.AdjustCalendar(20191103, day_delta:=5) = 20191108); // HPCC-23124
 
     ASSERT(vSeconds + vLocalTimeZoneOffset BETWEEN vSecondsLocal-1 AND vSecondsLocal+1);
 
@@ -270,9 +271,11 @@ EXPORT TestDate := MODULE
 
     ASSERT(Date.DatesForMonth(20141215).startDate = 20141201);
     ASSERT(Date.DatesForMonth(20141215).endDate = 20141231);
+    ASSERT(Date.DatesForMonth(20191103).endDate = 20191130); // HPCC-23124
 
     ASSERT(Date.DatesForWeek(20141030).startDate = 20141026);
     ASSERT(Date.DatesForWeek(20141030).endDate = 20141101);
+    ASSERT(Date.DatesForWeek(20191103).endDate = 20191109); // HPCC-23124
 
     ASSERT(Date.IsValidDate(vDate, 2014, 2050));
     ASSERT(NOT Date.IsValidDate(vDate, 2000, 2010));

+ 5 - 0
plugins/timelib/timelib.cpp

@@ -830,6 +830,7 @@ TIMELIB_API unsigned int TIMELIB_CALL tlAdjustCalendar(unsigned int date, short
         // If the returned month doesn't match the expected month, we need to
         // go back to the last day of the previous month
         timeInfo.tm_mday = 0;
+        timeInfo.tm_isdst = -1; // in case DST is different
         tlMKTime(&timeInfo);
     }
 
@@ -837,6 +838,7 @@ TIMELIB_API unsigned int TIMELIB_CALL tlAdjustCalendar(unsigned int date, short
     {
         // Now apply the day delta
         timeInfo.tm_mday += day_delta;
+        timeInfo.tm_isdst = -1; // in case DST is different
         tlMKTime(&timeInfo);
     }
 
@@ -985,6 +987,7 @@ TIMELIB_API unsigned int TIMELIB_CALL tlGetLastDayOfMonth(unsigned int date)
     // Adjust and call again
     timeInfo.tm_mon += 1;
     timeInfo.tm_mday = 0;
+    timeInfo.tm_isdst = -1; // in case DST is different
     tlMKTime(&timeInfo);
 
     result = tlExtractDateFromTimeStruct(&timeInfo);
@@ -1015,12 +1018,14 @@ TIMELIB_API size32_t TIMELIB_CALL tlDatesForWeek(ARowBuilder& __self, unsigned i
 
     // Adjust and call again
     timeInfo.tm_mday -= timeInfo.tm_wday;
+    timeInfo.tm_isdst = -1; // in case DST is different
     tlMKTime(&timeInfo);
 
     result->startDate = tlExtractDateFromTimeStruct(&timeInfo);
 
     // Adjust to the beginning of the week
     timeInfo.tm_mday += 6;
+    timeInfo.tm_isdst = -1; // in case DST is different
     tlMKTime(&timeInfo);
 
     result->endDate = tlExtractDateFromTimeStruct(&timeInfo);