-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Description
When using HybridGlobalization
on iOS, the shortdate
format does only contain just either one or two y
's, which result in only a two-digit year when formatting dates.
Reproduction Steps
Set <HybridGlobalization>true</HybridGlobalization>
in iOS csproj file and format some date with "short date" format (e.g. DateTime.Now.ToString("d")
)
Expected behavior
new CultureInfo("de-DE").DateTimeFormat.ShortDatePattern == "dd.MM.yyyy"
new CultureInfo("en-US").DateTimeFormat.ShortDatePattern == "M/d/yyyy"
new CultureInfo("fa-IR").DateTimeFormat.ShortDatePattern == "yyyy/M/d"
Actual behavior
new CultureInfo("de-DE").DateTimeFormat.ShortDatePattern == "dd.MM.yy"
new CultureInfo("en-US").DateTimeFormat.ShortDatePattern == "M/d/yy"
new CultureInfo("fa-IR").DateTimeFormat.ShortDatePattern == "y/M/d"
Regression?
No response
Known Workarounds
No response
Configuration
.NET 8
Other information
A similar problem was reported a while back for Linux here and fixed here. To code is still in the repo:
runtime/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs
Lines 166 to 251 in 3eb8c7f
// FixDefaultShortDatePattern will convert the default short date pattern from using 'yy' to using 'yyyy' | |
// And will ensure the original pattern still exist in the list. | |
// doing that will have the short date pattern format the year as 4-digit number and not just 2-digit number. | |
// Example: June 5, 2018 will be formatted to something like 6/5/2018 instead of 6/5/18 fro en-US culture. | |
private static void FixDefaultShortDatePattern(List<string> shortDatePatterns) | |
{ | |
if (shortDatePatterns.Count == 0) | |
return; | |
string s = shortDatePatterns[0]; | |
// We are not expecting any pattern have length more than 100. | |
// We have to do this check to prevent stack overflow as we allocate the buffer on the stack. | |
if (s.Length > 100) | |
return; | |
Span<char> modifiedPattern = stackalloc char[s.Length + 2]; | |
int index = 0; | |
while (index < s.Length) | |
{ | |
if (s[index] == '\'') | |
{ | |
do | |
{ | |
modifiedPattern[index] = s[index]; | |
index++; | |
} while (index < s.Length && s[index] != '\''); | |
if (index >= s.Length) | |
return; | |
} | |
else if (s[index] == 'y') | |
{ | |
modifiedPattern[index] = 'y'; | |
break; | |
} | |
modifiedPattern[index] = s[index]; | |
index++; | |
} | |
if (index >= s.Length - 1 || s[index + 1] != 'y') | |
{ | |
// not a 'yy' pattern | |
return; | |
} | |
if (index + 2 < s.Length && s[index + 2] == 'y') | |
{ | |
// we have 'yyy' then nothing to do | |
return; | |
} | |
// we are sure now we have 'yy' pattern | |
Debug.Assert(index + 3 < modifiedPattern.Length); | |
modifiedPattern[index + 1] = 'y'; // second y | |
modifiedPattern[index + 2] = 'y'; // third y | |
modifiedPattern[index + 3] = 'y'; // fourth y | |
index += 2; | |
// Now, copy the rest of the pattern to the destination buffer | |
while (index < s.Length) | |
{ | |
modifiedPattern[index + 2] = s[index]; | |
index++; | |
} | |
shortDatePatterns[0] = modifiedPattern.ToString(); | |
for (int i = 1; i < shortDatePatterns.Count; i++) | |
{ | |
if (shortDatePatterns[i] == shortDatePatterns[0]) | |
{ | |
// Found match in the list to the new constructed pattern, then replace it with the original modified pattern | |
shortDatePatterns[i] = s; | |
return; | |
} | |
} | |
// if we come here means the newly constructed pattern not found on the list, then add the original pattern | |
shortDatePatterns.Add(s); | |
} |