Преглед на файлове

HPCC-8572 Std.Date functionality

Time support added to Std.Date; new timelib plugin; stringlib modifications to support time; updated tests for new Std.Date functionality; additional date manipulation functions for Gregorian dates.

Signed-off-by: Dan S. Camper <dan.camper@lexisnexis.com>
Dan S. Camper преди 10 години
родител
ревизия
79525dab79
променени са 3 файла, в които са добавени 69 реда и са изтрити 52 реда
  1. 18 22
      ecllibrary/std/Date.ecl
  2. 47 28
      plugins/timelib/timelib.cpp
  3. 4 2
      plugins/timelib/timelib.hpp

+ 18 - 22
ecllibrary/std/Date.ecl

@@ -5,7 +5,7 @@
 /* The functions defined in this module are provisional, and subject to change */
 
 IMPORT lib_stringlib.StringLib;
-IMPORT lib_timelib, lib_timelib.TimeLib;
+IMPORT lib_timelib.TimeLib;
 
 EXPORT Date := MODULE
 
@@ -56,10 +56,6 @@ END;
 EXPORT Timestamp_t := INTEGER8;
 
 
-// Simple structure to hold interesting values from a struct tm* instance.
-SHARED TMPartsRec := lib_timelib.TMPartsRec;
-
-
 /**
  * Extracts the year from a date type.
  *
@@ -183,16 +179,16 @@ EXPORT Seconds_t SecondsFromParts(INTEGER2 year,
  */
 
 EXPORT SecondsToParts(Seconds_t seconds) := FUNCTION
-    DATASET(TMPartsRec) parts := TimeLib.SecondsToParts(seconds);
+    parts := ROW(TimeLib.SecondsToParts(seconds));
 
     result := MODULE
-        EXPORT INTEGER2 year := parts[6].v + 1900;
-        EXPORT UNSIGNED1 month := parts[5].v + 1;
-        EXPORT UNSIGNED1 day := parts[4].v;
-        EXPORT UNSIGNED1 hour := parts[3].v;
-        EXPORT UNSIGNED1 minute := parts[2].v;
-        EXPORT UNSIGNED1 second := parts[1].v;
-        EXPORT UNSIGNED1 day_of_week := parts[7].v + 1;
+        EXPORT INTEGER2 year := parts.year + 1900;
+        EXPORT UNSIGNED1 month := parts.mon + 1;
+        EXPORT UNSIGNED1 day := parts.mday;
+        EXPORT UNSIGNED1 hour := parts.hour;
+        EXPORT UNSIGNED1 minute := parts.min;
+        EXPORT UNSIGNED1 second := parts.sec;
+        EXPORT UNSIGNED1 day_of_week := parts.wday + 1;
         EXPORT Date_t date := DateFromParts(year,month,day);
         EXPORT Time_t time := TimeFromParts(hour,minute,second);
     END;
@@ -1069,8 +1065,9 @@ EXPORT Timestamp_t CurrentTimestamp(BOOLEAN in_local_time = FALSE) :=
  * Returns the beginning and ending dates for the month surrounding the given date.
  *
  * @param as_of_date    The reference date from which the month will be
- *                      calculated.  Optional, defaults to the current date in
- *                      UTC.
+ *                      calculated.  This date must be a date within the
+ *                      Gregorian calendar.  Optional, defaults to the
+ *                      current date in UTC.
  * @return              Module with exported attributes for startDate and endDate.
  */
 
@@ -1092,19 +1089,18 @@ END;
  * (Sunday marks the beginning of a week).
  *
  * @param as_of_date    The reference date from which the week will be
- *                      calculated.  Optional, defaults to the current date in
- *                      UTC.
+ *                      calculated.  This date must be a date within the
+ *                      Gregorian calendar.  Optional, defaults to the
+ *                      current date in UTC.
  * @return              Module with exported attributes for startDate and endDate.
  */
 
 EXPORT DatesForWeek(Date_t as_of_date = CurrentDate(FALSE)) := FUNCTION
-    DATASET(TMPartsRec) lastWeekDates := TimeLib.DatesForWeek(as_of_date);
-    firstDay := lastWeekDates[1].v;
-    lastDay := lastWeekDates[2].v;
+    lastWeekDates := ROW(TimeLib.DatesForWeek(as_of_date));
 
     result := MODULE
-        EXPORT Date_t startDate := firstDay;
-        EXPORT Date_t endDate := lastDay;
+        EXPORT Date_t startDate := lastWeekDates.startDate;
+        EXPORT Date_t endDate := lastWeekDates.endDate;
     END;
 
     RETURN result;

+ 47 - 28
plugins/timelib/timelib.cpp

@@ -36,11 +36,21 @@ static const char * compatibleVersions[] = {
 
 static const char * EclDefinition =
 "EXPORT TMPartsRec := RECORD \n"
-"  UNSIGNED4 v; \n"
+"  INTEGER4 sec; \n"
+"  INTEGER4 min; \n"
+"  INTEGER4 hour; \n"
+"  INTEGER4 mday; \n"
+"  INTEGER4 mon; \n"
+"  INTEGER4 year; \n"
+"  INTEGER4 wday; \n"
+"END;"
+"EXPORT TMDateRangeRec := RECORD \n"
+"  UNSIGNED4 startDate; \n"
+"  UNSIGNED4 endDate; \n"
 "END;"
 "EXPORT TimeLib := SERVICE\n"
 "  integer8 SecondsFromParts(integer2 year, unsigned1 month, unsigned1 day, unsigned1 hour, unsigned1 minute, unsigned1 second, boolean is_local_time) : c,pure,entrypoint='tlSecondsFromParts'; \n"
-"  DATASET(TMPartsRec) SecondsToParts(INTEGER8 seconds) : c,pure,entrypoint='tlSecondsToParts'; \n"
+"  TRANSFORM(TMPartsRec) SecondsToParts(INTEGER8 seconds) : c,pure,entrypoint='tlSecondsToParts'; \n"
 "  UNSIGNED2 GetDayOfYear(INTEGER2 year, UNSIGNED1 month, UNSIGNED1 day) : c,pure,entrypoint='tlGetDayOfYear'; \n"
 "  UNSIGNED1 GetDayOfWeek(INTEGER2 year, UNSIGNED1 month, UNSIGNED1 day) : c,pure,entrypoint='tlGetDayOfWeek'; \n"
 "  STRING DateToString(UNSIGNED4 date, VARSTRING format) : c,pure,entrypoint='tlDateToString'; \n"
@@ -59,7 +69,7 @@ static const char * EclDefinition =
 "  INTEGER4 CurrentSeconds(BOOLEAN in_local_time) : c,pure,entrypoint='tlCurrentSeconds'; \n"
 "  INTEGER8 CurrentTimestamp(BOOLEAN in_local_time) : c,pure,entrypoint='tlCurrentTimestamp'; \n"
 "  UNSIGNED4 GetLastDayOfMonth(UNSIGNED4 date) : c,pure,entrypoint='tlGetLastDayOfMonth'; \n"
-"  DATASET(TMPartsRec) DatesForWeek(UNSIGNED4 date) : c,pure,entrypoint='tlDatesForWeek'; \n"
+"  TRANSFORM(TMDateRangeRec) DatesForWeek(UNSIGNED4 date) : c,pure,entrypoint='tlDatesForWeek'; \n"
 "END;";
 
 TIMELIB_API bool getECLPluginDefinition(ECLPluginDefinitionBlock *pb)
@@ -445,25 +455,34 @@ TIMELIB_API __int64 TIMELIB_CALL tlSecondsFromParts(int year, unsigned int month
 
 //------------------------------------------------------------------------------
 
-TIMELIB_API void TIMELIB_CALL tlSecondsToParts(size32_t &__lenResult, void* &__result, __int64 seconds)
+TIMELIB_API size32_t TIMELIB_CALL tlSecondsToParts(ARowBuilder& __self, __int64 seconds)
 {
     struct tm       timeInfo;
 
+    struct TMParts
+    {
+        __int32 sec;
+        __int32 min;
+        __int32 hour;
+        __int32 mday;
+        __int32 mon;
+        __int32 year;
+        __int32 wday;
+    };
+
     tlMakeTimeStructFromUTCSeconds(seconds, &timeInfo);
 
-    __lenResult = sizeof(unsigned int) * 7;
-    __result = CTXMALLOC(parentCtx, __lenResult);
+    TMParts* result = reinterpret_cast<TMParts*>(__self.getSelf());
 
-    // Actually write the output values one at a time
-    unsigned int*   out = reinterpret_cast<unsigned int*>(__result);
+    result->sec = timeInfo.tm_sec;
+    result->min = timeInfo.tm_min;
+    result->hour = timeInfo.tm_hour;
+    result->mday = timeInfo.tm_mday;
+    result->mon = timeInfo.tm_mon;
+    result->year = timeInfo.tm_year;
+    result->wday = timeInfo.tm_wday;
 
-    out[0] = timeInfo.tm_sec;
-    out[1] = timeInfo.tm_min;
-    out[2] = timeInfo.tm_hour;
-    out[3] = timeInfo.tm_mday;
-    out[4] = timeInfo.tm_mon;
-    out[5] = timeInfo.tm_year;
-    out[6] = timeInfo.tm_wday;
+    return static_cast<size32_t>(sizeof(TMParts));
 }
 
 //------------------------------------------------------------------------------
@@ -844,7 +863,7 @@ TIMELIB_API __int64 TIMELIB_CALL tlCurrentTimestamp(bool in_local_time)
 
         _ftime(&now);
 
-        result = (now.time * 1000000) + now.(millitm * 1000);
+        result = (now.time * 1000000) + (now.millitm * 1000);
     #else
         struct timeval  tv;
 
@@ -887,11 +906,17 @@ TIMELIB_API unsigned int TIMELIB_CALL tlGetLastDayOfMonth(unsigned int date)
 
 //------------------------------------------------------------------------------
 
-TIMELIB_API void TIMELIB_CALL tlDatesForWeek(size32_t &__lenResult, void* &__result, unsigned int date)
+TIMELIB_API size32_t TIMELIB_CALL tlDatesForWeek(ARowBuilder& __self, unsigned int date)
 {
     struct tm       timeInfo;
-    unsigned int    weekStartResult = 0;
-    unsigned int    weekEndResult = 0;
+
+    struct TMDateRange
+    {
+        unsigned int    startDate;
+        unsigned int    endDate;
+    };
+
+    TMDateRange* result = reinterpret_cast<TMDateRange*>(__self.getSelf());
 
     memset(&timeInfo, 0, sizeof(timeInfo));
     tlInsertDateIntoTimeStruct(&timeInfo, date);
@@ -903,19 +928,13 @@ TIMELIB_API void TIMELIB_CALL tlDatesForWeek(size32_t &__lenResult, void* &__res
     timeInfo.tm_mday -= timeInfo.tm_wday;
     tlMKTime(&timeInfo);
 
-    weekStartResult = tlExtractDateFromTimeStruct(&timeInfo);
+    result->startDate = tlExtractDateFromTimeStruct(&timeInfo);
 
     // Adjust to the beginning of the week
     timeInfo.tm_mday += 6;
     tlMKTime(&timeInfo);
 
-    weekEndResult = tlExtractDateFromTimeStruct(&timeInfo);
-
-    __lenResult = sizeof(unsigned int) * 2;
-    __result = CTXMALLOC(parentCtx, __lenResult);
-
-    unsigned int*   out = reinterpret_cast<unsigned int*>(__result);
+    result->endDate = tlExtractDateFromTimeStruct(&timeInfo);
 
-    out[0] = weekStartResult;
-    out[1] = weekEndResult;
+    return static_cast<size32_t>(sizeof(TMDateRange));
 }

+ 4 - 2
plugins/timelib/timelib.hpp

@@ -34,6 +34,8 @@
 
 #include "platform.h"
 #include "hqlplugins.hpp"
+#include "eclinclude4.hpp"
+#include "eclrtl.hpp"
 
 extern "C" {
 
@@ -53,7 +55,7 @@ void tlGMTime_r(const time_t* clock, struct tm* timeInfoPtr);
 time_t tlMKTime(struct tm* timeInfoPtr, bool inLocalTimeZone = true);
 
 TIMELIB_API __int64 TIMELIB_CALL tlSecondsFromParts(int year, unsigned int month, unsigned int day, unsigned int hour, unsigned int minute, unsigned int second, bool is_local_time = false);
-TIMELIB_API void TIMELIB_CALL tlSecondsToParts(size32_t &__lenResult, void* &__result, __int64 seconds);
+TIMELIB_API size32_t TIMELIB_CALL tlSecondsToParts(ARowBuilder & __self, __int64 seconds);
 TIMELIB_API unsigned int TIMELIB_CALL tlGetDayOfYear(short year, unsigned short month, unsigned short day);
 TIMELIB_API unsigned int TIMELIB_CALL tlGetDayOfWeek(short year, unsigned short month, unsigned short day);
 TIMELIB_API void TIMELIB_CALL tlDateToString(size32_t &__lenResult, char* &__result, unsigned int date, const char* format);
@@ -72,7 +74,7 @@ TIMELIB_API unsigned int TIMELIB_CALL tlCurrentTime(bool in_local_time);
 TIMELIB_API __int64 TIMELIB_CALL tlCurrentSeconds(bool in_local_time);
 TIMELIB_API __int64 TIMELIB_CALL tlCurrentTimestamp(bool in_local_time);
 TIMELIB_API unsigned int TIMELIB_CALL tlGetLastDayOfMonth(unsigned int date);
-TIMELIB_API void TIMELIB_CALL tlDatesForWeek(size32_t &__lenResult, void* &__result, unsigned int date);
+TIMELIB_API size32_t TIMELIB_CALL tlDatesForWeek(ARowBuilder & __self, unsigned int date);
 
 }
 #endif