Fixed Bugs with DateTime Parsing (dotnet/corefx#24899)
authorShin Mao <shmao@microsoft.com>
Sat, 28 Oct 2017 00:10:08 +0000 (17:10 -0700)
committerGitHub <noreply@github.com>
Sat, 28 Oct 2017 00:10:08 +0000 (17:10 -0700)
* Fixed Bugs with Parsing DateTime String.

Fix dotnet/corefx#24894

* Improved error message.

* Fixed feed name.

* Use Rfc3339DateTimeFormat.

* Refactor the code.

* removed unused code

* Fixed Rfc3339DateTimeParser.

Commit migrated from https://github.com/dotnet/corefx/commit/a6c58c0efaa43967b63cc5ef676ba7cc81e00218

src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/DateTimeHelper.cs
src/libraries/System.ServiceModel.Syndication/tests/BasicScenarioTests.cs

index 8b9678d..1a10b9d 100644 (file)
@@ -9,6 +9,8 @@ namespace System.ServiceModel.Syndication
 {
     internal static class DateTimeHelper
     {
+        private const string Rfc3339DateTimeFormat = "yyyy-MM-ddTHH:mm:ssK";
+
         public static Func<string, string, string, DateTimeOffset> CreateRss20DateTimeParser()
         {
             return (dateTimeString, localName, ns) =>
@@ -42,21 +44,36 @@ namespace System.ServiceModel.Syndication
         {
             return (dateTimeString, localName, ns) =>
             {
-                DateTimeOffset dto;
-                if (Rfc3339DateTimeParser(dateTimeString, out dto))
+                if (Rfc3339DateTimeParser(dateTimeString, out DateTimeOffset dto))
                 {
                     return dto;
                 }
 
-                // Unable to parse - using a default date;
-                return new DateTimeOffset();
+                throw new FormatException(SR.ErrorParsingDateTime);
             };
         }
 
         private static bool Rfc3339DateTimeParser(string dateTimeString, out DateTimeOffset dto)
         {
-            // RFC3339 uses the W3C Profile of ISO 8601 so using the date time format string "O" will achieve this.
-            return DateTimeOffset.TryParseExact(dateTimeString, "O", null as IFormatProvider, DateTimeStyles.AllowWhiteSpaces, out dto);
+            dateTimeString = dateTimeString.Trim();
+            if (dateTimeString.Length < 20)
+            {
+                return false;
+            }
+
+            if (dateTimeString[19] == '.')
+            {
+                // remove any fractional seconds, we choose to ignore them
+                int i = 20;
+                while (dateTimeString.Length > i && char.IsDigit(dateTimeString[i]))
+                {
+                    ++i;
+                }
+
+                dateTimeString = dateTimeString.Substring(0, 19) + dateTimeString.Substring(i);
+            }
+
+            return DateTimeOffset.TryParseExact(dateTimeString, Rfc3339DateTimeFormat,CultureInfo.InvariantCulture.DateTimeFormat,DateTimeStyles.None, out dto);
         }
 
         private static bool Rfc822DateTimeParser(string dateTimeString, out DateTimeOffset dto)
index fd593d5..0fa3694 100644 (file)
@@ -300,7 +300,6 @@ namespace System.ServiceModel.Syndication.Tests
         }
 
         [Fact]
-        [ActiveIssue(24894)]
         public static void AtomEntryPositiveTest()
         {
             string filePath = @"brief-entry-noerror.xml";
@@ -335,7 +334,6 @@ namespace System.ServiceModel.Syndication.Tests
         }
 
         [Fact]
-        [ActiveIssue(24894)]
         public static void AtomEntryPositiveTest_write()
         {
             string filePath = @"AtomEntryTest.xml";
@@ -343,7 +341,7 @@ namespace System.ServiceModel.Syndication.Tests
 
             SyndicationItem item = new SyndicationItem("SyndicationFeed released for .net Core", "A lot of text describing the release of .net core feature", new Uri("http://contoso.com/news/path"));
             item.Id = "uuid:43481a10-d881-40d1-adf2-99b438c57e21;id=1";
-            item.LastUpdatedTime = new DateTimeOffset(Convert.ToDateTime("2017-10-11T11:25:55Z"));
+            item.LastUpdatedTime = new DateTimeOffset(Convert.ToDateTime("2017-10-11T11:25:55Z")).UtcDateTime;
 
             try
             {
@@ -367,7 +365,6 @@ namespace System.ServiceModel.Syndication.Tests
         }
 
         [Fact]
-        [ActiveIssue(24894)]
         public static void AtomFeedPositiveTest()
         {
             string dataFile = @"atom_feeds.dat";
@@ -488,13 +485,14 @@ namespace System.ServiceModel.Syndication.Tests
                 {
                     if (!file.StartsWith("#"))
                     {
+                        file = file.Trim();
                         if (File.Exists(file))
                         {
                             fileList.Add(Path.GetFullPath(file));
                         }
                         else
                         {
-                            throw new FileNotFoundException("File not found!",file);
+                            throw new FileNotFoundException($"File `{file}` was not found!");
                         }
                     }
                 }