[release/6.0] Fix DateOnly and TimeOnly Formatting using interpolated strings (#64460)
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Mon, 7 Feb 2022 19:39:51 +0000 (11:39 -0800)
committerGitHub <noreply@github.com>
Mon, 7 Feb 2022 19:39:51 +0000 (11:39 -0800)
* Fix DateOnly and TimeOnly Formatting using interpolated strings

* Add TryFormat tests

Co-authored-by: Tarek Mahmoud Sayed <tarekms@microsoft.com>
src/libraries/System.Private.CoreLib/src/System/DateOnly.cs
src/libraries/System.Private.CoreLib/src/System/Globalization/DateTimeFormat.cs
src/libraries/System.Private.CoreLib/src/System/ISpanFormattable.cs
src/libraries/System.Private.CoreLib/src/System/TimeOnly.cs
src/libraries/System.Runtime/tests/System/DateOnlyTests.cs
src/libraries/System.Runtime/tests/System/TimeOnlyTests.cs

index 2dcf490..955ecb1 100644 (file)
@@ -817,15 +817,13 @@ namespace System
                         return DateTimeFormat.TryFormat(GetEquivalentDateTime(), destination, out charsWritten, format, provider);
 
                     default:
-                        charsWritten = 0;
-                        return false;
+                        throw new FormatException(SR.Argument_BadFormatSpecifier);
                 }
             }
 
             if (!DateTimeFormat.IsValidCustomDateFormat(format, throwOnError: false))
             {
-                charsWritten = 0;
-                return false;
+                throw new FormatException(SR.Format(SR.Format_DateTimeOnlyContainsNoneDateParts, format.ToString(), nameof(DateOnly)));
             }
 
             return DateTimeFormat.TryFormat(GetEquivalentDateTime(), destination, out charsWritten, format, provider);
index e72e788..f8c1745 100644 (file)
@@ -62,8 +62,8 @@ namespace System
         "M"     "0"         month w/o leading zero                2
         "MM"    "00"        month with leading zero               02
         "MMM"               short month name (abbreviation)       Feb
-        "MMMM"              full month name                       Febuary
-        "MMMM*"             full month name                       Febuary
+        "MMMM"              full month name                       February
+        "MMMM*"             full month name                       February
 
         "y"     "0"         two digit year (year % 100) w/o leading zero           0
         "yy"    "00"        two digit year (year % 100) with leading zero          00
@@ -734,7 +734,7 @@ namespace System
                         break;
                     case '\\':
                         // Escaped character.  Can be used to insert a character into the format string.
-                        // For exmple, "\d" will insert the character 'd' into the string.
+                        // For example, "\d" will insert the character 'd' into the string.
                         //
                         // NOTENOTE : we can remove this format character if we enforce the enforced quote
                         // character rule.
@@ -966,7 +966,7 @@ namespace System
                         // This format is not supported by DateTimeOffset
                         throw new FormatException(SR.Format_InvalidString);
                     }
-                    // Universal time is always in Greogrian calendar.
+                    // Universal time is always in Gregorian calendar.
                     //
                     // Change the Calendar to be Gregorian Calendar.
                     //
index 0998785..15e7717 100644 (file)
@@ -15,6 +15,7 @@ namespace System
         /// <remarks>
         /// An implementation of this interface should produce the same string of characters as an implementation of <see cref="IFormattable.ToString(string?, IFormatProvider?)"/>
         /// on the same type.
+        /// TryFormat should return false only if there is not enough space in the destination buffer. Any other failures should throw an exception.
         /// </remarks>
         bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? provider);
     }
index aee22dc..9fb102f 100644 (file)
@@ -892,15 +892,13 @@ namespace System
                         return DateTimeFormat.TryFormat(ToDateTime(), destination, out charsWritten, format, provider);
 
                     default:
-                        charsWritten = 0;
-                        return false;
+                        throw new FormatException(SR.Argument_BadFormatSpecifier);
                 }
             }
 
             if (!DateTimeFormat.IsValidCustomTimeFormat(format, throwOnError: false))
             {
-                charsWritten = 0;
-                return false;
+                throw new FormatException(SR.Format(SR.Format_DateTimeOnlyContainsNoneDateParts, format.ToString(), nameof(TimeOnly)));
             }
 
             return DateTimeFormat.TryFormat(ToDateTime(), destination, out charsWritten, format, provider);
index 935c75e..624b9b5 100644 (file)
@@ -513,6 +513,16 @@ namespace System.Tests
             Assert.False(dateOnly.TryFormat(buffer.Slice(0, 3), out charsWritten));
             Assert.False(dateOnly.TryFormat(buffer.Slice(0, 3), out charsWritten, "r"));
             Assert.False(dateOnly.TryFormat(buffer.Slice(0, 3), out charsWritten, "O"));
+            Assert.Throws<FormatException>(() => {
+                    Span<char> buff = stackalloc char[100];
+                    dateOnly.TryFormat(buff, out charsWritten, "u");
+                });
+            Assert.Throws<FormatException>(() => {
+                    Span<char> buff = stackalloc char[100];
+                    dateOnly.TryFormat(buff, out charsWritten, "hh-ss");
+                });
+            Assert.Throws<FormatException>(() => $"{dateOnly:u}");
+            Assert.Throws<FormatException>(() => $"{dateOnly:hh-ss}");
         }
     }
 }
index b39e94e..f74a401 100644 (file)
@@ -483,6 +483,17 @@ namespace System.Tests
             Assert.False(timeOnly.TryFormat(buffer.Slice(0, 3), out charsWritten));
             Assert.False(timeOnly.TryFormat(buffer.Slice(0, 3), out charsWritten, "r"));
             Assert.False(timeOnly.TryFormat(buffer.Slice(0, 3), out charsWritten, "O"));
+
+            Assert.Throws<FormatException>(() => {
+                    Span<char> buff = stackalloc char[100];
+                    timeOnly.TryFormat(buff, out charsWritten, "u");
+                });
+            Assert.Throws<FormatException>(() => {
+                    Span<char> buff = stackalloc char[100];
+                    timeOnly.TryFormat(buff, out charsWritten, "dd-yyyy");
+                });
+            Assert.Throws<FormatException>(() => $"{timeOnly:u}");
+            Assert.Throws<FormatException>(() => $"{timeOnly:dd-yyyy}");
         }
     }
 }