|
@@ -35,29 +35,29 @@ static const char * compatibleVersions[] = {
|
|
|
#define TIMELIB_VERSION "TIMELIB 1.0.0"
|
|
|
|
|
|
static const char * EclDefinition =
|
|
|
-"export TMPartsRec := RECORD \n"
|
|
|
+"EXPORT TMPartsRec := RECORD \n"
|
|
|
" UNSIGNED4 v; \n"
|
|
|
"END;"
|
|
|
-"export TimeLib := SERVICE\n"
|
|
|
-" integer4 SecondsFromParts(integer2 year, unsigned1 month, unsigned1 day, unsigned1 hour, unsigned1 minute, unsigned1 second, boolean is_local_time) : c,pure,entrypoint='tlSecondsFromParts'; \n"
|
|
|
+"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"
|
|
|
" 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"
|
|
|
" STRING TimeToString(UNSIGNED3 time, VARSTRING format) : c,pure,entrypoint='tlTimeToString'; \n"
|
|
|
-" STRING SecondsToString(INTEGER4 seconds, VARSTRING format) : c,pure,entrypoint='tlSecondsToString'; \n"
|
|
|
+" STRING SecondsToString(INTEGER8 seconds, VARSTRING format) : c,pure,entrypoint='tlSecondsToString'; \n"
|
|
|
" UNSIGNED4 AdjustDate(UNSIGNED4 date, INTEGER2 year_delta, INTEGER4 month_delta, INTEGER4 day_delta) : c,pure,entrypoint='tlAdjustDate'; \n"
|
|
|
" UNSIGNED4 AdjustDateBySeconds(UNSIGNED4 date, INTEGER4 seconds_delta) : c,pure,entrypoint='tlAdjustDateBySeconds'; \n"
|
|
|
" UNSIGNED3 AdjustTime(UNSIGNED3 time, INTEGER2 hour_delta, INTEGER4 minute_delta, INTEGER4 second_delta) : c,pure,entrypoint='tlAdjustTime'; \n"
|
|
|
" UNSIGNED3 AdjustTimeBySeconds(UNSIGNED3 time, INTEGER4 seconds_delta) : c,pure,entrypoint='tlAdjustTimeBySeconds'; \n"
|
|
|
-" INTEGER4 AdjustSeconds(INTEGER4 seconds, INTEGER2 year_delta, INTEGER4 month_delta, INTEGER4 day_delta, INTEGER2 hour_delta, INTEGER4 minute_delta, INTEGER4 second_delta) : c,pure,entrypoint='tlAdjustSeconds'; \n"
|
|
|
+" INTEGER4 AdjustSeconds(INTEGER8 seconds, INTEGER2 year_delta, INTEGER4 month_delta, INTEGER4 day_delta, INTEGER2 hour_delta, INTEGER4 minute_delta, INTEGER4 second_delta) : c,pure,entrypoint='tlAdjustSeconds'; \n"
|
|
|
" UNSIGNED4 AdjustCalendar(UNSIGNED4 date, INTEGER2 year_delta, INTEGER4 month_delta, INTEGER4 day_delta) : c,pure,entrypoint='tlAdjustCalendar'; \n"
|
|
|
" BOOLEAN IsLocalDaylightSavingsInEffect() : c,pure,entrypoint='tlIsLocalDaylightSavingsInEffect'; \n"
|
|
|
" INTEGER4 LocalTimeZoneOffset() : c,pure,entrypoint='tlLocalTimeZoneOffset'; \n"
|
|
|
" UNSIGNED4 CurrentDate(BOOLEAN in_local_time) : c,pure,entrypoint='tlCurrentDate'; \n"
|
|
|
" UNSIGNED4 CurrentTime(BOOLEAN in_local_time) : c,pure,entrypoint='tlCurrentTime'; \n"
|
|
|
" INTEGER4 CurrentSeconds(BOOLEAN in_local_time) : c,pure,entrypoint='tlCurrentSeconds'; \n"
|
|
|
-" REAL8 CurrentTimestamp(BOOLEAN in_local_time) : c,pure,entrypoint='tlCurrentTimestamp'; \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"
|
|
|
"END;";
|
|
@@ -86,16 +86,297 @@ TIMELIB_API void setPluginContext(IPluginContext * _ctx) { parentCtx = _ctx; }
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
-void tlMakeTimeStructFromUTCSeconds(time_t seconds, struct tm* timeInfo)
|
|
|
+#ifdef _WINDOWS
|
|
|
+ const __int64 _onesec_in100ns = (__int64)10000000;
|
|
|
+
|
|
|
+ __int64 tlFileTimeToInt64(FILETIME f)
|
|
|
+ {
|
|
|
+ __int64 seconds;
|
|
|
+
|
|
|
+ seconds = f.dwHighDateTime;
|
|
|
+ seconds <<= 32;
|
|
|
+ seconds |= f.dwLowDateTime;
|
|
|
+
|
|
|
+ return seconds;
|
|
|
+ }
|
|
|
+
|
|
|
+ FILETIME tlInt64ToFileTime(__int64 seconds)
|
|
|
+ {
|
|
|
+ FILETIME f;
|
|
|
+
|
|
|
+ f.dwHighDateTime = (DWORD)((seconds >> 32) & 0x00000000FFFFFFFF);
|
|
|
+ f.dwLowDateTime = (DWORD)(seconds & 0x00000000FFFFFFFF);
|
|
|
+
|
|
|
+ return f;
|
|
|
+ }
|
|
|
+
|
|
|
+ FILETIME tlFileTimeFromYear(WORD year)
|
|
|
+ {
|
|
|
+ SYSTEMTIME s;
|
|
|
+ FILETIME f;
|
|
|
+
|
|
|
+ memset(&s, 0, sizeof(s));
|
|
|
+
|
|
|
+ s.wYear = year;
|
|
|
+ s.wMonth = 1;
|
|
|
+ s.wDayOfWeek = 1;
|
|
|
+ s.wDay = 1;
|
|
|
+
|
|
|
+ SystemTimeToFileTime(&s, &f);
|
|
|
+
|
|
|
+ return f;
|
|
|
+ }
|
|
|
+
|
|
|
+ unsigned int tlYearDayFromSystemTime(const SYSTEMTIME* s)
|
|
|
+ {
|
|
|
+ __int64 seconds;
|
|
|
+ FILETIME f1;
|
|
|
+ FILETIME f2;
|
|
|
+
|
|
|
+ f1 = tlFileTimeFromYear(s->wYear);
|
|
|
+ SystemTimeToFileTime(s, &f2);
|
|
|
+
|
|
|
+ seconds = tlFileTimeToInt64(f2) - tlFileTimeToInt64(f1);
|
|
|
+
|
|
|
+ return static_cast<unsigned int>((seconds / _onesec_in100ns) / (60 * 60 * 24));
|
|
|
+ }
|
|
|
+
|
|
|
+ SYSTEMTIME tlTimeStructToSystemTime(struct tm* timeInfoPtr)
|
|
|
+ {
|
|
|
+ SYSTEMTIME s;
|
|
|
+
|
|
|
+ s.wYear = timeInfoPtr->tm_year + 1900;
|
|
|
+ s.wMonth = timeInfoPtr->tm_mon + 1;
|
|
|
+ s.wDayOfWeek = timeInfoPtr->tm_wday;
|
|
|
+ s.wDay = timeInfoPtr->tm_mday;
|
|
|
+ s.wHour = timeInfoPtr->tm_hour;
|
|
|
+ s.wMinute = timeInfoPtr->tm_min;
|
|
|
+ s.wSecond = timeInfoPtr->tm_sec;
|
|
|
+ s.wMilliseconds = 0;
|
|
|
+
|
|
|
+ return s;
|
|
|
+ }
|
|
|
+
|
|
|
+ void tlSystemTimeToTimeStruct_r(SYSTEMTIME* s, struct tm* timeInfoPtr)
|
|
|
+ {
|
|
|
+ memset(timeInfoPtr, 0, sizeof(struct tm));
|
|
|
+
|
|
|
+ timeInfoPtr->tm_year = s->wYear - 1900;
|
|
|
+ timeInfoPtr->tm_mon = s->wMonth - 1;
|
|
|
+ timeInfoPtr->tm_wday = s->wDayOfWeek;
|
|
|
+ timeInfoPtr->tm_mday = s->wDay;
|
|
|
+ timeInfoPtr->tm_yday = tlYearDayFromSystemTime(s);
|
|
|
+ timeInfoPtr->tm_hour = s->wHour;
|
|
|
+ timeInfoPtr->tm_min = s->wMinute;
|
|
|
+ timeInfoPtr->tm_sec = s->wSecond;
|
|
|
+ timeInfoPtr->tm_isdst = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ time_t tlFileTimeToSeconds(const FILETIME* f)
|
|
|
+ {
|
|
|
+ __int64 offset = 11644473600; // Number of seconds between 1601 and 1970 (Jan 1 of each)
|
|
|
+ __int64 seconds;
|
|
|
+
|
|
|
+ seconds = tlFileTimeToInt64(*f) - offset;
|
|
|
+
|
|
|
+ return static_cast<time_t>(seconds / _onesec_in100ns);
|
|
|
+ }
|
|
|
+
|
|
|
+ FILETIME tlSecondsToFileTime(const time_t seconds)
|
|
|
+ {
|
|
|
+ FILETIME f1970 = tlFileTimeFromYear(1970);
|
|
|
+ FILETIME f;
|
|
|
+ __int64 time;
|
|
|
+
|
|
|
+ time = (seconds * _onesec_in100ns) + tlFileTimeToInt64(f1970);
|
|
|
+
|
|
|
+ f = tlInt64ToFileTime(time);
|
|
|
+
|
|
|
+ return f;
|
|
|
+ }
|
|
|
+
|
|
|
+ __int64 tlLocalTimeDiff()
|
|
|
+ {
|
|
|
+ SYSTEMTIME systemUTC;
|
|
|
+ SYSTEMTIME systemLocal;
|
|
|
+ FILETIME fileUTC;
|
|
|
+ FILETIME fileLocal;
|
|
|
+
|
|
|
+ GetSystemTime(&systemUTC);
|
|
|
+ GetLocalTime(&systemLocal);
|
|
|
+
|
|
|
+ SystemTimeToFileTime(&systemUTC, &fileUTC);
|
|
|
+ SystemTimeToFileTime(&systemLocal, &fileLocal);
|
|
|
+
|
|
|
+ return tlFileTimeToInt64(fileUTC) - tlFileTimeToInt64(fileLocal);
|
|
|
+ }
|
|
|
+
|
|
|
+ void tlBoundaryMod(int* tensPtr, int* unitsPtr, int base)
|
|
|
+ {
|
|
|
+ if (*unitsPtr >= base)
|
|
|
+ {
|
|
|
+ *tensPtr += *unitsPtr / base;
|
|
|
+ *unitsPtr %= base;
|
|
|
+ }
|
|
|
+ else if (*unitsPtr < 0)
|
|
|
+ {
|
|
|
+ --*tensPtr;
|
|
|
+ *unitsPtr += base;
|
|
|
+ if (*unitsPtr < 0)
|
|
|
+ {
|
|
|
+ *tensPtr -= 1 + (-*unitsPtr) / base;
|
|
|
+ *unitsPtr = base - (-*unitsPtr) % base;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void tlNormalizeTimeStruct(struct tm* timeInfoPtr)
|
|
|
+ {
|
|
|
+ // Normalize incoming struct tm
|
|
|
+ const int secondsPerMinute = 60;
|
|
|
+ const int minutesPerHour = 60;
|
|
|
+ const int hoursPerDay = 24;
|
|
|
+ const int daysPerWeek = 7;
|
|
|
+ const int daysPerNYear = 365;
|
|
|
+ const int daysPerLYear = 366;
|
|
|
+ const int yearLengths[2] = { daysPerNYear, daysPerLYear };
|
|
|
+ const int secondsPerHour = secondsPerMinute * minutesPerHour;
|
|
|
+ const long secondsPerDay = secondsPerHour * hoursPerDay;
|
|
|
+ const int monthsPerYear = 12;
|
|
|
+ const int yearBase = 1900;
|
|
|
+ const int monthLengths[2][monthsPerYear] = { { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } };
|
|
|
+
|
|
|
+ tlBoundaryMod(&timeInfoPtr->tm_min, &timeInfoPtr->tm_sec, secondsPerMinute);
|
|
|
+ tlBoundaryMod(&timeInfoPtr->tm_hour, &timeInfoPtr->tm_min, minutesPerHour);
|
|
|
+ tlBoundaryMod(&timeInfoPtr->tm_mday, &timeInfoPtr->tm_hour, hoursPerDay);
|
|
|
+ tlBoundaryMod(&timeInfoPtr->tm_year, &timeInfoPtr->tm_mon, monthsPerYear);
|
|
|
+
|
|
|
+ while (timeInfoPtr->tm_mday <= 0)
|
|
|
+ {
|
|
|
+ --timeInfoPtr->tm_year;
|
|
|
+ int isLeapYear = ((((timeInfoPtr->tm_year + yearBase) % 4) == 0 && ((timeInfoPtr->tm_year + yearBase) % 100) != 0) || ((timeInfoPtr->tm_year + yearBase) % 400) == 0);
|
|
|
+ timeInfoPtr->tm_mday += yearLengths[isLeapYear];
|
|
|
+ }
|
|
|
+
|
|
|
+ for (;;)
|
|
|
+ {
|
|
|
+ int isLeapYear = ((((timeInfoPtr->tm_year + yearBase) % 4) == 0 && ((timeInfoPtr->tm_year + yearBase) % 100) != 0) || ((timeInfoPtr->tm_year + yearBase) % 400) == 0);
|
|
|
+ int i = monthLengths[isLeapYear][timeInfoPtr->tm_mon];
|
|
|
+
|
|
|
+ if (timeInfoPtr->tm_mday <= i)
|
|
|
+ break;
|
|
|
+ timeInfoPtr->tm_mday -= i;
|
|
|
+ if (++timeInfoPtr->tm_mon >= monthsPerYear)
|
|
|
+ {
|
|
|
+ timeInfoPtr->tm_mon = 0;
|
|
|
+ ++timeInfoPtr->tm_year;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+//---------------------------
|
|
|
+
|
|
|
+ void tlWinLocalTime_r(const time_t* clock, struct tm* timeInfoPtr)
|
|
|
+ {
|
|
|
+ SYSTEMTIME s;
|
|
|
+ FILETIME f;
|
|
|
+ __int64 time;
|
|
|
+
|
|
|
+ f = tlSecondsToFileTime(*clock);
|
|
|
+ time = tlFileTimeToInt64(f) - tlLocalTimeDiff();
|
|
|
+ f = tlInt64ToFileTime(time);
|
|
|
+
|
|
|
+ FileTimeToSystemTime(&f, &s);
|
|
|
+
|
|
|
+ tlSystemTimeToTimeStruct_r(&s, timeInfoPtr);
|
|
|
+ }
|
|
|
+
|
|
|
+ void tlWinGMTime_r(const time_t* clock, struct tm* timeInfo)
|
|
|
+ {
|
|
|
+ FILETIME f;
|
|
|
+ SYSTEMTIME s;
|
|
|
+
|
|
|
+ f = tlSecondsToFileTime(*clock);
|
|
|
+ FileTimeToSystemTime(&f, &s);
|
|
|
+ tlSystemTimeToTimeStruct_r(&s, timeInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ time_t tlWinMKTime(struct tm* timeInfoPtr)
|
|
|
+ {
|
|
|
+ SYSTEMTIME s;
|
|
|
+ FILETIME f;
|
|
|
+ time_t diff;
|
|
|
+
|
|
|
+ // Windows apparently doesn't normalize/fix bogus date values before
|
|
|
+ // doing conversions, so we need to normalize them first
|
|
|
+ tlNormalizeTimeStruct(timeInfoPtr);
|
|
|
+
|
|
|
+ s = tlTimeStructToSystemTime(timeInfoPtr);
|
|
|
+ SystemTimeToFileTime(&s, &f);
|
|
|
+
|
|
|
+ // Reset day of week
|
|
|
+ FileTimeToSystemTime(&f, &s);
|
|
|
+ timeInfoPtr->wday = s.wDayOfWeek;
|
|
|
+
|
|
|
+ diff = tlLocalTimeDiff() / _onesec_in100ns;
|
|
|
+
|
|
|
+ return tlFileTimeToSeconds(&f) - diff;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+//------------------------------------------------------------------------------
|
|
|
+
|
|
|
+void tlLocalTime_r(const time_t* clock, struct tm* timeInfoPtr)
|
|
|
{
|
|
|
#ifdef _WINDOWS
|
|
|
- // gmtime is thread-safe under Windows
|
|
|
- memcpy(timeInfo,gmtime(&seconds),sizeof(&timeInfo));
|
|
|
+ tlWinLocalTime_r(clock, timeInfoPtr);
|
|
|
#else
|
|
|
- gmtime_r(&seconds,timeInfo);
|
|
|
+ localtime_r(clock, timeInfoPtr);
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+void tlGMTime_r(const time_t* clock, struct tm* timeInfoPtr)
|
|
|
+{
|
|
|
+ #ifdef _WINDOWS
|
|
|
+ tlWinGMTime_r(clock, timeInfoPtr);
|
|
|
+ #else
|
|
|
+ gmtime_r(clock, timeInfoPtr);
|
|
|
+ #endif
|
|
|
+}
|
|
|
+
|
|
|
+time_t tlMKTime(struct tm* timeInfoPtr, bool inLocalTimeZone)
|
|
|
+{
|
|
|
+ time_t the_time = 0;
|
|
|
+
|
|
|
+ #ifdef _WINDOWS
|
|
|
+ the_time = tlWinMKTime(timeInfoPtr);
|
|
|
+
|
|
|
+ if (!inLocalTimeZone)
|
|
|
+ {
|
|
|
+ // Adjust for time zone offset
|
|
|
+ the_time += (tlLocalTimeZoneDiffIn100nsIntervals() / _onesec_in100ns);
|
|
|
+ }
|
|
|
+ #else
|
|
|
+ // Get the initial time components; note that mktime assumes local time
|
|
|
+ the_time = mktime(timeInfoPtr);
|
|
|
+
|
|
|
+ if (!inLocalTimeZone)
|
|
|
+ {
|
|
|
+ // Adjust for time zone offset
|
|
|
+ the_time += timeInfoPtr->tm_gmtoff;
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+
|
|
|
+ return the_time;
|
|
|
+}
|
|
|
+
|
|
|
+//------------------------------------------------------------------------------
|
|
|
+
|
|
|
+void tlMakeTimeStructFromUTCSeconds(time_t seconds, struct tm* timeInfo)
|
|
|
+{
|
|
|
+ tlGMTime_r(&seconds, timeInfo);
|
|
|
+}
|
|
|
+
|
|
|
void tlInsertDateIntoTimeStruct(struct tm* timeInfo, unsigned int date)
|
|
|
{
|
|
|
unsigned int year = date / 10000;
|
|
@@ -142,12 +423,12 @@ unsigned int tlExtractTimeFromTimeStruct(struct tm* timeInfo)
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
-TIMELIB_API time_t TIMELIB_CALL tlSecondsFromParts(int year, unsigned int month, unsigned int day, unsigned int hour, unsigned int minute, unsigned int second, bool is_local_time)
|
|
|
+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)
|
|
|
{
|
|
|
struct tm timeInfo;
|
|
|
time_t the_time = 0;
|
|
|
|
|
|
- memset(&timeInfo,0,sizeof(timeInfo));
|
|
|
+ memset(&timeInfo, 0, sizeof(timeInfo));
|
|
|
|
|
|
// Push each time part value into the tm struct
|
|
|
timeInfo.tm_sec = second;
|
|
@@ -157,21 +438,14 @@ TIMELIB_API time_t TIMELIB_CALL tlSecondsFromParts(int year, unsigned int month,
|
|
|
timeInfo.tm_mon = month - 1;
|
|
|
timeInfo.tm_year = year - 1900;
|
|
|
|
|
|
- // Get the initial time components; note that mktime assumes local time
|
|
|
- the_time = mktime(&timeInfo);
|
|
|
+ the_time = tlMKTime(&timeInfo, is_local_time);
|
|
|
|
|
|
- if (!is_local_time)
|
|
|
- {
|
|
|
- // Adjust for time zone offset
|
|
|
- the_time += timeInfo.tm_gmtoff;
|
|
|
- }
|
|
|
-
|
|
|
- return the_time;
|
|
|
+ return static_cast<__int64>(the_time);
|
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
-TIMELIB_API void TIMELIB_CALL tlSecondsToParts(size32_t &__lenResult, void* &__result, time_t seconds)
|
|
|
+TIMELIB_API void TIMELIB_CALL tlSecondsToParts(size32_t &__lenResult, void* &__result, __int64 seconds)
|
|
|
{
|
|
|
struct tm timeInfo;
|
|
|
|
|
@@ -196,18 +470,34 @@ TIMELIB_API void TIMELIB_CALL tlSecondsToParts(size32_t &__lenResult, void* &__r
|
|
|
|
|
|
TIMELIB_API unsigned int TIMELIB_CALL tlGetDayOfYear(short year, unsigned short month, unsigned short day)
|
|
|
{
|
|
|
- struct tm timeInfo;
|
|
|
+ unsigned int dayOfYear = 0;
|
|
|
|
|
|
- memset(&timeInfo,0,sizeof(timeInfo));
|
|
|
+ #ifdef _WINDOWS
|
|
|
+ SYSTEMTIME s;
|
|
|
|
|
|
- // Push each time part value into the tm struct
|
|
|
- timeInfo.tm_mday = day;
|
|
|
- timeInfo.tm_mon = month - 1;
|
|
|
- timeInfo.tm_year = year - 1900;
|
|
|
+ memset(&s, 0, sizeof(s));
|
|
|
+
|
|
|
+ s.wYear = year;
|
|
|
+ s.wMonth = month;
|
|
|
+ s.wDay = day;
|
|
|
+
|
|
|
+ dayOfYear = tlYearDayFromSystemTime(&s);
|
|
|
+ #else
|
|
|
+ struct tm timeInfo;
|
|
|
+
|
|
|
+ memset(&timeInfo, 0, sizeof(timeInfo));
|
|
|
|
|
|
- mktime(&timeInfo);
|
|
|
+ // Push each time part value into the tm struct
|
|
|
+ timeInfo.tm_mday = day;
|
|
|
+ timeInfo.tm_mon = month - 1;
|
|
|
+ timeInfo.tm_year = year - 1900;
|
|
|
|
|
|
- return timeInfo.tm_yday;
|
|
|
+ tlMKTime(&timeInfo);
|
|
|
+
|
|
|
+ dayOfYear = timeInfo.tm_yday;
|
|
|
+ #endif
|
|
|
+
|
|
|
+ return dayOfYear;
|
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
@@ -216,14 +506,14 @@ TIMELIB_API unsigned int TIMELIB_CALL tlGetDayOfWeek(short year, unsigned short
|
|
|
{
|
|
|
struct tm timeInfo;
|
|
|
|
|
|
- memset(&timeInfo,0,sizeof(timeInfo));
|
|
|
+ memset(&timeInfo, 0, sizeof(timeInfo));
|
|
|
|
|
|
// Push each time part value into the tm struct
|
|
|
timeInfo.tm_mday = day;
|
|
|
timeInfo.tm_mon = month - 1;
|
|
|
timeInfo.tm_year = year - 1900;
|
|
|
|
|
|
- mktime(&timeInfo);
|
|
|
+ tlMKTime(&timeInfo);
|
|
|
|
|
|
return timeInfo.tm_wday;
|
|
|
}
|
|
@@ -236,16 +526,16 @@ TIMELIB_API void TIMELIB_CALL tlDateToString(size32_t &__lenResult, char* &__res
|
|
|
size_t kBufferSize = 256;
|
|
|
char buffer[kBufferSize];
|
|
|
|
|
|
- memset(&timeInfo,0,sizeof(timeInfo));
|
|
|
- tlInsertDateIntoTimeStruct(&timeInfo,date);
|
|
|
+ memset(&timeInfo, 0, sizeof(timeInfo));
|
|
|
+ tlInsertDateIntoTimeStruct(&timeInfo, date);
|
|
|
|
|
|
- __lenResult = strftime(buffer,kBufferSize,format,&timeInfo);
|
|
|
+ __lenResult = strftime(buffer, kBufferSize, format, &timeInfo);
|
|
|
__result = NULL;
|
|
|
|
|
|
if (__lenResult > 0)
|
|
|
{
|
|
|
__result = reinterpret_cast<char*>(CTXMALLOC(parentCtx, __lenResult));
|
|
|
- memcpy(__result,buffer,__lenResult);
|
|
|
+ memcpy(__result, buffer, __lenResult);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -257,44 +547,39 @@ TIMELIB_API void TIMELIB_CALL tlTimeToString(size32_t &__lenResult, char* &__res
|
|
|
size_t kBufferSize = 256;
|
|
|
char buffer[kBufferSize];
|
|
|
|
|
|
- memset(&timeInfo,0,sizeof(timeInfo));
|
|
|
- tlInsertTimeIntoTimeStruct(&timeInfo,time);
|
|
|
+ memset(&timeInfo, 0, sizeof(timeInfo));
|
|
|
+ tlInsertTimeIntoTimeStruct(&timeInfo, time);
|
|
|
|
|
|
- __lenResult = strftime(buffer,kBufferSize,format,&timeInfo);
|
|
|
+ __lenResult = strftime(buffer, kBufferSize, format, &timeInfo);
|
|
|
__result = NULL;
|
|
|
|
|
|
if (__lenResult > 0)
|
|
|
{
|
|
|
__result = reinterpret_cast<char*>(rtlMalloc(__lenResult));
|
|
|
- memcpy(__result,buffer,__lenResult);
|
|
|
+ memcpy(__result, buffer, __lenResult);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
-TIMELIB_API void TIMELIB_CALL tlSecondsToString(size32_t &__lenResult, char* &__result, int seconds, const char* format)
|
|
|
+TIMELIB_API void TIMELIB_CALL tlSecondsToString(size32_t &__lenResult, char* &__result, __int64 seconds, const char* format)
|
|
|
{
|
|
|
struct tm timeInfo;
|
|
|
time_t theTime = seconds;
|
|
|
size_t kBufferSize = 256;
|
|
|
char buffer[kBufferSize];
|
|
|
|
|
|
- memset(buffer,kBufferSize,0);
|
|
|
+ memset(buffer, kBufferSize, 0);
|
|
|
|
|
|
- #ifdef _WINDOWS
|
|
|
- // gmtime is thread-safe under Windows
|
|
|
- memcpy(&timeInfo,gmtime(&theTime),sizeof(timeInfo));
|
|
|
- #else
|
|
|
- gmtime_r(&theTime,&timeInfo);
|
|
|
- #endif
|
|
|
+ tlGMTime_r(&theTime, &timeInfo);
|
|
|
|
|
|
- __lenResult = strftime(buffer,kBufferSize,format,&timeInfo);
|
|
|
+ __lenResult = strftime(buffer, kBufferSize, format, &timeInfo);
|
|
|
__result = NULL;
|
|
|
|
|
|
if (__lenResult > 0)
|
|
|
{
|
|
|
__result = reinterpret_cast<char*>(rtlMalloc(__lenResult));
|
|
|
- memcpy(__result,buffer,__lenResult);
|
|
|
+ memcpy(__result, buffer, __lenResult);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -305,15 +590,15 @@ TIMELIB_API unsigned int TIMELIB_CALL tlAdjustDate(unsigned int date, short year
|
|
|
struct tm timeInfo;
|
|
|
unsigned int result = 0;
|
|
|
|
|
|
- memset(&timeInfo,0,sizeof(timeInfo));
|
|
|
+ memset(&timeInfo, 0, sizeof(timeInfo));
|
|
|
|
|
|
- tlInsertDateIntoTimeStruct(&timeInfo,date);
|
|
|
+ tlInsertDateIntoTimeStruct(&timeInfo, date);
|
|
|
|
|
|
timeInfo.tm_year += year_delta;
|
|
|
timeInfo.tm_mon += month_delta;
|
|
|
timeInfo.tm_mday += day_delta;
|
|
|
|
|
|
- mktime(&timeInfo);
|
|
|
+ tlMKTime(&timeInfo);
|
|
|
|
|
|
result = tlExtractDateFromTimeStruct(&timeInfo);
|
|
|
|
|
@@ -327,12 +612,12 @@ TIMELIB_API unsigned int TIMELIB_CALL tlAdjustDateBySeconds(unsigned int date, i
|
|
|
struct tm timeInfo;
|
|
|
unsigned int result = 0;
|
|
|
|
|
|
- memset(&timeInfo,0,sizeof(timeInfo));
|
|
|
+ memset(&timeInfo, 0, sizeof(timeInfo));
|
|
|
|
|
|
- tlInsertDateIntoTimeStruct(&timeInfo,date);
|
|
|
+ tlInsertDateIntoTimeStruct(&timeInfo, date);
|
|
|
timeInfo.tm_sec = seconds_delta;
|
|
|
|
|
|
- mktime(&timeInfo);
|
|
|
+ tlMKTime(&timeInfo);
|
|
|
|
|
|
result = tlExtractDateFromTimeStruct(&timeInfo);
|
|
|
|
|
@@ -346,15 +631,15 @@ TIMELIB_API unsigned int TIMELIB_CALL tlAdjustTime(unsigned int time, short hour
|
|
|
struct tm timeInfo;
|
|
|
unsigned int result = 0;
|
|
|
|
|
|
- memset(&timeInfo,0,sizeof(timeInfo));
|
|
|
+ memset(&timeInfo, 0, sizeof(timeInfo));
|
|
|
|
|
|
- tlInsertTimeIntoTimeStruct(&timeInfo,time);
|
|
|
+ tlInsertTimeIntoTimeStruct(&timeInfo, time);
|
|
|
|
|
|
timeInfo.tm_hour += hour_delta;
|
|
|
timeInfo.tm_min += minute_delta;
|
|
|
timeInfo.tm_sec += second_delta;
|
|
|
|
|
|
- mktime(&timeInfo);
|
|
|
+ tlMKTime(&timeInfo);
|
|
|
|
|
|
result = tlExtractTimeFromTimeStruct(&timeInfo);
|
|
|
|
|
@@ -368,12 +653,12 @@ TIMELIB_API unsigned int TIMELIB_CALL tlAdjustTimeBySeconds(unsigned int time, i
|
|
|
struct tm timeInfo;
|
|
|
unsigned int result = 0;
|
|
|
|
|
|
- memset(&timeInfo,0,sizeof(timeInfo));
|
|
|
+ memset(&timeInfo, 0, sizeof(timeInfo));
|
|
|
|
|
|
- tlInsertTimeIntoTimeStruct(&timeInfo,time);
|
|
|
+ tlInsertTimeIntoTimeStruct(&timeInfo, time);
|
|
|
timeInfo.tm_sec += seconds_delta;
|
|
|
|
|
|
- mktime(&timeInfo);
|
|
|
+ tlMKTime(&timeInfo);
|
|
|
|
|
|
result = tlExtractTimeFromTimeStruct(&timeInfo);
|
|
|
|
|
@@ -382,17 +667,13 @@ TIMELIB_API unsigned int TIMELIB_CALL tlAdjustTimeBySeconds(unsigned int time, i
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
-TIMELIB_API time_t TIMELIB_CALL tlAdjustSeconds(time_t seconds, short year_delta, int month_delta, int day_delta, short hour_delta, int minute_delta, int second_delta)
|
|
|
+TIMELIB_API __int64 TIMELIB_CALL tlAdjustSeconds(__int64 seconds, short year_delta, int month_delta, int day_delta, short hour_delta, int minute_delta, int second_delta)
|
|
|
{
|
|
|
struct tm timeInfo;
|
|
|
+ time_t theTime = seconds;
|
|
|
time_t result = 0;
|
|
|
|
|
|
- #ifdef _WINDOWS
|
|
|
- // localtime is thread-safe under Windows
|
|
|
- memcpy(&timeInfo,localtime(&seconds),sizeof(timeInfo));
|
|
|
- #else
|
|
|
- localtime_r(&seconds,&timeInfo);
|
|
|
- #endif
|
|
|
+ tlLocalTime_r(&theTime, &timeInfo);
|
|
|
|
|
|
timeInfo.tm_year += year_delta;
|
|
|
timeInfo.tm_mon += month_delta;
|
|
@@ -401,9 +682,9 @@ TIMELIB_API time_t TIMELIB_CALL tlAdjustSeconds(time_t seconds, short year_delta
|
|
|
timeInfo.tm_min += minute_delta;
|
|
|
timeInfo.tm_sec += second_delta;
|
|
|
|
|
|
- result = mktime(&timeInfo);
|
|
|
+ result = theTime = tlMKTime(&timeInfo);
|
|
|
|
|
|
- return result;
|
|
|
+ return static_cast<__int64>(result);
|
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
@@ -427,7 +708,7 @@ TIMELIB_API unsigned int TIMELIB_CALL tlAdjustCalendar(unsigned int date, short
|
|
|
expectedMonthVal = 12 - (abs(expectedMonthVal) % 12);
|
|
|
}
|
|
|
|
|
|
- memset(&timeInfo,0,sizeof(timeInfo));
|
|
|
+ memset(&timeInfo, 0, sizeof(timeInfo));
|
|
|
|
|
|
timeInfo.tm_year = year - 1900;
|
|
|
timeInfo.tm_mon = month - 1;
|
|
@@ -436,19 +717,22 @@ TIMELIB_API unsigned int TIMELIB_CALL tlAdjustCalendar(unsigned int date, short
|
|
|
timeInfo.tm_year += year_delta;
|
|
|
timeInfo.tm_mon += month_delta;
|
|
|
|
|
|
- mktime(&timeInfo);
|
|
|
+ tlMKTime(&timeInfo);
|
|
|
|
|
|
if (timeInfo.tm_mon != expectedMonthVal)
|
|
|
{
|
|
|
// 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;
|
|
|
- mktime(&timeInfo);
|
|
|
+ tlMKTime(&timeInfo);
|
|
|
}
|
|
|
|
|
|
- // Now apply the day delta
|
|
|
- timeInfo.tm_mday += day_delta;
|
|
|
- mktime(&timeInfo);
|
|
|
+ if (day_delta != 0)
|
|
|
+ {
|
|
|
+ // Now apply the day delta
|
|
|
+ timeInfo.tm_mday += day_delta;
|
|
|
+ tlMKTime(&timeInfo);
|
|
|
+ }
|
|
|
|
|
|
result = tlExtractDateFromTimeStruct(&timeInfo);
|
|
|
|
|
@@ -462,12 +746,7 @@ TIMELIB_API bool TIMELIB_CALL tlIsLocalDaylightSavingsInEffect()
|
|
|
struct tm timeInfo;
|
|
|
time_t theTime = time(NULL);
|
|
|
|
|
|
- #ifdef _WINDOWS
|
|
|
- // localtime is thread-safe under Windows
|
|
|
- memcpy(&timeInfo,localtime(&theTime),sizeof(timeInfo));
|
|
|
- #else
|
|
|
- localtime_r(&theTime,&timeInfo);
|
|
|
- #endif
|
|
|
+ tlLocalTime_r(&theTime, &timeInfo);
|
|
|
|
|
|
return (timeInfo.tm_isdst == 1);
|
|
|
}
|
|
@@ -476,17 +755,20 @@ TIMELIB_API bool TIMELIB_CALL tlIsLocalDaylightSavingsInEffect()
|
|
|
|
|
|
TIMELIB_API int TIMELIB_CALL tlLocalTimeZoneOffset()
|
|
|
{
|
|
|
- struct tm timeInfo;
|
|
|
- time_t theTime = time(NULL);
|
|
|
+ int offset = 0;
|
|
|
|
|
|
#ifdef _WINDOWS
|
|
|
- // localtime is thread-safe under Windows
|
|
|
- memcpy(&timeInfo,localtime(&theTime),sizeof(timeInfo));
|
|
|
+ offset = tlLocalTimeZoneDiffIn100nsIntervals() / _onesec_in100ns;
|
|
|
#else
|
|
|
- localtime_r(&theTime,&timeInfo);
|
|
|
+ struct tm timeInfo;
|
|
|
+ time_t theTime = time(NULL);
|
|
|
+
|
|
|
+ tlLocalTime_r(&theTime, &timeInfo);
|
|
|
+
|
|
|
+ offset = timeInfo.tm_gmtoff;
|
|
|
#endif
|
|
|
|
|
|
- return timeInfo.tm_gmtoff;
|
|
|
+ return offset;
|
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
@@ -501,21 +783,11 @@ TIMELIB_API unsigned int TIMELIB_CALL tlCurrentDate(bool in_local_time)
|
|
|
// UTC or local time
|
|
|
if (in_local_time)
|
|
|
{
|
|
|
- #ifdef _WINDOWS
|
|
|
- // localtime is thread-safe under Windows
|
|
|
- memcpy(&timeInfo,localtime(&theTime),sizeof(timeInfo));
|
|
|
- #else
|
|
|
- localtime_r(&theTime,&timeInfo);
|
|
|
- #endif
|
|
|
+ tlLocalTime_r(&theTime, &timeInfo);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- #ifdef _WINDOWS
|
|
|
- // gmtime is thread-safe under Windows
|
|
|
- memcpy(&timeInfo,gmtime(&theTime),sizeof(timeInfo));
|
|
|
- #else
|
|
|
- gmtime_r(&theTime,&timeInfo);
|
|
|
- #endif
|
|
|
+ tlGMTime_r(&theTime, &timeInfo);
|
|
|
}
|
|
|
|
|
|
result = tlExtractDateFromTimeStruct(&timeInfo);
|
|
@@ -535,21 +807,11 @@ TIMELIB_API unsigned int TIMELIB_CALL tlCurrentTime(bool in_local_time)
|
|
|
// UTC or local time
|
|
|
if (in_local_time)
|
|
|
{
|
|
|
- #ifdef _WINDOWS
|
|
|
- // localtime is thread-safe under Windows
|
|
|
- memcpy(&timeInfo,localtime(&theTime),sizeof(timeInfo));
|
|
|
- #else
|
|
|
- localtime_r(&theTime,&timeInfo);
|
|
|
- #endif
|
|
|
+ tlLocalTime_r(&theTime, &timeInfo);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- #ifdef _WINDOWS
|
|
|
- // gmtime is thread-safe under Windows
|
|
|
- memcpy(&timeInfo,gmtime(&theTime),sizeof(timeInfo));
|
|
|
- #else
|
|
|
- gmtime_r(&theTime,&timeInfo);
|
|
|
- #endif
|
|
|
+ tlGMTime_r(&theTime, &timeInfo);
|
|
|
}
|
|
|
|
|
|
result = tlExtractTimeFromTimeStruct(&timeInfo);
|
|
@@ -559,7 +821,7 @@ TIMELIB_API unsigned int TIMELIB_CALL tlCurrentTime(bool in_local_time)
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
-TIMELIB_API time_t TIMELIB_CALL tlCurrentSeconds(bool in_local_time)
|
|
|
+TIMELIB_API __int64 TIMELIB_CALL tlCurrentSeconds(bool in_local_time)
|
|
|
{
|
|
|
time_t result = time(NULL);
|
|
|
|
|
@@ -568,33 +830,33 @@ TIMELIB_API time_t TIMELIB_CALL tlCurrentSeconds(bool in_local_time)
|
|
|
result += tlLocalTimeZoneOffset();
|
|
|
}
|
|
|
|
|
|
- return result;
|
|
|
+ return static_cast<__int64>(result);
|
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
-TIMELIB_API double TIMELIB_CALL tlCurrentTimestamp(bool in_local_time)
|
|
|
+TIMELIB_API __int64 TIMELIB_CALL tlCurrentTimestamp(bool in_local_time)
|
|
|
{
|
|
|
- double result = 0.0;
|
|
|
+ __int64 result = 0;
|
|
|
|
|
|
#ifdef _WINDOWS
|
|
|
struct _timeb now;
|
|
|
|
|
|
_ftime(&now);
|
|
|
|
|
|
- result = now.time + (now.millitm / 1000.0);
|
|
|
+ result = (now.time * 1000000) + now.(millitm * 1000);
|
|
|
#else
|
|
|
struct timeval tv;
|
|
|
|
|
|
- if (gettimeofday(&tv,NULL) == 0)
|
|
|
+ if (gettimeofday(&tv, NULL) == 0)
|
|
|
{
|
|
|
- result = tv.tv_sec + (tv.tv_usec / 1000000.0);
|
|
|
+ result = (tv.tv_sec * 1000000) + tv.tv_usec;
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
if (in_local_time)
|
|
|
{
|
|
|
- result += tlLocalTimeZoneOffset();
|
|
|
+ result += (static_cast<long>(tlLocalTimeZoneOffset()) * 1000000);
|
|
|
}
|
|
|
|
|
|
return result;
|
|
@@ -607,16 +869,16 @@ TIMELIB_API unsigned int TIMELIB_CALL tlGetLastDayOfMonth(unsigned int date)
|
|
|
struct tm timeInfo;
|
|
|
unsigned int result = 0;
|
|
|
|
|
|
- memset(&timeInfo,0,sizeof(timeInfo));
|
|
|
- tlInsertDateIntoTimeStruct(&timeInfo,date);
|
|
|
+ memset(&timeInfo, 0, sizeof(timeInfo));
|
|
|
+ tlInsertDateIntoTimeStruct(&timeInfo, date);
|
|
|
|
|
|
// Call mktime once to fix up any bogus data
|
|
|
- mktime(&timeInfo);
|
|
|
+ tlMKTime(&timeInfo);
|
|
|
|
|
|
// Adjust and call again
|
|
|
timeInfo.tm_mon += 1;
|
|
|
timeInfo.tm_mday = 0;
|
|
|
- mktime(&timeInfo);
|
|
|
+ tlMKTime(&timeInfo);
|
|
|
|
|
|
result = tlExtractDateFromTimeStruct(&timeInfo);
|
|
|
|
|
@@ -631,21 +893,21 @@ TIMELIB_API void TIMELIB_CALL tlDatesForWeek(size32_t &__lenResult, void* &__res
|
|
|
unsigned int weekStartResult = 0;
|
|
|
unsigned int weekEndResult = 0;
|
|
|
|
|
|
- memset(&timeInfo,0,sizeof(timeInfo));
|
|
|
- tlInsertDateIntoTimeStruct(&timeInfo,date);
|
|
|
+ memset(&timeInfo, 0, sizeof(timeInfo));
|
|
|
+ tlInsertDateIntoTimeStruct(&timeInfo, date);
|
|
|
|
|
|
// Call mktime once to fix up any bogus data
|
|
|
- mktime(&timeInfo);
|
|
|
+ tlMKTime(&timeInfo);
|
|
|
|
|
|
// Adjust and call again
|
|
|
timeInfo.tm_mday -= timeInfo.tm_wday;
|
|
|
- mktime(&timeInfo);
|
|
|
+ tlMKTime(&timeInfo);
|
|
|
|
|
|
weekStartResult = tlExtractDateFromTimeStruct(&timeInfo);
|
|
|
|
|
|
// Adjust to the beginning of the week
|
|
|
timeInfo.tm_mday += 6;
|
|
|
- mktime(&timeInfo);
|
|
|
+ tlMKTime(&timeInfo);
|
|
|
|
|
|
weekEndResult = tlExtractDateFromTimeStruct(&timeInfo);
|
|
|
|