1 /* 2 * COPYRIGHT: LGPL, See LGPL.txt in the top level directory 3 * PROJECT: ReactOS CRT library 4 * FILE: lib/sdk/crt/time/asctime.c 5 * PURPOSE: Implementation of asctime(), _asctime_s() 6 * PROGRAMERS: Timo Kreuzer 7 */ 8 #include <precomp.h> 9 #include <tchar.h> 10 #include <time.h> 11 #include "bitsfixup.h" 12 13 #define DAYSPERWEEK 7 14 #define MONSPERYEAR 12 15 #define HUNDREDYEAROFFSET 19 16 17 static const _TCHAR wday_name[DAYSPERWEEK][5] = 18 { 19 _T("Sun "), _T("Mon "), _T("Tue "), _T("Wed "), 20 _T("Thu "), _T("Fri "), _T("Sat ") 21 }; 22 23 static const _TCHAR mon_name[MONSPERYEAR][5] = 24 { 25 _T("Jan "), _T("Feb "), _T("Mar "), _T("Apr "), _T("May "), _T("Jun "), 26 _T("Jul "), _T("Aug "), _T("Sep "), _T("Oct "), _T("Nov "), _T("Dec ") 27 }; 28 29 #ifdef _UNICODE 30 typedef unsigned long long _TCHAR4; 31 typedef unsigned long _TCHAR2; 32 #else 33 typedef unsigned long _TCHAR4; 34 typedef unsigned short _TCHAR2; 35 #endif 36 37 #pragma pack(push,1) 38 typedef union 39 { 40 _TCHAR text[26]; 41 struct 42 { 43 _TCHAR4 WeekDay; 44 _TCHAR4 Month; 45 _TCHAR2 Day; 46 _TCHAR Space1; 47 _TCHAR2 Hour; 48 _TCHAR Sep1; 49 _TCHAR2 Minute; 50 _TCHAR Sep2; 51 _TCHAR2 Second; 52 _TCHAR Space2; 53 _TCHAR2 Year[2]; 54 _TCHAR lb; 55 _TCHAR zt; 56 }; 57 } timebuf_t; 58 #pragma pack(pop) 59 60 FORCEINLINE 61 _TCHAR2 62 IntToChar2(int x) 63 { 64 union 65 { 66 _TCHAR2 char2; 67 _TCHAR array[2]; 68 } u; 69 70 u.array[0] = '0' + (x / 10); 71 u.array[1] = '0' + (x % 10); 72 73 return u.char2; 74 } 75 76 static __inline 77 void 78 FillBuf(timebuf_t *buf, const struct tm *ptm) 79 { 80 /* Format looks like this: 81 * "Sun Mar 01 12:34:56 1902\n\0" */ 82 buf->WeekDay = *(_TCHAR4*)wday_name[ptm->tm_wday]; 83 buf->Month = *(_TCHAR4*)mon_name[ptm->tm_mon]; 84 buf->Day = IntToChar2(ptm->tm_mday); 85 buf->Space1 = ' '; 86 buf->Hour = IntToChar2(ptm->tm_hour); 87 buf->Sep1 = ':'; 88 buf->Minute = IntToChar2(ptm->tm_min); 89 buf->Sep2 = ':'; 90 buf->Second = IntToChar2(ptm->tm_sec); 91 buf->Space2 = ' '; 92 buf->Year[0] = IntToChar2(ptm->tm_year / 100 + HUNDREDYEAROFFSET); 93 buf->Year[1] = IntToChar2(ptm->tm_year % 100); 94 buf->lb = '\n'; 95 buf->zt = '\0'; 96 } 97 98 /****************************************************************************** 99 * \name _tasctime_s 100 * \brief Converts a local time into a string and returns a pointer to it. 101 * \param buffer Buffer that receives the string (26 characters). 102 * \param numberOfElements Size of the buffer in characters. 103 * \param time Pointer to the UTC time. 104 */ 105 errno_t 106 _tasctime_s( 107 _TCHAR* buffer, 108 size_t numberOfElements, 109 const struct tm *ptm) 110 { 111 /* Validate parameters */ 112 if (!buffer || numberOfElements < 26 || !ptm || 113 (unsigned int)ptm->tm_sec > 59 || 114 (unsigned int)ptm->tm_min > 59 || 115 (unsigned int)ptm->tm_hour > 23 || 116 (unsigned int)ptm->tm_mday > 31 || 117 (unsigned int)ptm->tm_mon > 11 || 118 (unsigned int)ptm->tm_year > 2038 || 119 (unsigned int)ptm->tm_wday > 6 || 120 (unsigned int)ptm->tm_yday > 365) 121 { 122 #if 0 123 _invalid_parameter(NULL, 124 #ifdef UNICODE 125 L"_wasctime", 126 #else 127 L"asctime", 128 #endif 129 _CRT_WIDE(__FILE__), 130 __LINE__, 131 0); 132 #endif 133 return EINVAL; 134 } 135 136 /* Fill the buffer */ 137 FillBuf((timebuf_t*)buffer, ptm); 138 139 return 0; 140 } 141 142 /****************************************************************************** 143 * \name _tasctime 144 * \brief Converts a UTC time into a string and returns a pointer to it. 145 * \param ptm Pointer to the UTC time. 146 * \remarks The string is stored in thread local buffer, shared between 147 * ctime, gmtime and localtime (32 and 64 bit versions). 148 */ 149 _TCHAR * 150 _tasctime(const struct tm *ptm) 151 { 152 thread_data_t *data = msvcrt_get_thread_data(); 153 _TCHAR *pstr; 154 155 #ifndef _UNICODE 156 pstr = data->asctime_buffer; 157 #else 158 pstr = data->wasctime_buffer; 159 #endif 160 161 if(!pstr) 162 pstr = malloc(sizeof(struct tm)); 163 164 /* Fill the buffer */ 165 FillBuf((timebuf_t*)pstr, ptm); 166 167 return pstr; 168 } 169