字體:小 中 大 | |
|
||||||||||||||||||||||||||||||
2023/11/02 09:18:57瀏覽65|回應0|推薦0 | ||||||||||||||||||||||||||||||
前陣子實作貨幣的數字中文大寫轉換時,發現Microsoft Visual Studio International Feature Pack 2.0中就有內建的數字轉中文大寫,實作後使用上並沒有什麼問題,直到近期Windows更新後發現,在轉換時會出現” The specified format is not supported in this culture”的錯誤訊息,研究後發現似乎與.NET全球化和ICU有關。 1.原始程式: 原本使用Microsoft Visual Studio International Feature Pack 2.0內建的” EastAsiaNumericFormatter.FormatWithCulture”功能來做轉換,程式碼如下。 當輸入為840時,輸出的大寫中文字為「捌佰肆拾」。 2.Windows Update後開始出現錯誤訊息: 在某次的Windows Update後,當程式執行到” EastAsiaNumericFormatter.FormatWithCulture”時,便會出現以下錯誤訊息” The specified format is not supported in this culture”。 查看了微軟所提供的程式碼。 internal static EastAsiaFormatter Create(CultureInfo culture, string format) 發現CultureInfo也有包含原先我們使用的(”zh-CHT”),看上去似乎沒什麼問題。 再接著查看” culture.IsNeutralCulture”與”culture.Parent”: IsNeutralCulture為false,因此在while判斷時,culture變成了culture.Parent的”zh-Hant”,又下方的if條件並沒有”zh-Hant”,因此被判斷為不支援的culture format。 3.全球化 API 在 Windows 10上使用 ICU 程式庫:
查看上方微軟所提供的結果,根據微軟提供的CultureInfo.IsNeutralCulture 屬性,zh-CHT的IsNeutralCulture應為true,而在我們的程式中卻為false,經查發現,Windows 10 2019年5月更新和更新版本包含icu.dll作為OS的一部分,而.NET 5和更新版本預設會使用ICU。在Windows上執行時,.NET 5和更新版本會嘗試載入icu.dll,如果找不到或無法載入ICU程式庫,.NET 5和更新版本會回復為以NLS為基礎的實作。 查看上方實際本機實作輸出結果,由於載入了ICU程式庫,而ICU程式庫中的Culture已不包含zh-CHT,因此IsNeutralCulture變成false,導致使用FormatWithCulture時無法在程式中if條件上找到對應的項目。 4.解決方式 使用 NLS 而非 ICU: 因ICU程式庫的影響,在Microsoft Visual Studio International Feature Pack 2.0更新前,僅能手動設定回舊版的程式庫,才能繼續使用微軟尚未更新的功能,而官方提供了三種方法讓使用者修改設定,分別為 1.在專案檔新增: <ItemGroup> 2.在 runtimeconfig.json 檔案新增:
{ 3.將環境變數 DOTNET_SYSTEM_GLOBALIZATION_USENLS的值設定為true或1。 修改後可以看到,IsNeutralCulture變回true了。 5.結語: 使用ICU可能會導致某些全球化相關作業的差異,微軟官網也針對此部分了提供了「全球化最佳做法、當地語系化最佳做法、ASP.NET 應用程式的全球化最佳做法」等的建議,如果使用了官網提供的建議後程式依然出現錯誤或無法執行,也可以依照官方提供的設定方式嘗試改回使用NLS而非ICU。 Reference |
||||||||||||||||||||||||||||||
( 知識學習|其他 ) |