Fix Abbreviated Genitive Month Names Parsing (#26384)
authorTarek Mahmoud Sayed <tarekms@microsoft.com>
Tue, 27 Aug 2019 19:51:12 +0000 (12:51 -0700)
committerGitHub <noreply@github.com>
Tue, 27 Aug 2019 19:51:12 +0000 (12:51 -0700)
In 3.0 we have fixed the formatting to use the abbreviated genitive month names when having "d" format specifier followed by "MMM". This fix is good as original formatting specs required but we needed to support the parsing when we have such genitive names.

src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfo.cs
src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfoScanner.cs
src/System.Private.CoreLib/shared/System/Globalization/DateTimeParse.cs

index db64442..a31d3bd 100644 (file)
@@ -1349,7 +1349,7 @@ namespace System.Globalization
 
         /// <summary>
         /// Retrieve the array which contains the month names in genitive form.
-        /// If this culture does not use the gentive form, the normal month name is returned.
+        /// If this culture does not use the genitive form, the normal month name is returned.
         /// </summary>
         private string[] InternalGetGenitiveMonthNames(bool abbreviated)
         {
@@ -2320,14 +2320,15 @@ namespace System.Globalization
                     InsertHash(temp, GetAbbreviatedMonthName(i), TokenType.MonthToken, i);
                 }
 
-
                 if ((FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != 0)
                 {
+                    string [] genitiveMonthNames = InternalGetGenitiveMonthNames(abbreviated: false);
+                    string [] abbreviatedGenitiveMonthNames = InternalGetGenitiveMonthNames(abbreviated: true);
+
                     for (int i = 1; i <= 13; i++)
                     {
-                        string str;
-                        str = InternalGetMonthName(i, MonthNameStyles.Genitive, false);
-                        InsertHash(temp, str, TokenType.MonthToken, i);
+                        InsertHash(temp, genitiveMonthNames[i - 1], TokenType.MonthToken, i);
+                        InsertHash(temp, abbreviatedGenitiveMonthNames[i - 1], TokenType.MonthToken, i);
                     }
                 }
 
index accc5b9..beef72a 100644 (file)
@@ -354,10 +354,10 @@ namespace System.Globalization
 
         ////////////////////////////////////////////////////////////////////////////
         //
-        // Add the text that is a date separator but is treated like ignroable symbol.
+        // Add the text that is a date separator but is treated like ignorable symbol.
         // E.g.
         // hu-HU has:
-        //      shrot date pattern: yyyy. MM. dd.;yyyy-MM-dd;yy-MM-dd
+        //      short date pattern: yyyy. MM. dd.;yyyy-MM-dd;yy-MM-dd
         //      long date pattern: yyyy. MMMM d.
         // Here, "." is the date separator (derived from short date pattern). However,
         // "." also appear at the end of long date pattern.  In this case, we just
@@ -614,7 +614,7 @@ namespace System.Globalization
         //-----------------------------------------------------------------------------
         // EqualStringArrays
         //      compares two string arrays and return true if all elements of the first
-        //      array equals to all elmentsof the second array.
+        //      array equals to all elements of the second array.
         //      otherwise it returns false.
         //-----------------------------------------------------------------------------
 
index 511a440..13e532f 100644 (file)
@@ -3305,7 +3305,7 @@ new DS[] { DS.ERROR, DS.TX_NNN,  DS.TX_NNN,  DS.TX_NNN,  DS.ERROR,   DS.ERROR,
 
         /*=================================MatchAbbreviatedMonthName==================================
         **Action: Parse the abbreviated month name from string starting at str.Index.
-        **Returns: A value from 1 to 12 for the first month to the twelveth month.
+        **Returns: A value from 1 to 12 for the first month to the twelfth month.
         **Arguments:    str: a __DTString.  The parsing will start from the
         **              next character after str.Index.
         **Exceptions: FormatException if an abbreviated month name can not be found.
@@ -3340,6 +3340,19 @@ new DS[] { DS.ERROR, DS.TX_NNN,  DS.TX_NNN,  DS.TX_NNN,  DS.ERROR,   DS.ERROR,
                     }
                 }
 
+                // Search genitive form.
+                if ((dtfi.FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != 0)
+                {
+                    int tempResult = str.MatchLongestWords(dtfi.AbbreviatedMonthGenitiveNames, ref maxMatchStrLen);
+
+                    // We found a longer match in the genitive month name.  Use this as the result.
+                    // tempResult + 1 should be the month value.
+                    if (tempResult >= 0)
+                    {
+                        result = tempResult + 1;
+                    }
+                }
+
                 // Search leap year form.
                 if ((dtfi.FormatFlags & DateTimeFormatFlags.UseLeapYearMonth) != 0)
                 {
@@ -3363,7 +3376,7 @@ new DS[] { DS.ERROR, DS.TX_NNN,  DS.TX_NNN,  DS.TX_NNN,  DS.ERROR,   DS.ERROR,
 
         /*=================================MatchMonthName==================================
         **Action: Parse the month name from string starting at str.Index.
-        **Returns: A value from 1 to 12 indicating the first month to the twelveth month.
+        **Returns: A value from 1 to 12 indicating the first month to the twelfth month.
         **Arguments:    str: a __DTString.  The parsing will start from the
         **              next character after str.Index.
         **Exceptions: FormatException if a month name can not be found.