Skip to content

Commit e63ffc1

Browse files
committed
rt: Convert timezone to utf-8 on Windows
Previously #9418 fixed utf-8 assertion issue by wcsftime, but the function didn't work as expected: it follows the locale set by setlocale(), not the system code page. This patch fixes it by manual multibyte-to-unicode conversion.
1 parent 72e432d commit e63ffc1

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

src/rt/rust_builtin.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -325,11 +325,16 @@ rust_localtime(int64_t sec, int32_t nsec, rust_tm *timeptr) {
325325
const char* zone = NULL;
326326
#if defined(__WIN32__)
327327
int32_t gmtoff = -timezone;
328-
wchar_t wbuffer[64];
329-
char buffer[256];
328+
wchar_t wbuffer[64] = {0};
329+
char buffer[256] = {0};
330330
// strftime("%Z") can contain non-UTF-8 characters on non-English locale (issue #9418),
331-
// so time zone should be converted from UTF-16 string set by wcsftime.
332-
if (wcsftime(wbuffer, sizeof(wbuffer) / sizeof(wchar_t), L"%Z", &tm) > 0) {
331+
// so time zone should be converted from UTF-16 string.
332+
// Since wcsftime depends on setlocale() result,
333+
// instead we convert it using MultiByteToWideChar.
334+
if (strftime(buffer, sizeof(buffer) / sizeof(char), "%Z", &tm) > 0) {
335+
// ANSI -> UTF-16
336+
MultiByteToWideChar(CP_ACP, 0, buffer, -1, wbuffer, sizeof(wbuffer) / sizeof(wchar_t));
337+
// UTF-16 -> UTF-8
333338
WideCharToMultiByte(CP_UTF8, 0, wbuffer, -1, buffer, sizeof(buffer), NULL, NULL);
334339
zone = buffer;
335340
}

0 commit comments

Comments
 (0)