From cd1b4cff818a700b6ff82fde024c65b036979894 Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Wed, 28 Jul 2021 13:02:39 -0700 Subject: [PATCH] Fix fr-CA culture time formatting and parsing (#56443) --- .../DateTimeFormatInfo/DateTimeFormatInfoTests.cs | 12 ++++++++++++ .../src/System/Globalization/CultureData.cs | 21 +++++++++++++++------ .../src/System/Globalization/CultureInfo.cs | 2 +- .../src/System/Globalization/DateTimeFormatInfo.cs | 10 ++++++++++ 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs index 3139852..d429460 100644 --- a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs +++ b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs @@ -210,5 +210,17 @@ namespace System.Globalization.Tests Assert.Equal(i + 1, ci.DateTimeFormat.GetEra(eraNames[i])); } } + + [Fact] + public void TestFrenchCanadaTimeFormat() + { + CultureInfo ci = CultureInfo.GetCultureInfo("fr-CA"); + Assert.Equal(":", ci.DateTimeFormat.TimeSeparator); + + DateTime time = new DateTime(2021, 10, 1, 5, 36, 50); + string formattedTime = time.ToString("HH 'h' mm 'min' ss 's'", ci); + DateTime dt = DateTime.Parse(formattedTime, ci); + Assert.Equal(time.TimeOfDay, dt.TimeOfDay); + } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs index 43e0cfe..5766096 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.cs @@ -1936,14 +1936,23 @@ namespace System.Globalization { if (_sTimeSeparator == null && !GlobalizationMode.Invariant) { - string? longTimeFormat = ShouldUseUserOverrideNlsData ? NlsGetTimeFormatString() : IcuGetTimeFormatString(); - if (string.IsNullOrEmpty(longTimeFormat)) + // fr-CA culture uses time format as "HH 'h' mm 'min' ss 's'" which we cannot derive the time separator from such pattern. + // We special case such culture and force ':' as time separator. + if (_sName == "fr-CA") { - longTimeFormat = LongTimes[0]; + _sTimeSeparator = ":"; } + else + { + string? longTimeFormat = ShouldUseUserOverrideNlsData ? NlsGetTimeFormatString() : IcuGetTimeFormatString(); + if (string.IsNullOrEmpty(longTimeFormat)) + { + longTimeFormat = LongTimes[0]; + } - // Compute STIME from time format - _sTimeSeparator = GetTimeSeparator(longTimeFormat); + // Compute STIME from time format + _sTimeSeparator = GetTimeSeparator(longTimeFormat); + } } return _sTimeSeparator!; } @@ -1966,7 +1975,7 @@ namespace System.Globalization // changing the default pattern is likely will happen in the near future which can easily break formatting // and parsing. // We are forcing here the date separator to '/' to ensure the parsing is not going to break when changing - // the default short date pattern. The application still can override this in the code by DateTimeFormatInfo.DateSeparartor. + // the default short date pattern. The application still can override this in the code by DateTimeFormatInfo.DateSeparator. return "/"; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs index e862e03..c0870e1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureInfo.cs @@ -282,7 +282,7 @@ namespace System.Globalization } /// - /// Return a specific culture. A tad irrelevent now since we always + /// Return a specific culture. A tad irrelevant now since we always /// return valid data for neutral locales. /// /// Note that there's interesting behavior that tries to find a diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs index a7b603e..b4c44b8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormatInfo.cs @@ -2054,6 +2054,16 @@ namespace System.Globalization InsertHash(temp, TimeSeparator, TokenType.SEP_Time, 0); } + if (_name == "fr-CA") + { + InsertHash(temp, " h", TokenType.SEP_HourSuff, 0); + InsertHash(temp, " h ", TokenType.SEP_HourSuff, 0); + InsertHash(temp, " min", TokenType.SEP_MinuteSuff, 0); + InsertHash(temp, " min ", TokenType.SEP_MinuteSuff, 0); + InsertHash(temp, " s", TokenType.SEP_SecondSuff, 0); + InsertHash(temp, " s ", TokenType.SEP_SecondSuff, 0); + } + InsertHash(temp, AMDesignator, TokenType.SEP_Am | TokenType.Am, 0); InsertHash(temp, PMDesignator, TokenType.SEP_Pm | TokenType.Pm, 1); -- 2.7.4