From d0f98c1dd1172c0bcfd99e964c205988a45b834c Mon Sep 17 00:00:00 2001 From: David Lowndes Date: Tue, 23 Jan 2024 17:36:27 +0000 Subject: [PATCH 1/2] Proposed fix for issue #93189. Rework MSFormatDateTime to use the isDate parameter to try and reproduce the prior .NET FW version behaviour that used the Win32 GetDateFormat & GetTimeFormat APIs to only output date or time parts. --- .../System/Xml/Xsl/Runtime/XsltFunctions.cs | 36 ++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XsltFunctions.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XsltFunctions.cs index 7d8613a4d7d3cd..dc52f305c0d6d6 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XsltFunctions.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XsltFunctions.cs @@ -355,31 +355,51 @@ public static double MSNumber(IList value) // string ms:format-time(string datetime[, string format[, string language]]) // // Format xsd:dateTime as a date/time string for a given language using a given format string. - // * Datetime contains a lexical representation of xsd:dateTime. If datetime is not valid, the + // * dateTime contains a lexical representation of xsd:dateTime. If datetime is not valid, the // empty string is returned. - // * Format specifies a format string in the same way as for GetDateFormat/GetTimeFormat system + // * format specifies a format string in the same way as for GetDateFormat/GetTimeFormat system // functions. If format is the empty string or not passed, the default date/time format for the // given culture is used. - // * Language specifies a culture used for formatting. If language is the empty string or not + // * lang specifies a culture used for formatting. If language is the empty string or not // passed, the current culture is used. If language is not recognized, a runtime error happens. + // * isDate - true to output just the date; false to output just the time. public static string MSFormatDateTime(string dateTime, string format, string lang, bool isDate) { try { string locale = GetCultureInfo(lang).Name; - XsdDateTime xdt; - if (!XsdDateTime.TryParse(dateTime, XsdDateTimeFlags.AllXsd | XsdDateTimeFlags.XdrDateTime | XsdDateTimeFlags.XdrTimeNoTz, out xdt)) + if (!XsdDateTime.TryParse(dateTime, XsdDateTimeFlags.AllXsd | XsdDateTimeFlags.XdrDateTime | XsdDateTimeFlags.XdrTimeNoTz, out XsdDateTime xdt)) { return string.Empty; } + + var ci = new CultureInfo(locale); + DateTime dt = xdt.ToZulu(); - // If format is the empty string or not specified, use the default format for the given locale - return dt.ToString(format.Length != 0 ? format : null, new CultureInfo(locale)); + if (isDate) + { + DateOnly dateOnly = DateOnly.FromDateTime(dt); + return dateOnly.ToString(format.Length != 0 ? format : null, ci); + } + else + { + TimeOnly timeOnly = TimeOnly.FromDateTime(dt); + if (format.Length != 0) + { + return timeOnly.ToString(format, ci); + } + else + { + // Duplicate what the Win32 GetTimeFormat API returns + // with an empty format - the long time string. + return timeOnly.ToLongTimeString(); + } + } } catch (ArgumentException) - { // Operations with DateTime can throw this exception eventualy + { // Operations with DateTime can throw this exception return string.Empty; } } From db52c80d1c297a8f489a9ad15d0cc97e850b4484 Mon Sep 17 00:00:00 2001 From: David Lowndes Date: Wed, 24 Jan 2024 10:28:25 +0000 Subject: [PATCH 2/2] Incorporate suggestions. --- .../src/System/Xml/Xsl/Runtime/XsltFunctions.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XsltFunctions.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XsltFunctions.cs index dc52f305c0d6d6..08aa61bea7b510 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XsltFunctions.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XsltFunctions.cs @@ -367,26 +367,25 @@ public static string MSFormatDateTime(string dateTime, string format, string lan { try { - string locale = GetCultureInfo(lang).Name; - if (!XsdDateTime.TryParse(dateTime, XsdDateTimeFlags.AllXsd | XsdDateTimeFlags.XdrDateTime | XsdDateTimeFlags.XdrTimeNoTz, out XsdDateTime xdt)) { return string.Empty; } - var ci = new CultureInfo(locale); - DateTime dt = xdt.ToZulu(); + CultureInfo ci = string.IsNullOrEmpty(lang) ? + CultureInfo.CurrentCulture : + GetCultureInfo(lang); if (isDate) { DateOnly dateOnly = DateOnly.FromDateTime(dt); - return dateOnly.ToString(format.Length != 0 ? format : null, ci); + return dateOnly.ToString(!string.IsNullOrEmpty(format) ? format : null, ci); } else { TimeOnly timeOnly = TimeOnly.FromDateTime(dt); - if (format.Length != 0) + if (!string.IsNullOrEmpty(format)) { return timeOnly.ToString(format, ci); } @@ -398,8 +397,8 @@ public static string MSFormatDateTime(string dateTime, string format, string lan } } } - catch (ArgumentException) - { // Operations with DateTime can throw this exception + catch (Exception ex) when (ex is ArgumentException or FormatException) + { return string.Empty; } }