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

kou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/main by this push:
     new 6166ef5980 GH-50435: [Ruby] Add `ArrowFormat::Time{32,64}.new(unit, 
values)` (#50443)
6166ef5980 is described below

commit 6166ef59804cbae988954776704301656eb68c1a
Author: Sutou Kouhei <[email protected]>
AuthorDate: Thu Jul 9 18:18:21 2026 +0900

    GH-50435: [Ruby] Add `ArrowFormat::Time{32,64}.new(unit, values)` (#50443)
    
    ### Rationale for this change
    
    Building a time{32,64} Arrow array from Ruby objects is convenient.
    
    ### What changes are included in this PR?
    
    Accept `ArrowFormat::Time{32,64}.new(unit, values)`.
    
    ### Are these changes tested?
    
    Yes.
    
    ### Are there any user-facing changes?
    
    Yes.
    * GitHub Issue: #50435
    
    Authored-by: Sutou Kouhei <[email protected]>
    Signed-off-by: Sutou Kouhei <[email protected]>
---
 ruby/red-arrow-format/lib/arrow-format/array.rb | 18 ++++++++
 ruby/red-arrow-format/lib/arrow-format/type.rb  | 36 +++++++++++++++
 ruby/red-arrow-format/test/test-time32-array.rb | 60 +++++++++++++++++++++++++
 ruby/red-arrow-format/test/test-time64-array.rb | 60 +++++++++++++++++++++++++
 4 files changed, 174 insertions(+)

diff --git a/ruby/red-arrow-format/lib/arrow-format/array.rb 
b/ruby/red-arrow-format/lib/arrow-format/array.rb
index 2cccb7013b..bc79edf9eb 100644
--- a/ruby/red-arrow-format/lib/arrow-format/array.rb
+++ b/ruby/red-arrow-format/lib/arrow-format/array.rb
@@ -192,6 +192,9 @@ module ArrowFormat
         expected_n_args = "1 or 3"
       else
         type = args.shift
+        unless type.is_a?(Type)
+          type = self.class.type_class.try_convert(type) || type
+        end
         expected_n_args = "2 or 4"
       end
       args = build_data(args[0], type) if args.size == 1
@@ -461,12 +464,27 @@ module ArrowFormat
   end
 
   class Time32Array < TimeArray
+    class << self
+      def type_class
+        Time32Type
+      end
+    end
   end
 
   class Time64Array < TimeArray
+    class << self
+      def type_class
+        Time64Type
+      end
+    end
   end
 
   class TimestampArray < TemporalArray
+    class << self
+      def type_class
+        TimestampType
+      end
+    end
   end
 
   class IntervalArray < TemporalArray
diff --git a/ruby/red-arrow-format/lib/arrow-format/type.rb 
b/ruby/red-arrow-format/lib/arrow-format/type.rb
index 0e57e62c32..6711f995fd 100644
--- a/ruby/red-arrow-format/lib/arrow-format/type.rb
+++ b/ruby/red-arrow-format/lib/arrow-format/type.rb
@@ -476,6 +476,20 @@ module ArrowFormat
   end
 
   class Time32Type < TimeType
+    class << self
+      def try_convert(value)
+        case value
+        when Symbol
+          unit = value
+          new(unit)
+        when self
+          value
+        else
+          nil
+        end
+      end
+    end
+
     def initialize(unit)
       super(32, unit)
     end
@@ -488,12 +502,30 @@ module ArrowFormat
       :s32
     end
 
+    def pack_template
+      "l"
+    end
+
     def build_array(...)
       Time32Array.new(self, ...)
     end
   end
 
   class Time64Type < TimeType
+    class << self
+      def try_convert(value)
+        case value
+        when Symbol
+          unit = value
+          new(unit)
+        when self
+          value
+        else
+          nil
+        end
+      end
+    end
+
     def initialize(unit)
       super(64, unit)
     end
@@ -506,6 +538,10 @@ module ArrowFormat
       :s64
     end
 
+    def pack_template
+      "q"
+    end
+
     def build_array(...)
       Time64Array.new(self, ...)
     end
diff --git a/ruby/red-arrow-format/test/test-time32-array.rb 
b/ruby/red-arrow-format/test/test-time32-array.rb
new file mode 100644
index 0000000000..98e865d9e2
--- /dev/null
+++ b/ruby/red-arrow-format/test/test-time32-array.rb
@@ -0,0 +1,60 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+class TestTime32Array < Test::Unit::TestCase
+  def setup
+    @time_00_00_10 = 10
+    @time_00_01_10 = 60 + 10
+  end
+
+  sub_test_case("#initialize") do
+    def test_no_null
+      values = [@time_00_00_10, @time_00_01_10]
+      assert_equal(values,
+                   ArrowFormat::Time32Array.new(:second, values).to_a)
+    end
+
+    def test_mixed
+      values = [@time_00_00_10, nil, @time_00_01_10]
+      assert_equal(values,
+                   ArrowFormat::Time32Array.new(:second, values).to_a)
+    end
+  end
+
+  sub_test_case("#==") do
+    def test_no_slice
+      values = [@time_00_00_10, nil, @time_00_01_10]
+      array1 = ArrowFormat::Time32Array.new(:second, values)
+      array2 = ArrowFormat::Time32Array.new(:second, values)
+      assert_equal(array1, array2)
+    end
+
+    def test_sliced
+      values = [@time_00_00_10, nil, @time_00_01_10]
+      array1 = ArrowFormat::Time32Array.new(:second, values)
+      array2 = ArrowFormat::Time32Array.new(:second, [0, *values, 0])
+      assert_equal(array1, array2.slice(1, 3))
+    end
+
+    def test_sliced_different_content
+      values = [@time_00_00_10, nil, @time_00_01_10]
+      array1 = ArrowFormat::Time32Array.new(:second, values)
+      array2 = ArrowFormat::Time32Array.new(:second, [0, 0, *values, 0])
+      assert_not_equal(array1, array2.slice(1, 3))
+    end
+  end
+end
diff --git a/ruby/red-arrow-format/test/test-time64-array.rb 
b/ruby/red-arrow-format/test/test-time64-array.rb
new file mode 100644
index 0000000000..3625a1917f
--- /dev/null
+++ b/ruby/red-arrow-format/test/test-time64-array.rb
@@ -0,0 +1,60 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+class TestTime64Array < Test::Unit::TestCase
+  def setup
+    @time_00_00_10_000_000 = 10 * 1_000_000
+    @time_00_01_10_000_000 = (60 + 10) * 1_000_000
+  end
+
+  sub_test_case("#initialize") do
+    def test_no_null
+      values = [@time_00_00_10_000_000, @time_00_01_10_000_000]
+      assert_equal(values,
+                   ArrowFormat::Time64Array.new(:microsecond, values).to_a)
+    end
+
+    def test_mixed
+      values = [@time_00_00_10_000_000, nil, @time_00_01_10_000_000]
+      assert_equal(values,
+                   ArrowFormat::Time64Array.new(:microsecond, values).to_a)
+    end
+  end
+
+  sub_test_case("#==") do
+    def test_no_slice
+      values = [@time_00_00_10_000_000, nil, @time_00_01_10_000_000]
+      array1 = ArrowFormat::Time64Array.new(:microsecond, values)
+      array2 = ArrowFormat::Time64Array.new(:microsecond, values)
+      assert_equal(array1, array2)
+    end
+
+    def test_sliced
+      values = [@time_00_00_10_000_000, nil, @time_00_01_10_000_000]
+      array1 = ArrowFormat::Time64Array.new(:microsecond, values)
+      array2 = ArrowFormat::Time64Array.new(:microsecond, [0, *values, 0])
+      assert_equal(array1, array2.slice(1, 3))
+    end
+
+    def test_sliced_different_content
+      values = [@time_00_00_10_000_000, nil, @time_00_01_10_000_000]
+      array1 = ArrowFormat::Time64Array.new(:microsecond, values)
+      array2 = ArrowFormat::Time64Array.new(:microsecond, [0, 0, *values, 0])
+      assert_not_equal(array1, array2.slice(1, 3))
+    end
+  end
+end

Reply via email to