Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 9e84b5d

Browse files
committed
Force short date pattern to use yyyy on Linux (dotnet/coreclr#18316)
* 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 <[email protected]>
1 parent aaf464e commit 9e84b5d

File tree

1 file changed

+93
-2
lines changed

1 file changed

+93
-2
lines changed

src/Common/src/CoreLib/System/Globalization/CalendarData.Unix.cs

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,16 +134,107 @@ private static bool EnumDatePatterns(string localeName, CalendarId calendarId, C
134134
{
135135
List<string> datePatternsList = callbackContext.Results;
136136

137-
datePatterns = new string[datePatternsList.Count];
138137
for (int i = 0; i < datePatternsList.Count; i++)
139138
{
140-
datePatterns[i] = NormalizeDatePattern(datePatternsList[i]);
139+
datePatternsList[i] = NormalizeDatePattern(datePatternsList[i]);
141140
}
141+
142+
if (dataType == CalendarDataType.ShortDates)
143+
FixDefaultShortDatePattern(datePatternsList);
144+
145+
datePatterns = datePatternsList.ToArray();
142146
}
143147

144148
return result;
145149
}
146150

151+
// FixDefaultShortDatePattern will convert the default short date pattern from using 'yy' to using 'yyyy'
152+
// And will ensure the original pattern still exist in the list.
153+
// doing that will have the short date pattern format the year as 4-digit number and not just 2-digit number.
154+
// Example: June 5, 2018 will be formatted to something like 6/5/2018 instead of 6/5/18 fro en-US culture.
155+
private static void FixDefaultShortDatePattern(List<string> shortDatePatterns)
156+
{
157+
if (shortDatePatterns.Count == 0)
158+
return;
159+
160+
string s = shortDatePatterns[0];
161+
162+
// We are not expecting any pattern have length more than 100.
163+
// We have to do this check to prevent stack overflow as we allocate the buffer on the stack.
164+
if (s.Length > 100)
165+
return;
166+
167+
Span<char> modifiedPattern = stackalloc char[s.Length + 2];
168+
int index = 0;
169+
170+
while (index < s.Length)
171+
{
172+
if (s[index] == '\'')
173+
{
174+
do
175+
{
176+
modifiedPattern[index] = s[index];
177+
index++;
178+
} while (index < s.Length && s[index] != '\'');
179+
180+
if (index >= s.Length)
181+
return;
182+
}
183+
else if (s[index] == 'y')
184+
{
185+
modifiedPattern[index] = 'y';
186+
break;
187+
}
188+
189+
modifiedPattern[index] = s[index];
190+
index++;
191+
}
192+
193+
if (index >= s.Length - 1 || s[index + 1] != 'y')
194+
{
195+
// not a 'yy' pattern
196+
return;
197+
}
198+
199+
if (index + 2 < s.Length && s[index + 2] == 'y')
200+
{
201+
// we have 'yyy' then nothing to do
202+
return;
203+
}
204+
205+
// we are sure now we have 'yy' pattern
206+
207+
Debug.Assert(index + 3 < modifiedPattern.Length);
208+
209+
modifiedPattern[index + 1] = 'y'; // second y
210+
modifiedPattern[index + 2] = 'y'; // third y
211+
modifiedPattern[index + 3] = 'y'; // fourth y
212+
213+
index += 2;
214+
215+
// Now, copy the rest of the pattern to the destination buffer
216+
while (index < s.Length)
217+
{
218+
modifiedPattern[index + 2] = s[index];
219+
index++;
220+
}
221+
222+
shortDatePatterns[0] = modifiedPattern.ToString();
223+
224+
for (int i = 1; i < shortDatePatterns.Count; i++)
225+
{
226+
if (shortDatePatterns[i] == shortDatePatterns[0])
227+
{
228+
// Found match in the list to the new constructed pattern, then replace it with the original modified pattern
229+
shortDatePatterns[i] = s;
230+
return;
231+
}
232+
}
233+
234+
// if we come here means the newly constructed pattern not found on the list, then add the original pattern
235+
shortDatePatterns.Add(s);
236+
}
237+
147238
/// <summary>
148239
/// The ICU date format characters are not exactly the same as the .NET date format characters.
149240
/// NormalizeDatePattern will take in an ICU date pattern and return the equivalent .NET date pattern.

0 commit comments

Comments
 (0)