Bläddra i källkod

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 år sedan
förälder
incheckning
7c01515ab8
2 ändrade filer med 8 tillägg och 0 borttagningar
  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);