time.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. */
  9. #include <sys/time.h>
  10. #include <rtthread.h>
  11. /* days per month -- nonleap! */
  12. 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. /* seconds per day */
  29. #define SPD 24*60*60
  30. #ifdef RT_USING_DEVICE
  31. int gettimeofday(struct timeval *tp, void *ignore)
  32. {
  33. time_t time;
  34. rt_device_t device;
  35. device = rt_device_find("rtc");
  36. if (device != RT_NULL)
  37. {
  38. rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time);
  39. if (tp != RT_NULL)
  40. {
  41. tp->tv_sec = time;
  42. tp->tv_usec = 0;
  43. }
  44. return time;
  45. }
  46. return 0;
  47. }
  48. #endif
  49. /**
  50. * Returns the current time.
  51. *
  52. * @param time_t * t the timestamp pointer, if not used, keep NULL.
  53. *
  54. * @return time_t return timestamp current.
  55. *
  56. */
  57. /* for IAR 6.2 later Compiler */
  58. #if defined (__IAR_SYSTEMS_ICC__) && (__VER__) >= 6020000
  59. #pragma module_name = "?time"
  60. time_t (__time32)(time_t *t) /* Only supports 32-bit timestamp */
  61. #else
  62. time_t time(time_t *t)
  63. #endif
  64. {
  65. time_t time_now = 0;
  66. #ifdef RT_USING_RTC
  67. static rt_device_t device = RT_NULL;
  68. /* optimization: find rtc device only first. */
  69. if (device == RT_NULL)
  70. {
  71. device = rt_device_find("rtc");
  72. }
  73. /* read timestamp from RTC device. */
  74. if (device != RT_NULL)
  75. {
  76. if (rt_device_open(device, 0) == RT_EOK)
  77. {
  78. rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time_now);
  79. rt_device_close(device);
  80. }
  81. }
  82. #endif /* RT_USING_RTC */
  83. /* if t is not NULL, write timestamp to *t */
  84. if (t != RT_NULL)
  85. {
  86. *t = time_now;
  87. }
  88. return time_now;
  89. }
  90. static int __isleap(int year)
  91. {
  92. /* every fourth year is a leap year except for century years that are
  93. * not divisible by 400. */
  94. /* return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); */
  95. return (!(year % 4) && ((year % 100) || !(year % 400)));
  96. }
  97. /**
  98. * This function will convert Time (Restartable)
  99. *
  100. * @param timep the timestamp
  101. * @param the structure to stores information
  102. *
  103. * @return the structure to stores information
  104. *
  105. */
  106. struct tm *gmtime_r(const time_t *timep, struct tm *r)
  107. {
  108. time_t i;
  109. register time_t work = *timep % (SPD);
  110. r->tm_sec = work % 60;
  111. work /= 60;
  112. r->tm_min = work % 60;
  113. r->tm_hour = work / 60;
  114. work = *timep / (SPD);
  115. r->tm_wday = (4 + work) % 7;
  116. for (i = 1970;; ++i)
  117. {
  118. register time_t k = __isleap(i) ? 366 : 365;
  119. if (work >= k)
  120. work -= k;
  121. else
  122. break;
  123. }
  124. r->tm_year = i - 1900;
  125. r->tm_yday = work;
  126. r->tm_mday = 1;
  127. if (__isleap(i) && (work > 58))
  128. {
  129. if (work == 59)
  130. r->tm_mday = 2; /* 29.2. */
  131. work -= 1;
  132. }
  133. for (i = 11; i && (__spm[i] > work); --i)
  134. ;
  135. r->tm_mon = i;
  136. r->tm_mday += work - __spm[i];
  137. return r;
  138. }
  139. RT_WEAK clock_t clock(void)
  140. {
  141. return rt_tick_get();
  142. }