Date format culture differences with .NET 4.8 and .NET 8 [duplicate]
Asked Answered
D

2

5

I have this bit of code and when running in .NET 4.8 gives a different result than .NET 8

 var cultureInfo = CultureInfo.CreateSpecificCulture("ar-KW");
 var date = new DateTime(2024, 10, 12);
 string result = date.ToString("d", cultureInfo);

.NET 4.8 => 12/10/2024

.NET 8.0 => 12‏‏/10‏‏/2024

The .NET 8 version does appear to have special characters (unicode??).

Can someone explain the differences and how to get the .NET 8 to perform consistently with 4.8.

Disenthrall answered 14/10 at 5:41 Comment(2)
Yes, it .Net 8 uses \u200f/ as a delimiter where \u200f is a special 'Right-to-left mark' symbolEpicalyx
.NET 8 is .NET Core 8. The differences were introduced with .NET Core itself, not .NET 8. What you see as special characters are Left-to-Right and Right-to-Left marks, which should be expected in ArabicGonorrhea
K
7

This is due to changes made to .NET to support ICU rather than NLS

If you want to revert to the previous behaviour in a .NET 8 application, add the following to the ".csproj" project file and rebuild:

<ItemGroup>
  <RuntimeHostConfigurationOption Include="System.Globalization.UseNls" Value="true" />
</ItemGroup>

The odd unicode characters you are seeing in the date output are the "right-to-left" mark.

A Console App doesn't seem to be able to display this correctly (even if you add Console.OutputEncoding = System.Text.Encoding.Unicode).

However, if you output this in a Windows message box it is correctly displayed:

Correctly displayed Arabic date

Keese answered 14/10 at 8:22 Comment(0)
O
2

I reproduced your issue in my side, I have .Net 8 MVC App, .Net 8 Console App and .Net Framework 4.8 App. .Net 8 MVC app and .Net 8 Console app have the same test result. The test results are the same even if I set CultureInfo.DefaultThreadCurrentCulture = cultureInfo;.

enter image description here enter image description here

However, when I copy the value from MVC project and paste, I will get 12‏‏/10‏‏/2024 just like what you shared, but not what I can see 2024/10/12. While the value copyed from .Net Framework app is the same as what we can see, it's 12/10/2024. Then I searched online which said this is due to Unicode bidirectional marks such as Right-to-Left Marks (RLM) (U+200F) are automatically added to the formatted output which suggest adding string cleanResult = Regex.Replace(result, @"[\u200F\u200E]", ""); to remove the marks. I test in my side which worked. Here's the Microsoft Document for introducing the differences about globalization APIs. So that I agree with what Matthew Watson shared which using <RuntimeHostConfigurationOption Include="System.Globalization.UseNls" Value="true" />, it will ask applications can enable NLS mode instead of the default ICU in .Net 8. The document also shared another way which set configurations below in runtimeconfig.json.

{
  "runtimeOptions": {
     "configProperties": {
       "System.Globalization.UseNls": true
      }
  }
}

Before .NET 5, the .NET globalization APIs used different underlying libraries on different platforms. On Unix, the APIs used International Components for Unicode (ICU), and on Windows, they used National Language Support (NLS). This resulted in some behavioral differences in a handful of globalization APIs when running applications on different platforms.

enter image description here

Ouachita answered 14/10 at 8:38 Comment(1)
The issue is due to before .NET 5, the .NET globalization APIs used National Language Support (NLS) but in .Net 5 and ubsequent versions it uses International Components for Unicode (ICU). If we want to make the whole .net 8 app to have the same behavior as .net framework 4.8, we can revert back to using NLS. If we only want to change the behavior for part of the app such as in a function, then we can remove Unicode bidirectional marks with Regex.Replace(result, @"[\u200F\u200E]", "");Ouachita

© 2022 - 2024 — McMap. All rights reserved.