htime.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. #include "htime.h"
  2. #include <string.h>
  3. #ifdef _MSC_VER
  4. #define strcasecmp stricmp
  5. #define strncasecmp strnicmp
  6. #else
  7. #include <strings.h>
  8. #define stricmp strcasecmp
  9. #define strnicmp strncasecmp
  10. #endif
  11. static const char* s_weekdays[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
  12. static const char* s_months[] = {"January", "February", "March", "April", "May", "June",
  13. "July", "August", "September", "October", "November", "December"};
  14. static const uint8_t s_days[] = \
  15. // 1 3 5 7 8 10 12
  16. {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  17. unsigned long long gethrtime() {
  18. #ifdef OS_WIN
  19. static LONGLONG s_freq = 0;
  20. if (s_freq == 0) {
  21. LARGE_INTEGER freq;
  22. QueryPerformanceFrequency(&freq);
  23. s_freq = freq.QuadPart;
  24. }
  25. if (s_freq != 0) {
  26. LARGE_INTEGER count;
  27. QueryPerformanceCounter(&count);
  28. return (unsigned long long)(count.QuadPart / (double)s_freq * 1000000);
  29. }
  30. return 0;
  31. #elif HAVE_CLOCK_GETTIME
  32. struct timespec ts;
  33. clock_gettime(CLOCK_MONOTONIC, &ts);
  34. return ts.tv_sec*(unsigned long long)1000000 + ts.tv_nsec / 1000;
  35. #else
  36. struct timeval tv;
  37. gettimeofday(&tv, NULL);
  38. return tv.tv_sec*(unsigned long long)1000000 + tv.tv_usec;
  39. #endif
  40. }
  41. datetime_t datetime_now() {
  42. datetime_t dt;
  43. #ifdef OS_WIN
  44. SYSTEMTIME tm;
  45. GetLocalTime(&tm);
  46. dt.year = tm.wYear;
  47. dt.month = tm.wMonth;
  48. dt.day = tm.wDay;
  49. dt.hour = tm.wHour;
  50. dt.min = tm.wMinute;
  51. dt.sec = tm.wSecond;
  52. dt.ms = tm.wMilliseconds;
  53. #else
  54. struct timeval tv;
  55. struct tm* tm = NULL;
  56. gettimeofday(&tv, NULL);
  57. time_t tt = tv.tv_sec;
  58. tm = localtime(&tt);
  59. dt.year = tm->tm_year + 1900;
  60. dt.month = tm->tm_mon + 1;
  61. dt.day = tm->tm_mday;
  62. dt.hour = tm->tm_hour;
  63. dt.min = tm->tm_min;
  64. dt.sec = tm->tm_sec;
  65. dt.ms = tv.tv_usec/1000;
  66. #endif
  67. return dt;
  68. }
  69. time_t datetime_mktime(datetime_t* dt) {
  70. struct tm tm;
  71. tm.tm_yday = dt->year - 1900;
  72. tm.tm_mon = dt->month - 1;
  73. tm.tm_mday = dt->day;
  74. tm.tm_hour = dt->hour;
  75. tm.tm_min = dt->min;
  76. tm.tm_sec = dt->sec;
  77. return mktime(&tm);
  78. }
  79. char* datetime_fmt(datetime_t* dt, char* buf) {
  80. sprintf(buf, DATETIME_FMT,
  81. dt->year, dt->month, dt->day,
  82. dt->hour, dt->min, dt->sec, dt->ms);
  83. return buf;
  84. }
  85. char* gmtime_fmt(time_t time, char* buf) {
  86. struct tm* tm = gmtime(&time);
  87. //strftime(buf, GMTIME_FMT_BUFLEN, "%a, %d %b %Y %H:%M:%S GMT", tm);
  88. sprintf(buf, GMTIME_FMT,
  89. s_weekdays[tm->tm_wday],
  90. tm->tm_mday, s_months[tm->tm_mon], tm->tm_year + 1900,
  91. tm->tm_hour, tm->tm_min, tm->tm_sec);
  92. return buf;
  93. }
  94. int days_of_month(int month, int year) {
  95. if (month < 1 || month > 12) {
  96. return 0;
  97. }
  98. int days = s_days[month-1];
  99. return (month == 2 && IS_LEAP_YEAR(year)) ? ++days : days;
  100. }
  101. datetime_t* datetime_past(datetime_t* dt, int days) {
  102. assert(days >= 0);
  103. int sub = days;
  104. while (sub) {
  105. if (dt->day > sub) {
  106. dt->day -= sub;
  107. break;
  108. }
  109. sub -= dt->day;
  110. if (--dt->month == 0) {
  111. dt->month = 12;
  112. --dt->year;
  113. }
  114. dt->day = days_of_month(dt->month, dt->year);
  115. }
  116. return dt;
  117. }
  118. datetime_t* datetime_future(datetime_t* dt, int days) {
  119. assert(days >= 0);
  120. int sub = days;
  121. int mdays;
  122. while (sub) {
  123. mdays = days_of_month(dt->month, dt->year);
  124. if (dt->day + sub <= mdays) {
  125. dt->day += sub;
  126. break;
  127. }
  128. sub -= (mdays - dt->day + 1);
  129. if (++dt->month > 12) {
  130. dt->month = 1;
  131. ++dt->year;
  132. }
  133. dt->day = 1;
  134. }
  135. return dt;
  136. }
  137. time_t calc_next_timeout(int minute, int hour, int day, int week, int month) {
  138. enum {
  139. UNKOWN,
  140. HOURLY,
  141. DAILY,
  142. WEEKLY,
  143. MONTHLY,
  144. YEARLY,
  145. } period_type = UNKOWN;
  146. struct tm tm;
  147. time_t tt;
  148. time(&tt);
  149. tm = *localtime(&tt);
  150. time_t tt_round = 0;
  151. tm.tm_sec = 0;
  152. if (minute >= 0) {
  153. period_type = HOURLY;
  154. tm.tm_min = minute;
  155. }
  156. if (hour >= 0) {
  157. period_type = DAILY;
  158. tm.tm_hour = hour;
  159. }
  160. if (week >= 0) {
  161. period_type = WEEKLY;
  162. }
  163. else if (day > 0) {
  164. period_type = MONTHLY;
  165. tm.tm_mday = day;
  166. if (month > 0) {
  167. period_type = YEARLY;
  168. tm.tm_mon = month - 1;
  169. }
  170. }
  171. if (period_type == UNKOWN) {
  172. return -1;
  173. }
  174. tt_round = mktime(&tm);
  175. if (week >= 0) {
  176. tt_round = tt + (week-tm.tm_wday)*SECONDS_PER_DAY;
  177. }
  178. if (tt_round > tt) {
  179. return tt_round;
  180. }
  181. switch(period_type) {
  182. case HOURLY:
  183. tt_round += SECONDS_PER_HOUR;
  184. return tt_round;
  185. case DAILY:
  186. tt_round += SECONDS_PER_DAY;
  187. return tt_round;
  188. case WEEKLY:
  189. tt_round += SECONDS_PER_WEEK;
  190. return tt_round;
  191. case MONTHLY:
  192. if (++tm.tm_mon == 12) {
  193. tm.tm_mon = 0;
  194. ++tm.tm_year;
  195. }
  196. break;
  197. case YEARLY:
  198. ++tm.tm_year;
  199. break;
  200. default:
  201. return -1;
  202. }
  203. return mktime(&tm);
  204. }
  205. int month_atoi(const char* month) {
  206. for (size_t i = 0; i < 12; ++i) {
  207. if (strnicmp(month, s_months[i], strlen(month)) == 0)
  208. return i+1;
  209. }
  210. return 0;
  211. }
  212. const char* month_itoa(int month) {
  213. assert(month >= 1 && month <= 12);
  214. return s_months[month-1];
  215. }
  216. int weekday_atoi(const char* weekday) {
  217. for (size_t i = 0; i < 7; ++i) {
  218. if (strnicmp(weekday, s_weekdays[i], strlen(weekday)) == 0)
  219. return i;
  220. }
  221. return 0;
  222. }
  223. const char* weekday_itoa(int weekday) {
  224. assert(weekday >= 0 && weekday <= 7);
  225. if (weekday == 7) weekday = 0;
  226. return s_weekdays[weekday];
  227. }
  228. datetime_t hv_compile_datetime() {
  229. static datetime_t dt;
  230. char month[32];
  231. sscanf(__DATE__, "%s %d %d", month, &dt.day, &dt.year);
  232. sscanf(__TIME__, "%d %d %d", &dt.hour, &dt.min, &dt.sec);
  233. dt.month = month_atoi(month);
  234. return dt;
  235. }