123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922 |
- /*##############################################################################
- HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ############################################################################## */
- #include <platform.h>
- #include <time.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <assert.h>
- #include <eclrtl.hpp>
- #ifdef _WINDOWS
- #include <sys/timeb.h>
- #endif
- #include "timelib.hpp"
- static const char * compatibleVersions[] = {
- NULL };
- #define TIMELIB_VERSION "TIMELIB 1.0.0"
- static const char * EclDefinition =
- "EXPORT TMPartsRec := RECORD \n"
- " UNSIGNED4 v; \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"
- " 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(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(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"
- " 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;";
- TIMELIB_API bool getECLPluginDefinition(ECLPluginDefinitionBlock *pb)
- {
- if (pb->size == sizeof(ECLPluginDefinitionBlockEx))
- {
- ECLPluginDefinitionBlockEx * pbx = (ECLPluginDefinitionBlockEx *) pb;
- pbx->compatibleVersions = compatibleVersions;
- }
- else if (pb->size != sizeof(ECLPluginDefinitionBlock))
- return false;
- pb->magicVersion = PLUGIN_VERSION;
- pb->version = TIMELIB_VERSION;
- pb->moduleName = "lib_timelib";
- pb->ECL = EclDefinition;
- pb->flags = PLUGIN_IMPLICIT_MODULE | PLUGIN_MULTIPLE_VERSIONS;
- pb->description = "TimeLib time manipulation library";
- return true;
- }
- IPluginContext * parentCtx = NULL;
- TIMELIB_API void setPluginContext(IPluginContext * _ctx) { parentCtx = _ctx; }
- //------------------------------------------------------------------------------
- #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
- tlWinLocalTime_r(clock, timeInfoPtr);
- #else
- 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;
- unsigned int month = (date - (year * 10000)) / 100;
- unsigned int day = date - (year * 10000) - (month * 100);
- timeInfo->tm_year = year - 1900;
- timeInfo->tm_mon = month - 1;
- timeInfo->tm_mday = day;
- }
- unsigned int tlExtractDateFromTimeStruct(struct tm* timeInfo)
- {
- unsigned int result = 0;
- result = (timeInfo->tm_year + 1900) * 10000;
- result += (timeInfo->tm_mon + 1) * 100;
- result += timeInfo->tm_mday;
- return result;
- }
- void tlInsertTimeIntoTimeStruct(struct tm* timeInfo, unsigned int time)
- {
- unsigned int hour = time / 10000;
- unsigned int minute = (time - (hour * 10000)) / 100;
- unsigned int second = time - (hour * 10000) - (minute * 100);
- timeInfo->tm_hour = hour;
- timeInfo->tm_min = minute;
- timeInfo->tm_sec = second;
- }
- unsigned int tlExtractTimeFromTimeStruct(struct tm* timeInfo)
- {
- unsigned int result = 0;
- result = timeInfo->tm_hour * 10000;
- result += timeInfo->tm_min * 100;
- result += timeInfo->tm_sec;
- return result;
- }
- //------------------------------------------------------------------------------
- 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));
- // Push each time part value into the tm struct
- timeInfo.tm_sec = second;
- timeInfo.tm_min = minute;
- timeInfo.tm_hour = hour;
- timeInfo.tm_mday = day;
- timeInfo.tm_mon = month - 1;
- timeInfo.tm_year = year - 1900;
- the_time = tlMKTime(&timeInfo, is_local_time);
- return static_cast<__int64>(the_time);
- }
- //------------------------------------------------------------------------------
- TIMELIB_API void TIMELIB_CALL tlSecondsToParts(size32_t &__lenResult, void* &__result, __int64 seconds)
- {
- struct tm timeInfo;
- tlMakeTimeStructFromUTCSeconds(seconds, &timeInfo);
- __lenResult = sizeof(unsigned int) * 7;
- __result = CTXMALLOC(parentCtx, __lenResult);
- // Actually write the output values one at a time
- unsigned int* out = reinterpret_cast<unsigned int*>(__result);
- 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;
- }
- //------------------------------------------------------------------------------
- TIMELIB_API unsigned int TIMELIB_CALL tlGetDayOfYear(short year, unsigned short month, unsigned short day)
- {
- unsigned int dayOfYear = 0;
- #ifdef _WINDOWS
- SYSTEMTIME s;
- 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));
- // Push each time part value into the tm struct
- timeInfo.tm_mday = day;
- timeInfo.tm_mon = month - 1;
- timeInfo.tm_year = year - 1900;
- tlMKTime(&timeInfo);
- dayOfYear = timeInfo.tm_yday;
- #endif
- return dayOfYear;
- }
- //------------------------------------------------------------------------------
- TIMELIB_API unsigned int TIMELIB_CALL tlGetDayOfWeek(short year, unsigned short month, unsigned short day)
- {
- struct tm 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;
- tlMKTime(&timeInfo);
- return timeInfo.tm_wday;
- }
- //------------------------------------------------------------------------------
- TIMELIB_API void TIMELIB_CALL tlDateToString(size32_t &__lenResult, char* &__result, unsigned int date, const char* format)
- {
- struct tm timeInfo;
- size_t kBufferSize = 256;
- char buffer[kBufferSize];
- memset(&timeInfo, 0, sizeof(timeInfo));
- tlInsertDateIntoTimeStruct(&timeInfo, date);
- __lenResult = strftime(buffer, kBufferSize, format, &timeInfo);
- __result = NULL;
- if (__lenResult > 0)
- {
- __result = reinterpret_cast<char*>(CTXMALLOC(parentCtx, __lenResult));
- memcpy(__result, buffer, __lenResult);
- }
- }
- //------------------------------------------------------------------------------
- TIMELIB_API void TIMELIB_CALL tlTimeToString(size32_t &__lenResult, char* &__result, unsigned int time, const char* format)
- {
- struct tm timeInfo;
- size_t kBufferSize = 256;
- char buffer[kBufferSize];
- memset(&timeInfo, 0, sizeof(timeInfo));
- tlInsertTimeIntoTimeStruct(&timeInfo, time);
- __lenResult = strftime(buffer, kBufferSize, format, &timeInfo);
- __result = NULL;
- if (__lenResult > 0)
- {
- __result = reinterpret_cast<char*>(rtlMalloc(__lenResult));
- memcpy(__result, buffer, __lenResult);
- }
- }
- //------------------------------------------------------------------------------
- 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);
- tlGMTime_r(&theTime, &timeInfo);
- __lenResult = strftime(buffer, kBufferSize, format, &timeInfo);
- __result = NULL;
- if (__lenResult > 0)
- {
- __result = reinterpret_cast<char*>(rtlMalloc(__lenResult));
- memcpy(__result, buffer, __lenResult);
- }
- }
- //------------------------------------------------------------------------------
- TIMELIB_API unsigned int TIMELIB_CALL tlAdjustDate(unsigned int date, short year_delta, int month_delta, int day_delta)
- {
- struct tm timeInfo;
- unsigned int result = 0;
- memset(&timeInfo, 0, sizeof(timeInfo));
- tlInsertDateIntoTimeStruct(&timeInfo, date);
- timeInfo.tm_year += year_delta;
- timeInfo.tm_mon += month_delta;
- timeInfo.tm_mday += day_delta;
- tlMKTime(&timeInfo);
- result = tlExtractDateFromTimeStruct(&timeInfo);
- return result;
- }
- //------------------------------------------------------------------------------
- TIMELIB_API unsigned int TIMELIB_CALL tlAdjustDateBySeconds(unsigned int date, int seconds_delta)
- {
- struct tm timeInfo;
- unsigned int result = 0;
- memset(&timeInfo, 0, sizeof(timeInfo));
- tlInsertDateIntoTimeStruct(&timeInfo, date);
- timeInfo.tm_sec = seconds_delta;
- tlMKTime(&timeInfo);
- result = tlExtractDateFromTimeStruct(&timeInfo);
- return result;
- }
- //------------------------------------------------------------------------------
- TIMELIB_API unsigned int TIMELIB_CALL tlAdjustTime(unsigned int time, short hour_delta, int minute_delta, int second_delta)
- {
- struct tm timeInfo;
- unsigned int result = 0;
- memset(&timeInfo, 0, sizeof(timeInfo));
- tlInsertTimeIntoTimeStruct(&timeInfo, time);
- timeInfo.tm_hour += hour_delta;
- timeInfo.tm_min += minute_delta;
- timeInfo.tm_sec += second_delta;
- tlMKTime(&timeInfo);
- result = tlExtractTimeFromTimeStruct(&timeInfo);
- return result;
- }
- //------------------------------------------------------------------------------
- TIMELIB_API unsigned int TIMELIB_CALL tlAdjustTimeBySeconds(unsigned int time, int seconds_delta)
- {
- struct tm timeInfo;
- unsigned int result = 0;
- memset(&timeInfo, 0, sizeof(timeInfo));
- tlInsertTimeIntoTimeStruct(&timeInfo, time);
- timeInfo.tm_sec += seconds_delta;
- tlMKTime(&timeInfo);
- result = tlExtractTimeFromTimeStruct(&timeInfo);
- return result;
- }
- //------------------------------------------------------------------------------
- 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;
- tlLocalTime_r(&theTime, &timeInfo);
- timeInfo.tm_year += year_delta;
- timeInfo.tm_mon += month_delta;
- timeInfo.tm_mday += day_delta;
- timeInfo.tm_hour += hour_delta;
- timeInfo.tm_min += minute_delta;
- timeInfo.tm_sec += second_delta;
- result = theTime = tlMKTime(&timeInfo);
- return static_cast<__int64>(result);
- }
- //------------------------------------------------------------------------------
- TIMELIB_API unsigned int TIMELIB_CALL tlAdjustCalendar(unsigned int date, short year_delta, int month_delta, int day_delta)
- {
- struct tm timeInfo;
- unsigned int year = date / 10000;
- unsigned int month = (date - (year * 10000)) / 100;
- unsigned int day = date - (year * 10000) - (month * 100);
- int expectedMonthVal = month + month_delta - 1;
- unsigned int result = 0;
- // Normalize the expected month value
- if (expectedMonthVal >= 0)
- {
- expectedMonthVal = expectedMonthVal % 12;
- }
- else
- {
- expectedMonthVal = 12 - (abs(expectedMonthVal) % 12);
- }
- memset(&timeInfo, 0, sizeof(timeInfo));
- timeInfo.tm_year = year - 1900;
- timeInfo.tm_mon = month - 1;
- timeInfo.tm_mday = day;
- timeInfo.tm_year += year_delta;
- timeInfo.tm_mon += month_delta;
- 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;
- tlMKTime(&timeInfo);
- }
- if (day_delta != 0)
- {
- // Now apply the day delta
- timeInfo.tm_mday += day_delta;
- tlMKTime(&timeInfo);
- }
- result = tlExtractDateFromTimeStruct(&timeInfo);
- return result;
- }
- //------------------------------------------------------------------------------
- TIMELIB_API bool TIMELIB_CALL tlIsLocalDaylightSavingsInEffect()
- {
- struct tm timeInfo;
- time_t theTime = time(NULL);
- tlLocalTime_r(&theTime, &timeInfo);
- return (timeInfo.tm_isdst == 1);
- }
- //------------------------------------------------------------------------------
- TIMELIB_API int TIMELIB_CALL tlLocalTimeZoneOffset()
- {
- int offset = 0;
- #ifdef _WINDOWS
- offset = tlLocalTimeZoneDiffIn100nsIntervals() / _onesec_in100ns;
- #else
- struct tm timeInfo;
- time_t theTime = time(NULL);
- tlLocalTime_r(&theTime, &timeInfo);
- offset = timeInfo.tm_gmtoff;
- #endif
- return offset;
- }
- //------------------------------------------------------------------------------
- TIMELIB_API unsigned int TIMELIB_CALL tlCurrentDate(bool in_local_time)
- {
- struct tm timeInfo;
- time_t theTime = time(NULL);
- unsigned int result = 0;
- // Create time parts differently depending on whether you need
- // UTC or local time
- if (in_local_time)
- {
- tlLocalTime_r(&theTime, &timeInfo);
- }
- else
- {
- tlGMTime_r(&theTime, &timeInfo);
- }
- result = tlExtractDateFromTimeStruct(&timeInfo);
- return result;
- }
- //------------------------------------------------------------------------------
- TIMELIB_API unsigned int TIMELIB_CALL tlCurrentTime(bool in_local_time)
- {
- struct tm timeInfo;
- time_t theTime = time(NULL);
- unsigned int result = 0;
- // Create time parts differently depending on whether you need
- // UTC or local time
- if (in_local_time)
- {
- tlLocalTime_r(&theTime, &timeInfo);
- }
- else
- {
- tlGMTime_r(&theTime, &timeInfo);
- }
- result = tlExtractTimeFromTimeStruct(&timeInfo);
- return result;
- }
- //------------------------------------------------------------------------------
- TIMELIB_API __int64 TIMELIB_CALL tlCurrentSeconds(bool in_local_time)
- {
- time_t result = time(NULL);
- if (in_local_time)
- {
- result += tlLocalTimeZoneOffset();
- }
- return static_cast<__int64>(result);
- }
- //------------------------------------------------------------------------------
- TIMELIB_API __int64 TIMELIB_CALL tlCurrentTimestamp(bool in_local_time)
- {
- __int64 result = 0;
- #ifdef _WINDOWS
- struct _timeb now;
- _ftime(&now);
- result = (now.time * 1000000) + now.(millitm * 1000);
- #else
- struct timeval tv;
- if (gettimeofday(&tv, NULL) == 0)
- {
- result = (tv.tv_sec * 1000000) + tv.tv_usec;
- }
- #endif
- if (in_local_time)
- {
- result += (static_cast<long>(tlLocalTimeZoneOffset()) * 1000000);
- }
- return result;
- }
- //------------------------------------------------------------------------------
- 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);
- // Call mktime once to fix up any bogus data
- tlMKTime(&timeInfo);
- // Adjust and call again
- timeInfo.tm_mon += 1;
- timeInfo.tm_mday = 0;
- tlMKTime(&timeInfo);
- result = tlExtractDateFromTimeStruct(&timeInfo);
- return result;
- }
- //------------------------------------------------------------------------------
- TIMELIB_API void TIMELIB_CALL tlDatesForWeek(size32_t &__lenResult, void* &__result, unsigned int date)
- {
- struct tm timeInfo;
- unsigned int weekStartResult = 0;
- unsigned int weekEndResult = 0;
- memset(&timeInfo, 0, sizeof(timeInfo));
- tlInsertDateIntoTimeStruct(&timeInfo, date);
- // Call mktime once to fix up any bogus data
- tlMKTime(&timeInfo);
- // Adjust and call again
- timeInfo.tm_mday -= timeInfo.tm_wday;
- tlMKTime(&timeInfo);
- weekStartResult = 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);
- out[0] = weekStartResult;
- out[1] = weekEndResult;
- }
|