Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does "DateTime.Now.ToString("hh tt", new CultureInfo("de"))" return different results in different versions of .Net?

I'm fairly confused. Having read in this answer that we should rely on the built-in localization, I was surprised by the following observation:

When I run

using System;
using System.Globalization;
                    
public class Program
{
    public static void Main()
    {
        Console.WriteLine(DateTime.Now.ToString("hh tt", new CultureInfo("de")));
    }
}

I'm getting very different results depending on the framework and/or compiler. Example is based on 10:00 UTC (10 AM).

  • Running it on try-dotnet I get: 10 vorm.
  • Running it on dotnetfiddle with "compiler" set to .NET 5 I get the same: 10 vorm.

Now the fun part:

  • Running it on dotnetfiddle with "compiler" set to .NET 4.7.2 I get: 10
  • Running it on dotnetfiddle with "compiler" set to Roslyn I get: 10

And it gets weirder: I've tried it locally with a console app and expanded the example to

Console.WriteLine(DateTime.Now.ToString("hh tt", new CultureInfo("de")));
Console.WriteLine(DateTime.Now.ToString("hh tt", new CultureInfo("de-DE")));
Console.WriteLine(DateTime.Now.ToString("hh tt", new CultureInfo("fr")));

These are the results - with try-dotnet added for comparison.

Culture .NET 5 .NET Core 3.1 .NET Core 2.0 .NET Framework 4.8 Mono try-dotnet
"de" 10 AM 10 10 10 10 vorm. 10 vorm.
"de-DE" 10 10 10 10 10 vorm. 10 vorm.
"fr" 10 AM 10 10 10 10 AM 10 AM

In the Mono column, the results are from compiling the file with Mono (Mono JIT compiler version 6.4.0), then running it with mono. Running the .exe without Mono yields the same results as the third column.

Where is this coming from, is it a bug in the compiler or the framework? Is it just broken or is this somehow by design?

like image 509
badasta Avatar asked Sep 27 '21 10:09

badasta


1 Answers

This breaking change is a result of the use of the ICU Libraries on Windows instead of the NLS Libraries.

You can verify this in a .net 5.0 application by adding the following to the project to revert from using the ICU libraries back to using the NLS ones:

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

After adding that to my test .Net 5.0 console app with the code

Console.WriteLine(DateTime.Now.ToString("hh tt", new CultureInfo("de")));

The output changes from 11 AM to 11 (at the time of writing).

See here for more details.

like image 150
Matthew Watson Avatar answered Oct 12 '22 22:10

Matthew Watson