Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/msvcrt/time.c | 86 ++++++++++++++++++-------------------- dlls/ucrtbase/tests/misc.c | 2 +- 2 files changed, 42 insertions(+), 46 deletions(-)
diff --git a/dlls/msvcrt/time.c b/dlls/msvcrt/time.c index 058a8a53c9..30f59e0846 100644 --- a/dlls/msvcrt/time.c +++ b/dlls/msvcrt/time.c @@ -54,6 +54,12 @@ static const int MonthLengths[2][12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } };
+#if _MSVCR_VER>=140 +static const int MAX_SECONDS = 60; +#else +static const int MAX_SECONDS = 59; +#endif + static inline BOOL IsLeapYear(int Year) { return Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0); @@ -954,45 +960,6 @@ char ** CDECL __p__tzname(void) return MSVCRT__tzname; }
-static inline BOOL strftime_time(char *str, MSVCRT_size_t *pos, MSVCRT_size_t max, - const struct MSVCRT_tm *mstm, MSVCRT___lc_time_data *time_data) -{ - SYSTEMTIME st; - MSVCRT_size_t ret; - LCID lcid; - - st.wYear = mstm->tm_year + 1900; - st.wMonth = mstm->tm_mon + 1; - st.wDayOfWeek = mstm->tm_wday; - st.wDay = mstm->tm_mday; - st.wHour = mstm->tm_hour; - st.wMinute = mstm->tm_min; - st.wSecond = mstm->tm_sec; - st.wMilliseconds = 0; - -#if _MSVCR_VER < 110 - lcid = time_data->lcid; -#else - lcid = LocaleNameToLCID(time_data->locname, 0); -#endif - - ret = GetTimeFormatA(lcid, 0, &st, time_data->str.names.time, NULL, 0); - if(ret && ret<max-*pos) - ret = GetTimeFormatA(lcid, 0, &st, time_data->str.names.time, - str+*pos, max-*pos); - if(!ret) { - *str = 0; - *MSVCRT__errno() = MSVCRT_EINVAL; - return FALSE; - }else if(ret > max-*pos) { - *str = 0; - *MSVCRT__errno() = MSVCRT_ERANGE; - return FALSE; - } - *pos += ret-1; - return TRUE; -} - static inline BOOL strftime_tzdiff(char *str, MSVCRT_size_t *pos, MSVCRT_size_t max, BOOL is_dst) { MSVCRT_long tz = MSVCRT___timezone + (is_dst ? MSVCRT__dstbias : 0); @@ -1117,10 +1084,39 @@ static inline BOOL strftime_format(char *str, MSVCRT_size_t *pos, MSVCRT_size_t while(*format == *substr) format++; /* TODO: era */ break; + case 'h': + while(*format == *substr) format++; + if(!MSVCRT_CHECK_PMT(mstm->tm_hour>=0 && mstm->tm_hour<=23)) + goto einval_error; + ret = strftime_int(str, pos, max, (mstm->tm_hour + 11) % 12 + 1, + (format - substr < 2) ? 0 : 2, 1, 12); + break; + case 'H': + while(*format == *substr) format++; + ret = strftime_int(str, pos, max, mstm->tm_hour, (format - substr < 2) ? 0 : 2, 0, 23); + break; + case 'm': + while(*format == *substr) format++; + ret = strftime_int(str, pos, max, mstm->tm_min, (format - substr < 2) ? 0 : 2, 0, 59); + break; + case 's': + while(*format == *substr) format++; + ret = strftime_int(str, pos, max, mstm->tm_sec, + (format - substr < 2) ? 0 : 2, 0, MAX_SECONDS); + break; + case 't': + while(*format == *substr) format++; + if(!MSVCRT_CHECK_PMT(mstm->tm_hour>=0 && mstm->tm_hour<=23)) + goto einval_error; + ret = strftime_nstr(str, pos, max, + (mstm->tm_hour < 12) ? time_data->str.names.am : time_data->str.names.pm, + (format - substr < 2) ? 1 : MSVCRT_SIZE_MAX); + break; default: while(*format && *format != ''' && - *format != 'd' && *format != 'M' && - *format != 'y' && *format != 'g') + *format != 'd' && *format != 'M' && *format != 'y' && + *format != 'g' && *format != 'h' && *format != 'H' && + *format != 'm' && *format != 's' && *format != 't') format++; ret = strftime_nstr(str, pos, max, substr, format - substr); break; @@ -1182,7 +1178,7 @@ static MSVCRT_size_t strftime_helper(char *str, MSVCRT_size_t max, const char *f return 0; if(ret < max) str[ret++] = ' '; - if(!strftime_time(str, &ret, max, mstm, time_data)) + if(!strftime_format(str, &ret, max, mstm, time_data, time_data->str.names.time)) return 0; break; case 'x': @@ -1191,7 +1187,7 @@ static MSVCRT_size_t strftime_helper(char *str, MSVCRT_size_t max, const char *f return 0; break; case 'X': - if(!strftime_time(str, &ret, max, mstm, time_data)) + if(!strftime_format(str, &ret, max, mstm, time_data, time_data->str.names.time)) return 0; break; case 'a': @@ -1329,7 +1325,7 @@ static MSVCRT_size_t strftime_helper(char *str, MSVCRT_size_t max, const char *f break; #endif case 'S': - if(!strftime_int(str, &ret, max, mstm->tm_sec, alternate ? 0 : 2, 0, 59)) + if(!strftime_int(str, &ret, max, mstm->tm_sec, alternate ? 0 : 2, 0, MAX_SECONDS)) return 0; break; #if _MSVCR_VER>=140 @@ -1345,7 +1341,7 @@ static MSVCRT_size_t strftime_helper(char *str, MSVCRT_size_t max, const char *f return 0; if(ret < max) str[ret++] = ':'; - if(!strftime_int(str, &ret, max, mstm->tm_sec, alternate ? 0 : 2, 0, 59)) + if(!strftime_int(str, &ret, max, mstm->tm_sec, alternate ? 0 : 2, 0, MAX_SECONDS)) return 0; break; case 'u': diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c index 35b7375cd8..3aca31734f 100644 --- a/dlls/ucrtbase/tests/misc.c +++ b/dlls/ucrtbase/tests/misc.c @@ -946,7 +946,7 @@ static void test_strftime(void) {"%#x", "Thursday, February 30, 1970", { 0, 0, 0, 30, 1, 70, 4, 0, 0 }}, {"%X", "00:00:00", { 0, 0, 0, 1, 0, 70, 4, 0, 0 }}, {"%X", "14:00:00", { 0, 0, 14, 1, 0, 70, 4, 0, 0 }}, - {"%X", "23:59:60", { 60, 59, 23, 1, 0, 70, 4, 0, 0 }, TRUE}, + {"%X", "23:59:60", { 60, 59, 23, 1, 0, 70, 4, 0, 0 }}, };
const struct tm epoch = { 0, 0, 0, 1, 0, 70, 4, 0, 0 };