timelib.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #include <platform.h>
  14. #include <time.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <ctype.h>
  18. #include <assert.h>
  19. #include <eclrtl.hpp>
  20. #ifdef _WINDOWS
  21. #include <sys/timeb.h>
  22. #endif
  23. #include "timelib.hpp"
  24. static const char * compatibleVersions[] = {
  25. NULL };
  26. #define TIMELIB_VERSION "TIMELIB 1.0.0"
  27. static const char * EclDefinition =
  28. "export TMPartsRec := RECORD \n"
  29. " UNSIGNED4 v; \n"
  30. "END;"
  31. "export TimeLib := SERVICE\n"
  32. " integer4 SecondsFromParts(integer2 year, unsigned1 month, unsigned1 day, unsigned1 hour, unsigned1 minute, unsigned1 second, boolean is_local_time) : c,pure,entrypoint='tlSecondsFromParts'; \n"
  33. " DATASET(TMPartsRec) SecondsToParts(INTEGER8 seconds) : c,pure,entrypoint='tlSecondsToParts'; \n"
  34. " UNSIGNED2 GetDayOfYear(INTEGER2 year, UNSIGNED1 month, UNSIGNED1 day) : c,pure,entrypoint='tlGetDayOfYear'; \n"
  35. " UNSIGNED1 GetDayOfWeek(INTEGER2 year, UNSIGNED1 month, UNSIGNED1 day) : c,pure,entrypoint='tlGetDayOfWeek'; \n"
  36. " STRING DateToString(UNSIGNED4 date, VARSTRING format) : c,pure,entrypoint='tlDateToString'; \n"
  37. " STRING TimeToString(UNSIGNED3 time, VARSTRING format) : c,pure,entrypoint='tlTimeToString'; \n"
  38. " STRING SecondsToString(INTEGER4 seconds, VARSTRING format) : c,pure,entrypoint='tlSecondsToString'; \n"
  39. " UNSIGNED4 AdjustDate(UNSIGNED4 date, INTEGER2 year_delta, INTEGER4 month_delta, INTEGER4 day_delta) : c,pure,entrypoint='tlAdjustDate'; \n"
  40. " UNSIGNED4 AdjustDateBySeconds(UNSIGNED4 date, INTEGER4 seconds_delta) : c,pure,entrypoint='tlAdjustDateBySeconds'; \n"
  41. " UNSIGNED3 AdjustTime(UNSIGNED3 time, INTEGER2 hour_delta, INTEGER4 minute_delta, INTEGER4 second_delta) : c,pure,entrypoint='tlAdjustTime'; \n"
  42. " UNSIGNED3 AdjustTimeBySeconds(UNSIGNED3 time, INTEGER4 seconds_delta) : c,pure,entrypoint='tlAdjustTimeBySeconds'; \n"
  43. " 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"
  44. " UNSIGNED4 AdjustCalendar(UNSIGNED4 date, INTEGER2 year_delta, INTEGER4 month_delta, INTEGER4 day_delta) : c,pure,entrypoint='tlAdjustCalendar'; \n"
  45. " BOOLEAN IsLocalDaylightSavingsInEffect() : c,pure,entrypoint='tlIsLocalDaylightSavingsInEffect'; \n"
  46. " INTEGER4 LocalTimeZoneOffset() : c,pure,entrypoint='tlLocalTimeZoneOffset'; \n"
  47. " UNSIGNED4 CurrentDate(BOOLEAN in_local_time) : c,pure,entrypoint='tlCurrentDate'; \n"
  48. " UNSIGNED4 CurrentTime(BOOLEAN in_local_time) : c,pure,entrypoint='tlCurrentTime'; \n"
  49. " INTEGER4 CurrentSeconds(BOOLEAN in_local_time) : c,pure,entrypoint='tlCurrentSeconds'; \n"
  50. " REAL8 CurrentTimestamp(BOOLEAN in_local_time) : c,pure,entrypoint='tlCurrentTimestamp'; \n"
  51. " UNSIGNED4 GetLastDayOfMonth(UNSIGNED4 date) : c,pure,entrypoint='tlGetLastDayOfMonth'; \n"
  52. " DATASET(TMPartsRec) DatesForWeek(UNSIGNED4 date) : c,pure,entrypoint='tlDatesForWeek'; \n"
  53. "END;";
  54. TIMELIB_API bool getECLPluginDefinition(ECLPluginDefinitionBlock *pb)
  55. {
  56. if (pb->size == sizeof(ECLPluginDefinitionBlockEx))
  57. {
  58. ECLPluginDefinitionBlockEx * pbx = (ECLPluginDefinitionBlockEx *) pb;
  59. pbx->compatibleVersions = compatibleVersions;
  60. }
  61. else if (pb->size != sizeof(ECLPluginDefinitionBlock))
  62. return false;
  63. pb->magicVersion = PLUGIN_VERSION;
  64. pb->version = TIMELIB_VERSION;
  65. pb->moduleName = "lib_timelib";
  66. pb->ECL = EclDefinition;
  67. pb->flags = PLUGIN_IMPLICIT_MODULE | PLUGIN_MULTIPLE_VERSIONS;
  68. pb->description = "TimeLib time manipulation library";
  69. return true;
  70. }
  71. IPluginContext * parentCtx = NULL;
  72. TIMELIB_API void setPluginContext(IPluginContext * _ctx) { parentCtx = _ctx; }
  73. //------------------------------------------------------------------------------
  74. void tlMakeTimeStructFromUTCSeconds(time_t seconds, struct tm* timeInfo)
  75. {
  76. #ifdef _WINDOWS
  77. // gmtime is thread-safe under Windows
  78. memcpy(timeInfo,gmtime(&seconds),sizeof(&timeInfo));
  79. #else
  80. gmtime_r(&seconds,timeInfo);
  81. #endif
  82. }
  83. void tlInsertDateIntoTimeStruct(struct tm* timeInfo, unsigned int date)
  84. {
  85. unsigned int year = date / 10000;
  86. unsigned int month = (date - (year * 10000)) / 100;
  87. unsigned int day = date - (year * 10000) - (month * 100);
  88. timeInfo->tm_year = year - 1900;
  89. timeInfo->tm_mon = month - 1;
  90. timeInfo->tm_mday = day;
  91. }
  92. unsigned int tlExtractDateFromTimeStruct(struct tm* timeInfo)
  93. {
  94. unsigned int result = 0;
  95. result = (timeInfo->tm_year + 1900) * 10000;
  96. result += (timeInfo->tm_mon + 1) * 100;
  97. result += timeInfo->tm_mday;
  98. return result;
  99. }
  100. void tlInsertTimeIntoTimeStruct(struct tm* timeInfo, unsigned int time)
  101. {
  102. unsigned int hour = time / 10000;
  103. unsigned int minute = (time - (hour * 10000)) / 100;
  104. unsigned int second = time - (hour * 10000) - (minute * 100);
  105. timeInfo->tm_hour = hour;
  106. timeInfo->tm_min = minute;
  107. timeInfo->tm_sec = second;
  108. }
  109. unsigned int tlExtractTimeFromTimeStruct(struct tm* timeInfo)
  110. {
  111. unsigned int result = 0;
  112. result = timeInfo->tm_hour * 10000;
  113. result += timeInfo->tm_min * 100;
  114. result += timeInfo->tm_sec;
  115. return result;
  116. }
  117. //------------------------------------------------------------------------------
  118. 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)
  119. {
  120. struct tm timeInfo;
  121. time_t the_time = 0;
  122. memset(&timeInfo,0,sizeof(timeInfo));
  123. // Push each time part value into the tm struct
  124. timeInfo.tm_sec = second;
  125. timeInfo.tm_min = minute;
  126. timeInfo.tm_hour = hour;
  127. timeInfo.tm_mday = day;
  128. timeInfo.tm_mon = month - 1;
  129. timeInfo.tm_year = year - 1900;
  130. // Get the initial time components; note that mktime assumes local time
  131. the_time = mktime(&timeInfo);
  132. if (!is_local_time)
  133. {
  134. // Adjust for time zone offset
  135. the_time += timeInfo.tm_gmtoff;
  136. }
  137. return the_time;
  138. }
  139. //------------------------------------------------------------------------------
  140. TIMELIB_API void TIMELIB_CALL tlSecondsToParts(size32_t &__lenResult, void* &__result, time_t seconds)
  141. {
  142. struct tm timeInfo;
  143. tlMakeTimeStructFromUTCSeconds(seconds, &timeInfo);
  144. __lenResult = sizeof(unsigned int) * 7;
  145. __result = CTXMALLOC(parentCtx, __lenResult);
  146. // Actually write the output values one at a time
  147. unsigned int* out = reinterpret_cast<unsigned int*>(__result);
  148. out[0] = timeInfo.tm_sec;
  149. out[1] = timeInfo.tm_min;
  150. out[2] = timeInfo.tm_hour;
  151. out[3] = timeInfo.tm_mday;
  152. out[4] = timeInfo.tm_mon;
  153. out[5] = timeInfo.tm_year;
  154. out[6] = timeInfo.tm_wday;
  155. }
  156. //------------------------------------------------------------------------------
  157. TIMELIB_API unsigned int TIMELIB_CALL tlGetDayOfYear(short year, unsigned short month, unsigned short day)
  158. {
  159. struct tm timeInfo;
  160. memset(&timeInfo,0,sizeof(timeInfo));
  161. // Push each time part value into the tm struct
  162. timeInfo.tm_mday = day;
  163. timeInfo.tm_mon = month - 1;
  164. timeInfo.tm_year = year - 1900;
  165. mktime(&timeInfo);
  166. return timeInfo.tm_yday;
  167. }
  168. //------------------------------------------------------------------------------
  169. TIMELIB_API unsigned int TIMELIB_CALL tlGetDayOfWeek(short year, unsigned short month, unsigned short day)
  170. {
  171. struct tm timeInfo;
  172. memset(&timeInfo,0,sizeof(timeInfo));
  173. // Push each time part value into the tm struct
  174. timeInfo.tm_mday = day;
  175. timeInfo.tm_mon = month - 1;
  176. timeInfo.tm_year = year - 1900;
  177. mktime(&timeInfo);
  178. return timeInfo.tm_wday;
  179. }
  180. //------------------------------------------------------------------------------
  181. TIMELIB_API void TIMELIB_CALL tlDateToString(size32_t &__lenResult, char* &__result, unsigned int date, const char* format)
  182. {
  183. struct tm timeInfo;
  184. size_t kBufferSize = 256;
  185. char buffer[kBufferSize];
  186. memset(&timeInfo,0,sizeof(timeInfo));
  187. tlInsertDateIntoTimeStruct(&timeInfo,date);
  188. __lenResult = strftime(buffer,kBufferSize,format,&timeInfo);
  189. __result = NULL;
  190. if (__lenResult > 0)
  191. {
  192. __result = reinterpret_cast<char*>(CTXMALLOC(parentCtx, __lenResult));
  193. memcpy(__result,buffer,__lenResult);
  194. }
  195. }
  196. //------------------------------------------------------------------------------
  197. TIMELIB_API void TIMELIB_CALL tlTimeToString(size32_t &__lenResult, char* &__result, unsigned int time, const char* format)
  198. {
  199. struct tm timeInfo;
  200. size_t kBufferSize = 256;
  201. char buffer[kBufferSize];
  202. memset(&timeInfo,0,sizeof(timeInfo));
  203. tlInsertTimeIntoTimeStruct(&timeInfo,time);
  204. __lenResult = strftime(buffer,kBufferSize,format,&timeInfo);
  205. __result = NULL;
  206. if (__lenResult > 0)
  207. {
  208. __result = reinterpret_cast<char*>(rtlMalloc(__lenResult));
  209. memcpy(__result,buffer,__lenResult);
  210. }
  211. }
  212. //------------------------------------------------------------------------------
  213. TIMELIB_API void TIMELIB_CALL tlSecondsToString(size32_t &__lenResult, char* &__result, int seconds, const char* format)
  214. {
  215. struct tm timeInfo;
  216. time_t theTime = seconds;
  217. size_t kBufferSize = 256;
  218. char buffer[kBufferSize];
  219. memset(buffer,kBufferSize,0);
  220. #ifdef _WINDOWS
  221. // gmtime is thread-safe under Windows
  222. memcpy(&timeInfo,gmtime(&theTime),sizeof(timeInfo));
  223. #else
  224. gmtime_r(&theTime,&timeInfo);
  225. #endif
  226. __lenResult = strftime(buffer,kBufferSize,format,&timeInfo);
  227. __result = NULL;
  228. if (__lenResult > 0)
  229. {
  230. __result = reinterpret_cast<char*>(rtlMalloc(__lenResult));
  231. memcpy(__result,buffer,__lenResult);
  232. }
  233. }
  234. //------------------------------------------------------------------------------
  235. TIMELIB_API unsigned int TIMELIB_CALL tlAdjustDate(unsigned int date, short year_delta, int month_delta, int day_delta)
  236. {
  237. struct tm timeInfo;
  238. unsigned int result = 0;
  239. memset(&timeInfo,0,sizeof(timeInfo));
  240. tlInsertDateIntoTimeStruct(&timeInfo,date);
  241. timeInfo.tm_year += year_delta;
  242. timeInfo.tm_mon += month_delta;
  243. timeInfo.tm_mday += day_delta;
  244. mktime(&timeInfo);
  245. result = tlExtractDateFromTimeStruct(&timeInfo);
  246. return result;
  247. }
  248. //------------------------------------------------------------------------------
  249. TIMELIB_API unsigned int TIMELIB_CALL tlAdjustDateBySeconds(unsigned int date, int seconds_delta)
  250. {
  251. struct tm timeInfo;
  252. unsigned int result = 0;
  253. memset(&timeInfo,0,sizeof(timeInfo));
  254. tlInsertDateIntoTimeStruct(&timeInfo,date);
  255. timeInfo.tm_sec = seconds_delta;
  256. mktime(&timeInfo);
  257. result = tlExtractDateFromTimeStruct(&timeInfo);
  258. return result;
  259. }
  260. //------------------------------------------------------------------------------
  261. TIMELIB_API unsigned int TIMELIB_CALL tlAdjustTime(unsigned int time, short hour_delta, int minute_delta, int second_delta)
  262. {
  263. struct tm timeInfo;
  264. unsigned int result = 0;
  265. memset(&timeInfo,0,sizeof(timeInfo));
  266. tlInsertTimeIntoTimeStruct(&timeInfo,time);
  267. timeInfo.tm_hour += hour_delta;
  268. timeInfo.tm_min += minute_delta;
  269. timeInfo.tm_sec += second_delta;
  270. mktime(&timeInfo);
  271. result = tlExtractTimeFromTimeStruct(&timeInfo);
  272. return result;
  273. }
  274. //------------------------------------------------------------------------------
  275. TIMELIB_API unsigned int TIMELIB_CALL tlAdjustTimeBySeconds(unsigned int time, int seconds_delta)
  276. {
  277. struct tm timeInfo;
  278. unsigned int result = 0;
  279. memset(&timeInfo,0,sizeof(timeInfo));
  280. tlInsertTimeIntoTimeStruct(&timeInfo,time);
  281. timeInfo.tm_sec += seconds_delta;
  282. mktime(&timeInfo);
  283. result = tlExtractTimeFromTimeStruct(&timeInfo);
  284. return result;
  285. }
  286. //------------------------------------------------------------------------------
  287. 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)
  288. {
  289. struct tm timeInfo;
  290. time_t result = 0;
  291. #ifdef _WINDOWS
  292. // localtime is thread-safe under Windows
  293. memcpy(&timeInfo,localtime(&seconds),sizeof(timeInfo));
  294. #else
  295. localtime_r(&seconds,&timeInfo);
  296. #endif
  297. timeInfo.tm_year += year_delta;
  298. timeInfo.tm_mon += month_delta;
  299. timeInfo.tm_mday += day_delta;
  300. timeInfo.tm_hour += hour_delta;
  301. timeInfo.tm_min += minute_delta;
  302. timeInfo.tm_sec += second_delta;
  303. result = mktime(&timeInfo);
  304. return result;
  305. }
  306. //------------------------------------------------------------------------------
  307. TIMELIB_API unsigned int TIMELIB_CALL tlAdjustCalendar(unsigned int date, short year_delta, int month_delta, int day_delta)
  308. {
  309. struct tm timeInfo;
  310. unsigned int year = date / 10000;
  311. unsigned int month = (date - (year * 10000)) / 100;
  312. unsigned int day = date - (year * 10000) - (month * 100);
  313. int expectedMonthVal = month + month_delta - 1;
  314. unsigned int result = 0;
  315. // Normalize the expected month value
  316. if (expectedMonthVal >= 0)
  317. {
  318. expectedMonthVal = expectedMonthVal % 12;
  319. }
  320. else
  321. {
  322. expectedMonthVal = 12 - (abs(expectedMonthVal) % 12);
  323. }
  324. memset(&timeInfo,0,sizeof(timeInfo));
  325. timeInfo.tm_year = year - 1900;
  326. timeInfo.tm_mon = month - 1;
  327. timeInfo.tm_mday = day;
  328. timeInfo.tm_year += year_delta;
  329. timeInfo.tm_mon += month_delta;
  330. mktime(&timeInfo);
  331. if (timeInfo.tm_mon != expectedMonthVal)
  332. {
  333. // If the returned month doesn't match the expected month, we need to
  334. // go back to the last day of the previous month
  335. timeInfo.tm_mday = 0;
  336. mktime(&timeInfo);
  337. }
  338. // Now apply the day delta
  339. timeInfo.tm_mday += day_delta;
  340. mktime(&timeInfo);
  341. result = tlExtractDateFromTimeStruct(&timeInfo);
  342. return result;
  343. }
  344. //------------------------------------------------------------------------------
  345. TIMELIB_API bool TIMELIB_CALL tlIsLocalDaylightSavingsInEffect()
  346. {
  347. struct tm timeInfo;
  348. time_t theTime = time(NULL);
  349. #ifdef _WINDOWS
  350. // localtime is thread-safe under Windows
  351. memcpy(&timeInfo,localtime(&theTime),sizeof(timeInfo));
  352. #else
  353. localtime_r(&theTime,&timeInfo);
  354. #endif
  355. return (timeInfo.tm_isdst == 1);
  356. }
  357. //------------------------------------------------------------------------------
  358. TIMELIB_API int TIMELIB_CALL tlLocalTimeZoneOffset()
  359. {
  360. struct tm timeInfo;
  361. time_t theTime = time(NULL);
  362. #ifdef _WINDOWS
  363. // localtime is thread-safe under Windows
  364. memcpy(&timeInfo,localtime(&theTime),sizeof(timeInfo));
  365. #else
  366. localtime_r(&theTime,&timeInfo);
  367. #endif
  368. return timeInfo.tm_gmtoff;
  369. }
  370. //------------------------------------------------------------------------------
  371. TIMELIB_API unsigned int TIMELIB_CALL tlCurrentDate(bool in_local_time)
  372. {
  373. struct tm timeInfo;
  374. time_t theTime = time(NULL);
  375. unsigned int result = 0;
  376. // Create time parts differently depending on whether you need
  377. // UTC or local time
  378. if (in_local_time)
  379. {
  380. #ifdef _WINDOWS
  381. // localtime is thread-safe under Windows
  382. memcpy(&timeInfo,localtime(&theTime),sizeof(timeInfo));
  383. #else
  384. localtime_r(&theTime,&timeInfo);
  385. #endif
  386. }
  387. else
  388. {
  389. #ifdef _WINDOWS
  390. // gmtime is thread-safe under Windows
  391. memcpy(&timeInfo,gmtime(&theTime),sizeof(timeInfo));
  392. #else
  393. gmtime_r(&theTime,&timeInfo);
  394. #endif
  395. }
  396. result = tlExtractDateFromTimeStruct(&timeInfo);
  397. return result;
  398. }
  399. //------------------------------------------------------------------------------
  400. TIMELIB_API unsigned int TIMELIB_CALL tlCurrentTime(bool in_local_time)
  401. {
  402. struct tm timeInfo;
  403. time_t theTime = time(NULL);
  404. unsigned int result = 0;
  405. // Create time parts differently depending on whether you need
  406. // UTC or local time
  407. if (in_local_time)
  408. {
  409. #ifdef _WINDOWS
  410. // localtime is thread-safe under Windows
  411. memcpy(&timeInfo,localtime(&theTime),sizeof(timeInfo));
  412. #else
  413. localtime_r(&theTime,&timeInfo);
  414. #endif
  415. }
  416. else
  417. {
  418. #ifdef _WINDOWS
  419. // gmtime is thread-safe under Windows
  420. memcpy(&timeInfo,gmtime(&theTime),sizeof(timeInfo));
  421. #else
  422. gmtime_r(&theTime,&timeInfo);
  423. #endif
  424. }
  425. result = tlExtractTimeFromTimeStruct(&timeInfo);
  426. return result;
  427. }
  428. //------------------------------------------------------------------------------
  429. TIMELIB_API time_t TIMELIB_CALL tlCurrentSeconds(bool in_local_time)
  430. {
  431. time_t result = time(NULL);
  432. if (in_local_time)
  433. {
  434. result += tlLocalTimeZoneOffset();
  435. }
  436. return result;
  437. }
  438. //------------------------------------------------------------------------------
  439. TIMELIB_API double TIMELIB_CALL tlCurrentTimestamp(bool in_local_time)
  440. {
  441. double result = 0.0;
  442. #ifdef _WINDOWS
  443. struct _timeb now;
  444. _ftime(&now);
  445. result = now.time + (now.millitm / 1000.0);
  446. #else
  447. struct timeval tv;
  448. if (gettimeofday(&tv,NULL) == 0)
  449. {
  450. result = tv.tv_sec + (tv.tv_usec / 1000000.0);
  451. }
  452. #endif
  453. if (in_local_time)
  454. {
  455. result += tlLocalTimeZoneOffset();
  456. }
  457. return result;
  458. }
  459. //------------------------------------------------------------------------------
  460. TIMELIB_API unsigned int TIMELIB_CALL tlGetLastDayOfMonth(unsigned int date)
  461. {
  462. struct tm timeInfo;
  463. unsigned int result = 0;
  464. memset(&timeInfo,0,sizeof(timeInfo));
  465. tlInsertDateIntoTimeStruct(&timeInfo,date);
  466. // Call mktime once to fix up any bogus data
  467. mktime(&timeInfo);
  468. // Adjust and call again
  469. timeInfo.tm_mon += 1;
  470. timeInfo.tm_mday = 0;
  471. mktime(&timeInfo);
  472. result = tlExtractDateFromTimeStruct(&timeInfo);
  473. return result;
  474. }
  475. //------------------------------------------------------------------------------
  476. TIMELIB_API void TIMELIB_CALL tlDatesForWeek(size32_t &__lenResult, void* &__result, unsigned int date)
  477. {
  478. struct tm timeInfo;
  479. unsigned int weekStartResult = 0;
  480. unsigned int weekEndResult = 0;
  481. memset(&timeInfo,0,sizeof(timeInfo));
  482. tlInsertDateIntoTimeStruct(&timeInfo,date);
  483. // Call mktime once to fix up any bogus data
  484. mktime(&timeInfo);
  485. // Adjust and call again
  486. timeInfo.tm_mday -= timeInfo.tm_wday;
  487. mktime(&timeInfo);
  488. weekStartResult = tlExtractDateFromTimeStruct(&timeInfo);
  489. // Adjust to the beginning of the week
  490. timeInfo.tm_mday += 6;
  491. mktime(&timeInfo);
  492. weekEndResult = tlExtractDateFromTimeStruct(&timeInfo);
  493. __lenResult = sizeof(unsigned int) * 2;
  494. __result = CTXMALLOC(parentCtx, __lenResult);
  495. unsigned int* out = reinterpret_cast<unsigned int*>(__result);
  496. out[0] = weekStartResult;
  497. out[1] = weekEndResult;
  498. }