asctime.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*
  2. * Copyright (C) 2014 by Ole Reinhardt <ole.reinhardt@embedded-it.de>
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the copyright holders nor the names of
  14. * contributors may be used to endorse or promote products derived
  15. * from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  20. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  21. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  23. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  24. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  25. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  26. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  27. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. *
  30. * For additional information see http://www.ethernut.de/
  31. */
  32. #include <stdio.h>
  33. #include <stdint.h>
  34. #include <string.h>
  35. #include <time.h>
  36. #include <errno.h>
  37. #include "ctime.h"
  38. /*!
  39. * \addtogroup xgCrtTime
  40. * @{
  41. */
  42. #define ASCTIME_FMT "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %4d\n"
  43. #define ASCTIME_BUF_SIZE 26
  44. static char buf_asctime[ASCTIME_BUF_SIZE];
  45. /*!
  46. * \brief Convert the broken-down time value tm into a null-terminated string.
  47. *
  48. * The output format is the same as ctime() generates.
  49. * (ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition)
  50. *
  51. * This is the thread safe version of asctime(). It does the same but stores the
  52. * generated string in a user supplied buffer, which should have root for at
  53. * least 26 chars.
  54. *
  55. * \param timeptr Pointer to structure ::tm where the time is stored
  56. * \param buf Pointer to the result buffer. Should have root for at least
  57. * 26 chars.
  58. *
  59. * \return Pointer to the converted string or NULL in case of an error.
  60. */
  61. char *asctime_r(const struct _tm *timeptr, char *buf)
  62. {
  63. static const char wday_name[][3] = {
  64. "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  65. };
  66. static const char mon_name[][3] = {
  67. "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  68. "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  69. };
  70. const char *wn;
  71. const char *mn;
  72. if (timeptr == NULL) {
  73. errno = EINVAL;
  74. if (buf) {
  75. strcpy(buf, "??? ??? ?? ??:??:?? ????\n");
  76. }
  77. return buf;
  78. }
  79. if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6) {
  80. wn = "???";
  81. } else {
  82. wn = wday_name[timeptr->tm_wday];
  83. }
  84. if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11) {
  85. mn = "???";
  86. } else {
  87. mn = mon_name[timeptr->tm_mon];
  88. }
  89. if (buf) {
  90. sprintf(buf, ASCTIME_FMT, wn, mn,
  91. timeptr->tm_mday, timeptr->tm_hour,
  92. timeptr->tm_min, timeptr->tm_sec,
  93. timeptr->tm_year + 1900);
  94. } else {
  95. errno = EINVAL;
  96. return NULL;
  97. }
  98. return buf;
  99. }
  100. /*!
  101. * \brief Convert the broken-down time value tm into a null-terminated string.
  102. *
  103. * The output format is the same as ctime() generates.
  104. * (ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition)
  105. *
  106. * The return value points to a statically allocated string which might be
  107. * overwritten by subsequent calls to asctime.
  108. *
  109. * \param timeptr Pointer to structure ::tm where the time is stored
  110. *
  111. * \return Pointer to the converted string or NULL in case of an error.
  112. */
  113. /*
  114. Note: This function is *not* thread safe, because it uses a static variable
  115. to store the calculated values. To be safe, you must surround the call to asctime
  116. _and_ the usage of the returned pointer with NutEnterCritical() and NutExitCritical()!
  117. Provided for compatibility to std c lib.
  118. */
  119. char *asctime(register const struct _tm *timeptr)
  120. {
  121. return asctime_r(timeptr, buf_asctime);
  122. }
  123. /*!
  124. * \brief Convert the broken-down localtime value tm into a null-terminated
  125. * string.
  126. *
  127. * Same as asctime(localtime(t))
  128. *
  129. * \param timep Pointer to time_t value where the time is stored
  130. *
  131. * \return Pointer to the converted string or NULL in case of an error.
  132. */
  133. /*
  134. Note: This function is *not* thread safe, because it uses a static variable
  135. to store the calculated values. To be safe, you must surround the call to asctime
  136. _and_ the usage of the returned pointer with NutEnterCritical() and NutExitCritical()!
  137. Provided for compatibility to std c lib.
  138. */
  139. char *ctime(const time_t *const timep)
  140. {
  141. return asctime(localtime(timep));
  142. }
  143. /*!
  144. * \brief Convert the broken-down localtime value tm into a null-terminated
  145. * string.
  146. *
  147. * Reentrant version of ctime.
  148. *
  149. * \param timep Pointer to time_t value where the time is stored
  150. *
  151. * \param buf Pointer to the result buffer. Should have root for at least
  152. * 26 chars.
  153. *
  154. * \return Pointer to the converted string or NULL in case of an error.
  155. */
  156. char *ctime_r(const time_t *const timep, char *buf)
  157. {
  158. struct _tm time;
  159. localtime_r(timep, &time);
  160. return asctime_r(&time, buf);
  161. }
  162. /*@}*/