Reputation: 83
We are seeing what appears to be an anomaly/inconsistency in .NET's DateTime ToString() for US culture, "en-US". On some Windows systems, a four-digit year is displayed and on others, a two-digit year is displayed for the same code and the same culture, en-US.
On our Windows 2016 Servers, the code below displays 10/25/1999, which is what we expect.
On some of our Windows 10 Pro workstations, the following code displays 10/25/1999 but on others, it displays 10/25/99. We have not yet isolated the cause/differences between the boxes. Some boxes are upgraded to Fall Creator's update, some have .NET 4.7.1 installed, one box that displayed 10/25/99 had not been updated for months (we turned it on just to run this test).
The code that demonstrates the issue is:
var date = DateTime.Parse("10/25/1999", CultureInfo.InvariantCulture);
// correctly, always displays 1999
Console.WriteLine(date.Year);
// correctly, always displays 10/25/1999
Console.WriteLine(date.ToString("d", CultureInfo.InvariantCulture));
// **INCONSISTENT--displays 10/25/1999 on some boxes and 10/25/99 on others**
Console.WriteLine(date.ToString("d", new CultureInfo("en-US")));
// **INCONSISTENT--displays 10/25/1999 12:00:00 AM on some boxes and 10/25/99 12:00:00 AM on others**
Console.WriteLine(date.ToString(new CultureInfo("en-US")));
// Force formatting--correctly, always displays 10/25/1999
Console.WriteLine(date.ToString("MM/dd/yyyy", new CultureInfo("en-US")));
We have tested against .NET Frameworks ranging from v2 to v4.7.1 and in both x64 and x86 modes. Varying these does not change the number of digits displayed. It seems almost as though the number of digits displayed for the en-US culture is configured based on some OS setting.
I'm probably missing something obvious. Thank you for your help and insights.
p.s. I looked at threads like Strange behaviour of DateTime.Parse but that doesn't seem to be the issue since the issue we are seeing is in ToString. Parsing works fine.
Upvotes: 3
Views: 707
Reputation: 3451
From MSDN:
The user might choose to override some of the values associated with the current culture of Windows through the regional and language options portion of Control Panel. For example, the user might choose to display the date in a different format or to use a currency other than the default for the culture. If the culture identifier associated with name matches the culture identifier of the current Windows culture, this constructor creates a CultureInfo object that uses those overrides, including user settings for the properties of the DateTimeFormatInfo instance returned by the DateTimeFormat property, and the properties of the NumberFormatInfo instance returned by the NumberFormat property. If the user settings are incompatible with the culture associated with the CultureInfo, for example, if the selected calendar is not one of the OptionalCalendars, the results of the methods and the values of the properties are undefined.
So my guess is you would like to use the following constructor:
public CultureInfo(string name, bool useUserOverride)
and set useUserOverride
to false
.
Upvotes: 2