diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs index 35b7b7973ffcc7..080a24d625b106 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeParse.cs @@ -3744,24 +3744,36 @@ private static bool MatchTimeMark(ref __DTString str, DateTimeFormatInfo dtfi, s if (str.GetNext()) { - string searchStr = dtfi.AMDesignator; - if (searchStr.Length > 0) + string amDesignator = dtfi.AMDesignator; + string pmDesignator; + + if (amDesignator.Length > 0) { - if (str.MatchSpecifiedWord(searchStr)) + if (str.MatchSpecifiedWord(amDesignator)) { + pmDesignator = dtfi.PMDesignator; + if (pmDesignator.StartsWith(amDesignator, StringComparison.Ordinal) && str.MatchSpecifiedWord(pmDesignator)) + { + // AM designator is a prefix of PM designator and we have matched PM designator. Use longer match. + str.Index += (pmDesignator.Length - 1); + result = TM.PM; + return true; + } + // Found an AM timemark with length > 0. - str.Index += (searchStr.Length - 1); + str.Index += (amDesignator.Length - 1); result = TM.AM; return true; } } - searchStr = dtfi.PMDesignator; - if (searchStr.Length > 0) + + pmDesignator = dtfi.PMDesignator; + if (pmDesignator.Length > 0) { - if (str.MatchSpecifiedWord(searchStr)) + if (str.MatchSpecifiedWord(pmDesignator)) { // Found a PM timemark with length > 0. - str.Index += (searchStr.Length - 1); + str.Index += (pmDesignator.Length - 1); result = TM.PM; return true; } diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DateTimeTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DateTimeTests.cs index 716b4df993a6d3..1e310009f52fdb 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DateTimeTests.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DateTimeTests.cs @@ -3085,5 +3085,22 @@ public void TestDateTimeCalculationPrecision(double value, DateTime initialValue break; } } + + [Fact] + public void TestParsingWithAmPrefixPm() + { + var culture = new CultureInfo("en-US"); + DateTime dt = new DateTime(2023, 4, 17, 14, 30, 0); + + // AM designator is a prefix of PM designator + culture.DateTimeFormat.AMDesignator = "aM"; + culture.DateTimeFormat.PMDesignator = "aMP"; + + string formatted = dt.ToString("hh:mm tt", culture); + Assert.Equal("02:30 aMP", formatted); + + DateTime parsedDateTime = DateTime.ParseExact(formatted, "hh:mm tt", culture); + Assert.Equal(dt.TimeOfDay, parsedDateTime.TimeOfDay); + } } }