ctime.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. #include "bsp_rtc.h"
  2. #include "ctime.h"
  3. #include "stdint.h"
  4. #include "stdio.h"
  5. #include "time.h"
  6. #include "string.h"
  7. #include "gd32f4xx_libopt.h"
  8. #include "clock.h"
  9. #define RT_LIBC_TZ_DEFAULT_HOUR 8
  10. #define RT_LIBC_TZ_DEFAULT_MIN 0
  11. #define RT_LIBC_TZ_DEFAULT_SEC 0
  12. static const short __spm[13] =
  13. {
  14. 0,
  15. (31),
  16. (31 + 28),
  17. (31 + 28 + 31),
  18. (31 + 28 + 31 + 30),
  19. (31 + 28 + 31 + 30 + 31),
  20. (31 + 28 + 31 + 30 + 31 + 30),
  21. (31 + 28 + 31 + 30 + 31 + 30 + 31),
  22. (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31),
  23. (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30),
  24. (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31),
  25. (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30),
  26. (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31),
  27. };
  28. #define rt_align(n) __attribute__((aligned(n)))
  29. rt_align(8) static const char *days = "Sun Mon Tue Wed Thu Fri Sat ";
  30. rt_align(8) static const char *months = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ";
  31. #ifndef __isleap
  32. static int __isleap(int year)
  33. {
  34. /* every fourth year is a leap year except for century years that are
  35. * not divisible by 400. */
  36. /* return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); */
  37. return (!(year % 4) && ((year % 100) || !(year % 400)));
  38. }
  39. #endif
  40. static void num2str(char *c, int i)
  41. {
  42. c[0] = i / 10 + '0';
  43. c[1] = i % 10 + '0';
  44. }
  45. static volatile int32_t _current_tz_offset_sec = \
  46. RT_LIBC_TZ_DEFAULT_HOUR * 3600U + RT_LIBC_TZ_DEFAULT_MIN * 60U + RT_LIBC_TZ_DEFAULT_SEC;
  47. void fr_tz_set(int32_t offset_sec)
  48. {
  49. _current_tz_offset_sec = offset_sec;
  50. }
  51. int32_t fr_tz_get(void)
  52. {
  53. return _current_tz_offset_sec;
  54. }
  55. int8_t fr_tz_is_dst(void)
  56. {
  57. return 0U; /* TODO */
  58. }
  59. struct tm *gmtime_r(const time_t *timep, struct tm *r)
  60. {
  61. int i;
  62. int work;
  63. if(timep == NULL || r == NULL)
  64. {
  65. return NULL;
  66. }
  67. memset(r, NULL, sizeof(struct tm));
  68. work = *timep % (24*60*60);
  69. r->tm_sec = work % 60;
  70. work /= 60;
  71. r->tm_min = work % 60;
  72. r->tm_hour = work / 60;
  73. work = (int)(*timep / (24*60*60));
  74. r->tm_wday = (4 + work) % 7;
  75. for (i = 1970;; ++i)
  76. {
  77. int k = __isleap(i) ? 366 : 365;
  78. if (work >= k)
  79. work -= k;
  80. else
  81. break;
  82. }
  83. r->tm_year = i - 1900;
  84. r->tm_yday = work;
  85. r->tm_mday = 1;
  86. if (__isleap(i) && (work > 58))
  87. {
  88. if (work == 59)
  89. r->tm_mday = 2; /* 29.2. */
  90. work -= 1;
  91. }
  92. for (i = 11; i && (__spm[i] > work); --i);
  93. r->tm_mon = i;
  94. r->tm_mday += work - __spm[i];
  95. r->tm_isdst = 0U;
  96. return r;
  97. }
  98. struct tm* localtime_r(const time_t* t, struct tm* r)
  99. {
  100. time_t local_tz;
  101. local_tz = *t + fr_tz_get();
  102. return gmtime_r(&local_tz, r);
  103. }
  104. struct tm* localtime(const time_t* t)
  105. {
  106. static struct tm tmp;
  107. return localtime_r(t, &tmp);
  108. }
  109. time_t timegm(struct tm * const t)
  110. {
  111. time_t day;
  112. time_t i;
  113. time_t years;
  114. if(t == NULL)
  115. {
  116. return (time_t)-1;
  117. }
  118. years = (time_t)t->tm_year - 70;
  119. if (t->tm_sec > 60) /* seconds after the minute - [0, 60] including leap second */
  120. {
  121. t->tm_min += t->tm_sec / 60;
  122. t->tm_sec %= 60;
  123. }
  124. if (t->tm_min >= 60) /* minutes after the hour - [0, 59] */
  125. {
  126. t->tm_hour += t->tm_min / 60;
  127. t->tm_min %= 60;
  128. }
  129. if (t->tm_hour >= 24) /* hours since midnight - [0, 23] */
  130. {
  131. t->tm_mday += t->tm_hour / 24;
  132. t->tm_hour %= 24;
  133. }
  134. if (t->tm_mon >= 12) /* months since January - [0, 11] */
  135. {
  136. t->tm_year += t->tm_mon / 12;
  137. t->tm_mon %= 12;
  138. }
  139. while (t->tm_mday > __spm[1 + t->tm_mon])
  140. {
  141. if (t->tm_mon == 1 && __isleap(t->tm_year + 1900))
  142. {
  143. --t->tm_mday;
  144. }
  145. t->tm_mday -= __spm[t->tm_mon];
  146. ++t->tm_mon;
  147. if (t->tm_mon > 11)
  148. {
  149. t->tm_mon = 0;
  150. ++t->tm_year;
  151. }
  152. }
  153. if (t->tm_year < 70)
  154. {
  155. return (time_t) -1;
  156. }
  157. /* Days since 1970 is 365 * number of years + number of leap years since 1970 */
  158. day = years * 365 + (years + 1) / 4;
  159. /* After 2100 we have to substract 3 leap years for every 400 years
  160. This is not intuitive. Most mktime implementations do not support
  161. dates after 2059, anyway, so we might leave this out for it's
  162. bloat. */
  163. if (years >= 131)
  164. {
  165. years -= 131;
  166. years /= 100;
  167. day -= (years >> 2) * 3 + 1;
  168. if ((years &= 3) == 3)
  169. years--;
  170. day -= years;
  171. }
  172. day += t->tm_yday = __spm[t->tm_mon] + t->tm_mday - 1 +
  173. (__isleap(t->tm_year + 1900) & (t->tm_mon > 1));
  174. /* day is now the number of days since 'Jan 1 1970' */
  175. i = 7;
  176. t->tm_wday = (int)((day + 4) % i); /* Sunday=0, Monday=1, ..., Saturday=6 */
  177. i = 24;
  178. day *= i;
  179. i = 60;
  180. return ((day + t->tm_hour) * i + t->tm_min) * i + t->tm_sec;
  181. }
  182. time_t mktime(struct tm * const t)
  183. {
  184. time_t timestamp;
  185. timestamp = timegm(t);
  186. timestamp = timestamp - fr_tz_get();
  187. return timestamp;
  188. }
  189. char* asctime_r(const struct tm *t, char *buf)
  190. {
  191. if(t == NULL || buf == NULL)
  192. {
  193. return NULL;
  194. }
  195. memset(buf, NULL, 26);
  196. /* Checking input validity */
  197. if ((int)strlen(days) <= (t->tm_wday << 2) || (int)strlen(months) <= (t->tm_mon << 2))
  198. {
  199. *(int*) buf = *(int*) days;
  200. *(int*) (buf + 4) = *(int*) months;
  201. num2str(buf + 8, t->tm_mday);
  202. if (buf[8] == '0')
  203. buf[8] = ' ';
  204. buf[10] = ' ';
  205. num2str(buf + 11, t->tm_hour);
  206. buf[13] = ':';
  207. num2str(buf + 14, t->tm_min);
  208. buf[16] = ':';
  209. num2str(buf + 17, t->tm_sec);
  210. buf[19] = ' ';
  211. num2str(buf + 20, 2000 / 100);
  212. num2str(buf + 22, 2000 % 100);
  213. buf[24] = '\n';
  214. buf[25] = '\0';
  215. return buf;
  216. }
  217. /* "Wed Jun 30 21:49:08 1993\n" */
  218. *(int*) buf = *(int*) (days + (t->tm_wday << 2));
  219. *(int*) (buf + 4) = *(int*) (months + (t->tm_mon << 2));
  220. num2str(buf + 8, t->tm_mday);
  221. if (buf[8] == '0')
  222. buf[8] = ' ';
  223. buf[10] = ' ';
  224. num2str(buf + 11, t->tm_hour);
  225. buf[13] = ':';
  226. num2str(buf + 14, t->tm_min);
  227. buf[16] = ':';
  228. num2str(buf + 17, t->tm_sec);
  229. buf[19] = ' ';
  230. num2str(buf + 20, (t->tm_year + 1900) / 100);
  231. num2str(buf + 22, (t->tm_year + 1900) % 100);
  232. buf[24] = '\n';
  233. buf[25] = '\0';
  234. return buf;
  235. }
  236. char *asctime(const struct tm *timeptr)
  237. {
  238. static char buf[26];
  239. return asctime_r(timeptr, buf);
  240. }
  241. char *ctime_r(const time_t * tim_p, char * result)
  242. {
  243. struct tm tm;
  244. return asctime_r(localtime_r(tim_p, &tm), result);
  245. }
  246. char *ctime(const time_t *tim_p)
  247. {
  248. return asctime(localtime(tim_p));
  249. }
  250. #if (!defined __ARMCC_VERSION) && (!defined __CC_ARM) && (!defined __ICCARM__)
  251. double difftime(time_t time1, time_t time2)
  252. {
  253. return (double)(time1 - time2);
  254. }
  255. #endif
  256. time_t time(time_t *t)
  257. {
  258. time_t _t;
  259. //TODO
  260. struct timeval tv;
  261. bsp_rtc_get_timeval(&tv);
  262. _t = tv.tv_sec;
  263. if (t)
  264. *t = _t;
  265. return _t;
  266. }
  267. clock_t clock(void)
  268. {
  269. return fr_tick_get(); // TODO should return cpu usage time
  270. }
  271. int stime(const time_t *t)
  272. {
  273. //TODO
  274. if(t==NULL)
  275. return -1;
  276. bsp_rtc_set_time_stamp(*t);
  277. return 0;
  278. }
  279. int gettimeofday(struct timeval *tv, struct timezone *tz)
  280. {
  281. /* The use of the timezone structure is obsolete;
  282. * the tz argument should normally be specified as NULL.
  283. * The tz_dsttime field has never been used under Linux.
  284. * Thus, the following is purely of historic interest.
  285. */
  286. if(tz != NULL)
  287. {
  288. tz->tz_dsttime = DST_NONE;
  289. tz->tz_minuteswest = -(fr_tz_get() / 60);
  290. }
  291. if (tv != NULL)
  292. {
  293. tv->tv_sec = 0;
  294. tv->tv_usec = 0;
  295. bsp_rtc_get_timeval(tv);
  296. }
  297. //rt_set_errno(EINVAL);
  298. return 0;
  299. }