eerhardt commented on a change in pull request #7654:
URL: https://github.com/apache/arrow/pull/7654#discussion_r469456287



##########
File path: csharp/src/Apache.Arrow/Arrays/Date64Array.cs
##########
@@ -15,56 +15,103 @@
 
 using Apache.Arrow.Types;
 using System;
-using System.Collections.Generic;
-using Apache.Arrow.Memory;
 
 namespace Apache.Arrow
 {
+    /// <summary>
+    /// The <see cref="Date64Array"/> class holds an array of dates in the 
<c>Date64</c> format, where each date is
+    /// stored as the number of milliseconds since the dawn of (UNIX) time, 
excluding leap seconds, in multiples of
+    /// 86400000.
+    /// </summary>
     public class Date64Array: PrimitiveArray<long>
     {
+        private const long MillisecondsPerDay = 86400000;
+
         public Date64Array(
             ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
             int length, int nullCount, int offset)
             : this(new ArrayData(Date64Type.Default, length, nullCount, offset,
                 new[] { nullBitmapBuffer, valueBuffer }))
         { }
 
-        public class Builder : PrimitiveArrayBuilder<DateTimeOffset, long, 
Date64Array, Builder>
+        /// <summary>
+        /// The <see cref="Builder"/> class can be used to fluently build <see 
cref="Date64Array"/> objects.
+        /// </summary>
+        public class Builder : DateArrayBuilder<long, Date64Array, Builder>
         {
-            internal class DateBuilder: PrimitiveArrayBuilder<long, 
Date64Array, DateBuilder>
+            private class DateBuilder: PrimitiveArrayBuilder<long, 
Date64Array, DateBuilder>
             {
                 protected override Date64Array Build(
                     ArrowBuffer valueBuffer, ArrowBuffer nullBitmapBuffer,
                     int length, int nullCount, int offset) =>
                     new Date64Array(valueBuffer, nullBitmapBuffer, length, 
nullCount, offset);
-            } 
+            }
 
+            /// <summary>
+            /// Construct a new instance of the <see cref="Builder"/> class.
+            /// </summary>
             public Builder() : base(new DateBuilder()) { }
 
-            protected override long ConvertTo(DateTimeOffset value)
+            protected override long Convert(DateTime dateTime)
+            {
+                var dateTimeOffset = new DateTimeOffset(
+                    DateTime.SpecifyKind(dateTime.Date, 
DateTimeKind.Unspecified),
+                    TimeSpan.Zero);
+                return dateTimeOffset.ToUnixTimeMilliseconds();
+            }
+
+            protected override long Convert(DateTimeOffset dateTimeOffset)
             {
-                return value.ToUnixTimeMilliseconds();
+                // The internal value stored for a DateTimeOffset can be 
thought of as the number of milliseconds,
+                // in multiples of 86400000, that have passed since the UNIX 
epoch.  It is not the same as what would
+                // result from encoding the date from the DateTimeOffset.Date 
property.
+                long millis = dateTimeOffset.ToUnixTimeMilliseconds();
+                long days = millis / MillisecondsPerDay;
+                return (millis < 0 ? days - 1 : days) * MillisecondsPerDay;

Review comment:
       > From what I can tell, the Date64 builder (neither in this PR nor in 
master) has never had an Append(long) method.
   
   You're right - sorry I got confused between the different languages' 
implementations.
   
   I started a conversation on the dev list about this topic, and @wesm had a 
good idea that we could consider here:
   
   > I think we should validate optionally in ValidateFull in C++. I think to 
validate unconditionally would be too computationally expensive
   
   https://issues.apache.org/jira/browse/ARROW-9705
   
   I think you've convinced me that the default/right/safe behavior is to 
ensure the spec is enforced, so ensuring appending a `DateTimeOffset` to a 
`Date64Array` makes the underlying `long` value divisible by `86400000` is the 
right thing to do. If necessary, in the future we could add a `long` overload 
which doesn't do validation in the off chance that someone really did want 
non-zero time in their `Date64Array`.
   
   Thanks for working through this with me.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


Reply via email to