Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Commit

Permalink
Force short date pattern to use yyyy on Linux (dotnet/coreclr#18316)
Browse files Browse the repository at this point in the history
* Force short date pattern to use yyyy on Linux

The default pattern we get is using yy which causes the years  to be displayed  as 2 digits. This is not acceptable for many users. The fix here is to force 4-digit year as a default and still keep the original pattern which has 2-digits year in the optional list

* Address the review feedback

Signed-off-by: dotnet-bot-corefx-mirror <dotnet-bot@microsoft.com>
  • Loading branch information
tarekgh authored and dotnet-bot committed Jun 7, 2018
1 parent b996738 commit e64ded5
Showing 1 changed file with 93 additions and 2 deletions.
95 changes: 93 additions & 2 deletions src/Common/src/CoreLib/System/Globalization/CalendarData.Unix.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,107 @@ private static bool EnumDatePatterns(string localeName, CalendarId calendarId, C
{
List<string> datePatternsList = callbackContext.Results;

datePatterns = new string[datePatternsList.Count];
for (int i = 0; i < datePatternsList.Count; i++)
{
datePatterns[i] = NormalizeDatePattern(datePatternsList[i]);
datePatternsList[i] = NormalizeDatePattern(datePatternsList[i]);
}

if (dataType == CalendarDataType.ShortDates)
FixDefaultShortDatePattern(datePatternsList);

datePatterns = datePatternsList.ToArray();
}

return result;
}

// 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);
}

/// <summary>
/// The ICU date format characters are not exactly the same as the .NET date format characters.
/// NormalizeDatePattern will take in an ICU date pattern and return the equivalent .NET date pattern.
Expand Down

0 comments on commit e64ded5

Please sign in to comment.