You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2023/05/13 18:21:01 UTC

[lucenenet] 01/02: BUG: Lucene.Net.Documents.DateTools: Convert DateTimeKind.Unspecified dates to UTC, otherwise they can produce ArgumentOutOfRangeException. Fixes #772.

This is an automated email from the ASF dual-hosted git repository.

nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git

commit a84a8375e0849882380dc49878c5649a42fdc3bc
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Sat May 13 22:52:02 2023 +0700

    BUG: Lucene.Net.Documents.DateTools: Convert DateTimeKind.Unspecified dates to UTC, otherwise they can produce ArgumentOutOfRangeException. Fixes #772.
---
 src/Lucene.Net.Tests/Document/TestDateTools.cs |  9 +++++++
 src/Lucene.Net/Document/DateTools.cs           | 34 ++++++--------------------
 2 files changed, 16 insertions(+), 27 deletions(-)

diff --git a/src/Lucene.Net.Tests/Document/TestDateTools.cs b/src/Lucene.Net.Tests/Document/TestDateTools.cs
index 6ff731a52..408c832b1 100644
--- a/src/Lucene.Net.Tests/Document/TestDateTools.cs
+++ b/src/Lucene.Net.Tests/Document/TestDateTools.cs
@@ -584,5 +584,14 @@ namespace Lucene.Net.Documents
             Assert.AreEqual("2004-02-03 22:08:56:333", IsoFormat(DateTools.StringToDate(convertedDate)));
             Assert.AreEqual(unixDate, DateTools.StringToTime(convertedDate));
         }
+
+        [Test]
+        [LuceneNetSpecific] // GH-772
+        public void DateToString_MinDate_ShouldNotThrowArgumentOutOfRangeException()
+        {
+            var date = new DateTime();
+            var value = DateTools.DateToString(date, DateResolution.DAY);
+            Assert.AreEqual("00010101", value);
+        }
     }
 }
\ No newline at end of file
diff --git a/src/Lucene.Net/Document/DateTools.cs b/src/Lucene.Net/Document/DateTools.cs
index 0be286f10..916d4c041 100644
--- a/src/Lucene.Net/Document/DateTools.cs
+++ b/src/Lucene.Net/Document/DateTools.cs
@@ -62,7 +62,7 @@ namespace Lucene.Net.Documents
         };
 
         /// <summary>
-        /// Converts a <see cref="DateTime"/> to a string suitable for indexing using the specified 
+        /// Converts a <see cref="DateTime"/> to a string suitable for indexing using the specified
         /// <paramref name="resolution"/>.
         /// <para/>
         /// The <paramref name="date"/> is converted according to its <see cref="DateTime.Kind"/> property
@@ -77,7 +77,7 @@ namespace Lucene.Net.Documents
         /// depending on <paramref name="resolution"/>; using UTC as the timezone.</returns>
         public static string DateToString(DateTime date, DateResolution resolution)
         {
-            return DateToString(date, resolution, timeZone: null);
+            return DateToStringInternal(date, timeZone: null, resolution);
         }
 
         /// <summary>
@@ -98,39 +98,19 @@ namespace Lucene.Net.Documents
             if (timeZone is null)
                 throw new ArgumentNullException(nameof(timeZone));
 
-            return DateToString(date, resolution, timeZone);
+            return DateToStringInternal(date, timeZone, resolution);
         }
 
-        private static string DateToString(DateTime date, DateResolution resolution, TimeZoneInfo timeZone)
+        private static string DateToStringInternal(DateTime date, TimeZoneInfo timeZone, DateResolution resolution)
         {
             string format = ToDateFormat(resolution);
             if (format is null)
                 throw new ArgumentException($"Unknown resolution {resolution}.");
 
-            DateTimeOffset timeZoneAdjusted;
-            switch (date.Kind)
+            DateTimeOffset timeZoneAdjusted = new DateTimeOffset(date.ToUniversalTime(), TimeSpan.Zero);
+            if (timeZone is not null && !TimeZoneInfo.Utc.Equals(timeZone))
             {
-                case DateTimeKind.Utc:
-                    if (timeZone is null || TimeZoneInfo.Utc.Equals(timeZone))
-                    {
-                        timeZoneAdjusted = new DateTimeOffset(date, TimeSpan.Zero);
-                    }
-                    else
-                    {
-                        timeZoneAdjusted = new DateTimeOffset(date, TimeSpan.Zero);
-                        timeZoneAdjusted = TimeZoneInfo.ConvertTime(timeZoneAdjusted, timeZone);
-                    }
-                    break;
-
-                case DateTimeKind.Local:
-                    timeZone = timeZone ?? TimeZoneInfo.Local;
-                    timeZoneAdjusted = new DateTimeOffset(date, timeZone.GetUtcOffset(date));
-                    break;
-
-                default: //case DateTimeKind.Unspecified:
-                    timeZone = timeZone ?? TimeZoneInfo.Local; // Assume local time zone if not specified
-                    timeZoneAdjusted = new DateTimeOffset(date, timeZone.GetUtcOffset(new DateTime(date.Ticks, DateTimeKind.Local)));
-                    break;
+                timeZoneAdjusted = TimeZoneInfo.ConvertTime(timeZoneAdjusted, timeZone);
             }
 
             DateTime d = Round(timeZoneAdjusted.UtcDateTime, resolution);