From 78e57e44fac6ca7cba855f9970cb72982e538dc3 Mon Sep 17 00:00:00 2001 From: Sutou Kouhei Date: Tue, 27 Jan 2026 22:23:31 +0900 Subject: [PATCH] GH-49027: [Ruby] Add support for writing time arrays --- .../red-arrow-format/lib/arrow-format/type.rb | 19 ++- ruby/red-arrow-format/test/test-reader.rb | 3 +- ruby/red-arrow-format/test/test-writer.rb | 114 ++++++++++++++++++ 3 files changed, 134 insertions(+), 2 deletions(-) diff --git a/ruby/red-arrow-format/lib/arrow-format/type.rb b/ruby/red-arrow-format/lib/arrow-format/type.rb index a114ef225b0..4875cda27e6 100644 --- a/ruby/red-arrow-format/lib/arrow-format/type.rb +++ b/ruby/red-arrow-format/lib/arrow-format/type.rb @@ -388,14 +388,27 @@ def build_array(size, validity_buffer, values_buffer) end class TimeType < TemporalType + attr_reader :bit_width attr_reader :unit - def initialize(unit) + def initialize(bit_width, unit) super() + @bit_width = bit_width @unit = unit end + + def to_flatbuffers + fb_type = FB::Time::Data.new + fb_type.bit_width = @bit_width + fb_type.unit = FB::TimeUnit.try_convert(@unit.to_s.upcase) + fb_type + end end class Time32Type < TimeType + def initialize(unit) + super(32, unit) + end + def name "Time32" end @@ -406,6 +419,10 @@ def build_array(size, validity_buffer, values_buffer) end class Time64Type < TimeType + def initialize(unit) + super(64, unit) + end + def name "Time64" end diff --git a/ruby/red-arrow-format/test/test-reader.rb b/ruby/red-arrow-format/test/test-reader.rb index d59ae9cb168..a5919c3fb9f 100644 --- a/ruby/red-arrow-format/test/test-reader.rb +++ b/ruby/red-arrow-format/test/test-reader.rb @@ -225,7 +225,8 @@ def setup(&block) end def build_array - Arrow::Time32Array.new(:second, [@time_00_00_10, nil, @time_00_01_10]) + Arrow::Time32Array.new(:second, + [@time_00_00_10, nil, @time_00_01_10]) end def test_read diff --git a/ruby/red-arrow-format/test/test-writer.rb b/ruby/red-arrow-format/test/test-writer.rb index 6eb1273b7a6..e65a60be1ff 100644 --- a/ruby/red-arrow-format/test/test-writer.rb +++ b/ruby/red-arrow-format/test/test-writer.rb @@ -46,6 +46,20 @@ def convert_type(red_arrow_type) ArrowFormat::Date32Type.singleton when Arrow::Date64DataType ArrowFormat::Date64Type.singleton + when Arrow::Time32DataType + case red_arrow_type.unit.nick + when "second" + ArrowFormat::Time32Type.new(:second) + when "milli" + ArrowFormat::Time32Type.new(:millisecond) + end + when Arrow::Time64DataType + case red_arrow_type.unit.nick + when "micro" + ArrowFormat::Time64Type.new(:microsecond) + when "nano" + ArrowFormat::Time64Type.new(:nanosecond) + end when Arrow::BinaryDataType ArrowFormat::BinaryType.singleton when Arrow::LargeBinaryDataType @@ -268,6 +282,106 @@ def test_write end end + sub_test_case("Time32(:second)") do + def setup(&block) + @time_00_00_10 = 10 + @time_00_01_10 = 60 + 10 + super(&block) + end + + def build_array + Arrow::Time32Array.new(:second, + [@time_00_00_10, nil, @time_00_01_10]) + end + + def test_write + assert_equal([ + Arrow::Time.new(:second, @time_00_00_10), + nil, + Arrow::Time.new(:second, @time_00_01_10), + ], + @values) + end + end + + sub_test_case("Time32(:millisecond)") do + def setup(&block) + @time_00_00_10_000 = 10 * 1000 + @time_00_01_10_000 = (60 + 10) * 1000 + super(&block) + end + + def build_array + Arrow::Time32Array.new(:milli, + [ + @time_00_00_10_000, + nil, + @time_00_01_10_000, + ]) + end + + def test_write + assert_equal([ + Arrow::Time.new(:milli, @time_00_00_10_000), + nil, + Arrow::Time.new(:milli, @time_00_01_10_000), + ], + @values) + end + end + + sub_test_case("Time64(:microsecond)") do + def setup(&block) + @time_00_00_10_000_000 = 10 * 1_000_000 + @time_00_01_10_000_000 = (60 + 10) * 1_000_000 + super(&block) + end + + def build_array + Arrow::Time64Array.new(:micro, + [ + @time_00_00_10_000_000, + nil, + @time_00_01_10_000_000, + ]) + end + + def test_write + assert_equal([ + Arrow::Time.new(:micro, @time_00_00_10_000_000), + nil, + Arrow::Time.new(:micro, @time_00_01_10_000_000), + ], + @values) + end + end + + sub_test_case("Time64(:nanosecond)") do + def setup(&block) + @time_00_00_10_000_000_000 = 10 * 1_000_000_000 + @time_00_01_10_000_000_000 = (60 + 10) * 1_000_000_000 + super(&block) + end + + def build_array + Arrow::Time64Array.new(:nano, + [ + @time_00_00_10_000_000_000, + nil, + @time_00_01_10_000_000_000, + ]) + end + + def test_write + assert_equal([ + Arrow::Time.new(:nano, @time_00_00_10_000_000_000), + nil, + Arrow::Time.new(:nano, @time_00_01_10_000_000_000), + ], + @values) + end + end + sub_test_case("Binary") do def build_array Arrow::BinaryArray.new(["Hello".b, nil, "World".b])