time.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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. #pragma module_name = "?time"
  58. #if _DLIB_TIME_ALLOW_64
  59. __time64_t __time64(__time64_t *t)
  60. #else
  61. __time32_t __time32(__time32_t *t)
  62. #endif
  63. {
  64. time_t time_now = 0;
  65. #ifdef RT_USING_RTC
  66. static rt_device_t device = RT_NULL;
  67. /* optimization: find rtc device only first. */
  68. if (device == RT_NULL)
  69. {
  70. device = rt_device_find("rtc");
  71. }
  72. /* read timestamp from RTC device. */
  73. if (device != RT_NULL)
  74. {
  75. if (rt_device_open(device, 0) == RT_EOK)
  76. {
  77. rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time_now);
  78. rt_device_close(device);
  79. }
  80. }
  81. #endif /* RT_USING_RTC */
  82. /* if t is not NULL, write timestamp to *t */
  83. if (t != RT_NULL)
  84. {
  85. *t = time_now;
  86. }
  87. return time_now;
  88. }
  89. static int __isleap(int year)
  90. {
  91. /* every fourth year is a leap year except for century years that are
  92. * not divisible by 400. */
  93. /* return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); */
  94. return (!(year % 4) && ((year % 100) || !(year % 400)));
  95. }
  96. /**
  97. * This function will convert Time (Restartable)
  98. *
  99. * @param timep the timestamp
  100. * @param the structure to stores information
  101. *
  102. * @return the structure to stores information
  103. *
  104. */
  105. struct tm *gmtime_r(const time_t *timep, struct tm *r)
  106. {
  107. time_t i;
  108. register time_t work = *timep % (SPD);
  109. r->tm_sec = work % 60;
  110. work /= 60;
  111. r->tm_min = work % 60;
  112. r->tm_hour = work / 60;
  113. work = *timep / (SPD);
  114. r->tm_wday = (4 + work) % 7;
  115. for (i = 1970;; ++i)
  116. {
  117. register time_t k = __isleap(i) ? 366 : 365;
  118. if (work >= k)
  119. work -= k;
  120. else
  121. break;
  122. }
  123. r->tm_year = i - 1900;
  124. r->tm_yday = work;
  125. r->tm_mday = 1;
  126. if (__isleap(i) && (work > 58))
  127. {
  128. if (work == 59)
  129. r->tm_mday = 2; /* 29.2. */
  130. work -= 1;
  131. }
  132. for (i = 11; i && (__spm[i] > work); --i)
  133. ;
  134. r->tm_mon = i;
  135. r->tm_mday += work - __spm[i];
  136. return r;
  137. }
  138. RT_WEAK clock_t clock(void)
  139. {
  140. return rt_tick_get();
  141. }