I have temporarily set my browser language and locale to English - United Kingdom even though I am in the United States. I have removed "en-US" and now have "en-GB" as my only language preference.
In my Blazor WebAssembly site, on a component, I have a property that returns a string: myDate.ToString("d") + System.Globalization.CultureInfo.CurrentCulture.DisplayName;
that renders on my page as 6/27/2020en (GB)
, where myDate is a DateTime set to June 27, 2020 at 00:00:00.000. My Blazor site has app.UseRequestLocalization(...)
middleware set up.
Isn't is supposed to show the date in UK format, namely 27/06/2020
? I can only guess that ShortDatePattern isn't getting properly set from CultureInfo.CurrentCulture. What could it be?
UPDATE: All WebAssembly component outputs show me that DateTimeFormatInfo.CurrentInfo.ShortDatePattern == "M/d/yyyy"
even though CultureInfo.CurrentCulture.Name == "en-GB"
. Why might that be? What sets ShortDatePattern from the culture and can I "re-initialize" it?
An explicit call to myDate.ToString("d", System.Globalization.CultureInfo.GetCultureInfo("en-GB"));
still strangely outputs the M/d/yyyy format (U.S. format). Why might that be?
UPDATE 2: I created a minimal example: File-New Project, Blazor Web Assembly, .NET 5 ASP.NET Core hosted. I replaced App.Razor with the following:
<div> current culture @(System.Globalization.CultureInfo.CurrentCulture.Name) </div>
<div> current date format @(System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern) </div>
<div> today @DateTime.Now.ToString("d") </div>
That results in (unexpectedly):
Firefox browser settings (Edge and Chrome are similar and show the same issue):
That results in sending Accept-Language: en-GB,en-US;q=0.7,en;q=0.3
--which seems to be the correct way to "prefer en-GB" and results in CultureInfo.CurrentCulture having the correct value.
I've tried it with Microsoft.AspNetCore.Components.WebAssembly.* nuget packages version 5.0.9, 5.0.11 - both show the same incorrect result.
UPDATE 3: The same minimal project in 6.0.0-rc.1 works and gives the right date format! Is this really a Blazor 5 bug that they never fixed?
For .NET 6+, this seems to be fixed.
For .NET 5, I could not find the root cause, so I needed to code this workaround, which needs to be called explicitly when needed. Obviously this is undesirable if we can find a better solution to allow the use of DateTime.ToString as intended.
/// <summary>
/// Returns a short date-only string from a date/time value, based on the user's current culture.
/// </summary>
public static string ToLocalShortDate(this DateTime value)
{
// this is needed because I can't get localization to work -- see https://stackoverflow.com/q/69542125/7453
// (if we can fix, better to use DateTime.ToString("d"))
string format;
// countries taken from https://en.wikipedia.org/wiki/Date_format_by_country
if (CurrentCulture.Name.EndsWithAny("US", "CA", "ZA", "KE", "GH", "en"))
format = "MM/dd/yyyy";
else if (CurrentCulture.Name.EndsWithAny("CN", "JP", "KR", "KP", "TW", "HU", "MN", "LT", "BT"))
format = "yyyy-MM-dd";
else format = "dd/MM/yyyy";
return value.ToString(format);
}
/// <summary>
/// Returns true if and only if a string ends with any of some strings.
/// The value will not match a null reference.
/// </summary>
public static bool EndsWithAny(this string value, params string[] allowedValues) =>
allowedValues != null && value != null && allowedValues.Any(s => CurrentCulture.Name.EndsWith(s));