Getting the current time zone in non-English regions does not meet expectations

Taking my location, Mainland China, as an example, the correct identifier is Asia/Shanghai. The Windows language environment is Chinese. I looked at the swift-foundation source code, which uses GetTimeZoneInformation to get time zone information, resulting in a localized (中国标准时间). What is expected is China Standard Time. Using GetDynamicTimeZoneInformation can solve this problem. Unfortunately, I was unable to build from the latest branch of the source repository. Looking forward to a fix.

/// TimeZone_cache.swift:130

var timeZoneInfo = TIME_ZONE_INFORMATION()
if GetTimeZoneInformation(&timeZoneInfo) != TIME_ZONE_ID_INVALID {
let windowsName = withUnsafePointer(to: &(timeZoneInfo.StandardName)) {
$0.withMemoryRebound(to: WCHAR.self, capacity: 32) {
String(decoding: UnsafeBufferPointer(start: $0, count: wcslen($0)), as: UTF16.self)
}
}
if let identifier = _timeZoneIdentifier(forWindowsIdentifier: windowsName), let result = fixed(identifier) {
return TimeZone(inner: result)
}
}

Replace

var timeZoneInfo = DYNAMIC_TIME_ZONE_INFORMATION()
if GetDynamicTimeZoneInformation(&timeZoneInfo) != TIME_ZONE_ID_INVALID {
let windowsName = withUnsafePointer(to: &(timeZoneInfo.TimeZoneKeyName)) {
$0.withMemoryRebound(to: WCHAR.self, capacity: 128) {
String(decoding: UnsafeBufferPointer(start: $0, count: wcslen($0)), as: UTF16.self)
}
}
if let identifier = _timeZoneIdentifier(forWindowsIdentifier: windowsName), let result = fixed(identifier) {
return TimeZone(inner: result)
}
}

I would recommend filing a bug report using GitHub Issues, but first I think it would help to be more precise about the erroneous behavior. If I understand correctly, you are saying that TimeZone is using the wrong API to get the user’s current timezone identifier, and is winding up with a localized string instead of TZInfo-style English string. What problem does this cause down the line?

1 Like

Yes, `TIME_ZONE_INFORMATION.StandardName` returns a localized string, but the function `_timeZoneIdentifier` accepts a WindowsZone-style string (e.g., Central Standard Time). Unknown names return en_001 instead of a TZinfo-style identifier, causing `TimeZone.current` to not work as expected.