未验证 提交 b54d6ef1 编写于 作者: T Tom Deseyn 提交者: GitHub

ConvertIcuTimeFormatString: convert narrow no-break spaces to spaces too. (#83589)

上级 e9357808
......@@ -232,13 +232,14 @@ private static string ConvertIcuTimeFormatString(ReadOnlySpan<char> icuFormatStr
for (int i = 0; i < icuFormatString.Length; i++)
{
switch (icuFormatString[i])
char current = icuFormatString[i];
switch (current)
{
case '\'':
result[resultPos++] = icuFormatString[i++];
while (i < icuFormatString.Length)
{
char current = icuFormatString[i];
current = icuFormatString[i];
result[resultPos++] = current;
if (current == '\'')
{
......@@ -254,13 +255,10 @@ private static string ConvertIcuTimeFormatString(ReadOnlySpan<char> icuFormatStr
case 'h':
case 'm':
case 's':
result[resultPos++] = icuFormatString[i];
break;
case ' ':
case '\u00A0':
// Convert nonbreaking spaces into regular spaces
result[resultPos++] = ' ';
case '\u00A0': // no-break space
case '\u202F': // narrow no-break space
result[resultPos++] = current;
break;
case 'a': // AM/PM
......
......@@ -5571,7 +5571,7 @@ internal bool MatchSpecifiedWords(string target, bool checkWordBoundary, scoped
// Check word by word
int targetPosition = 0; // Where we are in the target string
int thisPosition = Index; // Where we are in this string
int wsIndex = target.AsSpan(targetPosition).IndexOfAny(' ', '\u00A0');
int wsIndex = target.AsSpan(targetPosition).IndexOfAny("\u0020\u00A0\u202F");
if (wsIndex < 0)
{
return false;
......@@ -5615,7 +5615,7 @@ internal bool MatchSpecifiedWords(string target, bool checkWordBoundary, scoped
matchLength++;
}
wsIndex = target.AsSpan(targetPosition).IndexOfAny(' ', '\u00A0');
wsIndex = target.AsSpan(targetPosition).IndexOfAny("\u0020\u00A0\u202F");
if (wsIndex < 0)
{
break;
......@@ -5678,7 +5678,8 @@ internal bool Match(char ch)
{
return false;
}
if (Value[Index] == ch)
if ((Value[Index] == ch) ||
(ch == ' ' && IsSpaceReplacingChar(Value[Index])))
{
m_current = ch;
return true;
......@@ -5687,6 +5688,8 @@ internal bool Match(char ch)
return false;
}
private static bool IsSpaceReplacingChar(char c) => c == '\u00a0' || c == '\u202f';
//
// Actions: From the current position, try matching the longest word in the specified string array.
// E.g. words[] = {"AB", "ABC", "ABCD"}, if the current position points to a substring like "ABC DEF",
......
......@@ -2008,6 +2008,57 @@ public static void Parse_ValidInput_Succeeds(string input, CultureInfo culture,
Assert.Equal(expected, DateTime.Parse(input, culture));
}
public static IEnumerable<object[]> FormatAndParse_DifferentUnicodeSpaces_Succeeds_MemberData()
{
char[] spaceTypes = new[] { ' ', // space
'\u00A0', // no-break space
'\u202F', // narrow no-break space
};
return spaceTypes.SelectMany(formatSpaceChar => spaceTypes.Select(parseSpaceChar => new object[] { formatSpaceChar, parseSpaceChar }));
}
[Theory]
[MemberData(nameof(FormatAndParse_DifferentUnicodeSpaces_Succeeds_MemberData))]
public void FormatAndParse_DifferentUnicodeSpaces_Succeeds(char formatSpaceChar, char parseSpaceChar)
{
var dateTime = new DateTime(2020, 5, 7, 9, 37, 40, DateTimeKind.Local);
DateTimeFormatInfo formatDtfi = CreateDateTimeFormatInfo(formatSpaceChar);
string formatted = dateTime.ToString(formatDtfi);
Assert.Contains(formatSpaceChar, formatted);
DateTimeFormatInfo parseDtfi = CreateDateTimeFormatInfo(parseSpaceChar);
Assert.Equal(dateTime, DateTime.Parse(formatted, parseDtfi));
static DateTimeFormatInfo CreateDateTimeFormatInfo(char spaceChar)
{
return new DateTimeFormatInfo()
{
Calendar = DateTimeFormatInfo.InvariantInfo.Calendar,
CalendarWeekRule = DateTimeFormatInfo.InvariantInfo.CalendarWeekRule,
FirstDayOfWeek = DayOfWeek.Monday,
AMDesignator = "AM",
DateSeparator = "/",
FullDateTimePattern = $"dddd,{spaceChar}MMMM{spaceChar}d,{spaceChar}yyyy{spaceChar}h:mm:ss{spaceChar}tt",
LongDatePattern = $"dddd,{spaceChar}MMMM{spaceChar}d,{spaceChar}yyyy",
LongTimePattern = $"h:mm:ss{spaceChar}tt",
MonthDayPattern = "MMMM d",
PMDesignator = "PM",
ShortDatePattern = "M/d/yyyy",
ShortTimePattern = $"h:mm{spaceChar}tt",
TimeSeparator = ":",
YearMonthPattern = $"MMMM{spaceChar}yyyy",
AbbreviatedDayNames = new[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" },
ShortestDayNames = new[] { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" },
DayNames = new[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" },
AbbreviatedMonthNames = new[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" },
MonthNames = new[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" },
AbbreviatedMonthGenitiveNames = new[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" },
MonthGenitiveNames = new[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" }
};
}
}
public static IEnumerable<object[]> ParseExact_ValidInput_Succeeds_MemberData()
{
foreach (DateTimeStyles style in new[] { DateTimeStyles.None, DateTimeStyles.AllowWhiteSpaces })
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册