Skip to content

Commit 58a6ea2

Browse files
authored
GH-50436: [Ruby] Add ArrowFormat::TimestampArray.new(unit, values) (#50445)
### Rationale for this change Building a timestamp Arrow array from Ruby objects is convenient. ### What changes are included in this PR? Accept `ArrowFormat::TimestampArray.new(unit, values)`. ### Are these changes tested? Yes. ### Are there any user-facing changes? Yes. * GitHub Issue: #50436 Authored-by: Sutou Kouhei <kou@clear-code.com> Signed-off-by: Sutou Kouhei <kou@clear-code.com>
1 parent 15fe981 commit 58a6ea2

2 files changed

Lines changed: 113 additions & 0 deletions

File tree

ruby/red-arrow-format/lib/arrow-format/type.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,23 @@ def build_array(...)
548548
end
549549

550550
class TimestampType < TemporalType
551+
class << self
552+
def try_convert(value)
553+
case value
554+
when Symbol
555+
unit = value
556+
new(unit, nil)
557+
when ::Array
558+
unit, time_zone = value
559+
new(unit, time_zone)
560+
when self
561+
value
562+
else
563+
nil
564+
end
565+
end
566+
end
567+
551568
attr_reader :unit
552569
attr_reader :time_zone
553570
def initialize(unit, time_zone)
@@ -556,6 +573,12 @@ def initialize(unit, time_zone)
556573
@time_zone = time_zone
557574
end
558575

576+
def ==(other)
577+
other.is_a?(self.class) and
578+
@unit == other.unit and
579+
@time_zone == other.time_zone
580+
end
581+
559582
def name
560583
"Timestamp"
561584
end
@@ -564,6 +587,10 @@ def buffer_type
564587
:s64
565588
end
566589

590+
def pack_template
591+
"q"
592+
end
593+
567594
def build_array(...)
568595
TimestampArray.new(self, ...)
569596
end
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
class TestTimestampArray < Test::Unit::TestCase
19+
def setup
20+
@timestamp_2019_11_17_15_09_11 = 1574003351
21+
@timestamp_2025_12_16_05_33_58 = 1765863238
22+
end
23+
24+
sub_test_case("#initialize") do
25+
def test_no_null
26+
values = [
27+
@timestamp_2019_11_17_15_09_11,
28+
@timestamp_2025_12_16_05_33_58,
29+
]
30+
assert_equal(values,
31+
ArrowFormat::TimestampArray.new(:second, values).to_a)
32+
end
33+
34+
def test_mixed
35+
values = [
36+
@timestamp_2019_11_17_15_09_11,
37+
nil,
38+
@timestamp_2025_12_16_05_33_58,
39+
]
40+
assert_equal(values,
41+
ArrowFormat::TimestampArray.new(:second, values).to_a)
42+
end
43+
44+
def test_time_zone
45+
time_zone = "UTC"
46+
array = ArrowFormat::TimestampArray.new([:second, time_zone], [nil])
47+
assert_equal(ArrowFormat::TimestampType.new(:second, time_zone),
48+
array.type)
49+
end
50+
end
51+
52+
sub_test_case("#==") do
53+
def test_no_slice
54+
values = [
55+
@timestamp_2019_11_17_15_09_11,
56+
nil,
57+
@timestamp_2025_12_16_05_33_58,
58+
]
59+
array1 = ArrowFormat::TimestampArray.new(:second, values)
60+
array2 = ArrowFormat::TimestampArray.new(:second, values)
61+
assert_equal(array1, array2)
62+
end
63+
64+
def test_sliced
65+
values = [
66+
@timestamp_2019_11_17_15_09_11,
67+
nil,
68+
@timestamp_2025_12_16_05_33_58,
69+
]
70+
array1 = ArrowFormat::TimestampArray.new(:second, values)
71+
array2 = ArrowFormat::TimestampArray.new(:second, [0, *values, 0])
72+
assert_equal(array1, array2.slice(1, 3))
73+
end
74+
75+
def test_sliced_different_content
76+
values = [
77+
@timestamp_2019_11_17_15_09_11,
78+
nil,
79+
@timestamp_2025_12_16_05_33_58,
80+
]
81+
array1 = ArrowFormat::TimestampArray.new(:second, values)
82+
array2 = ArrowFormat::TimestampArray.new(:second, [0, 0, *values, 0])
83+
assert_not_equal(array1, array2.slice(1, 3))
84+
end
85+
end
86+
end

0 commit comments

Comments
 (0)