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 0781f13414 GH-37290: [MATLAB] Add `arrow.array.Time32Array` class
(#37315)
0781f13414 is described below
commit 0781f1341446b8dbb281ac2910dc5e05ec982851
Author: sgilmore10 <[email protected]>
AuthorDate: Tue Aug 22 22:49:35 2023 -0400
GH-37290: [MATLAB] Add `arrow.array.Time32Array` class (#37315)
### Rationale for this change
Now that the `arrow.type.Time32Type` class has been added to the MATLAB
Interface (#37250), we can add the `arrow.array.Time32Array` class.
### What changes are included in this PR?
1. Added a new class `arrow.array.Time32Array`. It has the following
read-only properties: `Type` and `Length`. It has the following methods:
`fromMATLAB()`, `toMATLAB()`, and `duration()`. For reference, `duration`
arrays in MATLAB represent lengths of time in fixed-length units. Here's a
[link](https://www.mathworks.com/help/matlab/ref/duration.html) to the
documentation.
2. Added a new class called `arrow.type.traits.Time32Traits`.
**Example Usage**
```matlab
>> times = seconds([100 120 NaN 200])
times =
1×4 duration array
100 sec 120 sec NaN sec 200 sec
>> time32Array = arrow.array.Time32Array.fromMATLAB(times)
time32Array =
[
00:01:40,
00:02:00,
null,
00:03:20
]
>> roundtrip = toMATLAB(time32Array)
roundtrip =
4×1 duration array
100 sec
120 sec
NaN sec
200 sec
```
You can also specify the `TimeUnit` to use via a name-value pair.
`TimeUnit` can either be `"Second"` (default) or `"Milisecond"`.
```matlab
>> times = seconds([100 120 NaN 200]);
>> time32Array = arrow.array.Time32Array.fromMATLAB(times,
TimeUnit="Millisecond")
time32Array =
[
00:01:40.000,
00:02:00.000,
null,
00:03:20.000
]
```
### Are these changes tested?
Yes. Added two new test classes: `tTime32Array.m` and `tTime32Traits.m`.
### Are there any user-facing changes?
Yes, users can now create `arrow.array.Time32Array`s from MATLAB
`duration`s via the static `fromMATLAB` method on `arrow.array.Time32Array`.
### Future Directions
1. Add `arrow.array.Time64Array`
2. Add `arrow.type.Date32Type` and `arrow.array.Date32Array`
4. Add `arrow.type.Date64Type` and `arrow.array.Date64Array`
* Closes: #37290
Authored-by: Sarah Gilmore <[email protected]>
Signed-off-by: Sutou Kouhei <[email protected]>
---
.../cpp/arrow/matlab/array/proxy/time32_array.cc | 62 ++++++
.../cpp/arrow/matlab/array/proxy/time32_array.h | 31 +++
matlab/src/cpp/arrow/matlab/proxy/factory.cc | 2 +
matlab/src/cpp/arrow/matlab/type/proxy/wrap.cc | 3 +
matlab/src/matlab/+arrow/+array/Time32Array.m | 84 ++++++++
.../src/matlab/+arrow/+type/+traits/Time32Traits.m | 29 +++
matlab/src/matlab/+arrow/+type/+traits/traits.m | 2 +
matlab/test/arrow/array/tTime32Array.m | 220 +++++++++++++++++++++
matlab/test/arrow/type/traits/tTime32Traits.m | 32 +++
matlab/test/arrow/type/traits/ttraits.m | 12 ++
matlab/tools/cmake/BuildMatlabArrowInterface.cmake | 1 +
11 files changed, 478 insertions(+)
diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/time32_array.cc
b/matlab/src/cpp/arrow/matlab/array/proxy/time32_array.cc
new file mode 100644
index 0000000000..5def045a9d
--- /dev/null
+++ b/matlab/src/cpp/arrow/matlab/array/proxy/time32_array.cc
@@ -0,0 +1,62 @@
+// 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.
+
+#include "arrow/matlab/array/proxy/time32_array.h"
+
+#include "arrow/matlab/type/time_unit.h"
+#include "arrow/util/utf8.h"
+
+namespace arrow::matlab::array::proxy {
+
+ // Specialization of NumericArray::Make for arrow::Time32Type
+ template <>
+ libmexclass::proxy::MakeResult Time32Array::make(const
libmexclass::proxy::FunctionArguments& constructor_arguments) {
+ namespace mda = ::matlab::data;
+ using MatlabBuffer = arrow::matlab::buffer::MatlabBuffer;
+ using Time32Array = arrow::Time32Array;
+ using Time32ArrayProxy =
arrow::matlab::array::proxy::NumericArray<arrow::Time32Type>;
+
+ mda::StructArray opts = constructor_arguments[0];
+
+ // Get the mxArray from constructor arguments
+ const mda::TypedArray<int32_t> time32_mda = opts[0]["MatlabArray"];
+ const mda::TypedArray<bool> validity_bitmap_mda = opts[0]["Valid"];
+
+ const mda::TypedArray<mda::MATLABString> units_mda =
opts[0]["TimeUnit"];
+
+ // extract the time unit
+ const std::u16string& u16_timeunit = units_mda[0];
+ MATLAB_ASSIGN_OR_ERROR(const auto time_unit,
+
arrow::matlab::type::timeUnitFromString(u16_timeunit),
+ error::UKNOWN_TIME_UNIT_ERROR_ID)
+
+ // create the Time32Type
+ auto data_type = arrow::time32(time_unit);
+ auto array_length =
static_cast<int32_t>(time32_mda.getNumberOfElements()); // cast size_t to
int32_t
+
+ auto data_buffer = std::make_shared<MatlabBuffer>(time32_mda);
+
+ // Pack the validity bitmap values.
+ MATLAB_ASSIGN_OR_ERROR(auto packed_validity_bitmap,
+ bit::packValid(validity_bitmap_mda),
+ error::BITPACK_VALIDITY_BITMAP_ERROR_ID);
+
+ auto array_data = arrow::ArrayData::Make(data_type, array_length,
{packed_validity_bitmap, data_buffer});
+ auto time32_array =
std::static_pointer_cast<Time32Array>(arrow::MakeArray(array_data));
+ return std::make_shared<Time32ArrayProxy>(std::move(time32_array));
+ }
+}
diff --git a/matlab/src/cpp/arrow/matlab/array/proxy/time32_array.h
b/matlab/src/cpp/arrow/matlab/array/proxy/time32_array.h
new file mode 100644
index 0000000000..6770adeaed
--- /dev/null
+++ b/matlab/src/cpp/arrow/matlab/array/proxy/time32_array.h
@@ -0,0 +1,31 @@
+// 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.
+
+#pragma once
+
+#include "arrow/matlab/array/proxy/numeric_array.h"
+
+#include "arrow/matlab/api/visibility.h"
+
+namespace arrow::matlab::array::proxy {
+
+ using Time32Array = NumericArray<arrow::Time32Type>;
+
+ // Specialization of NumericArray::Make for arrow::Time32Type
+ template<>
+ ARROW_MATLAB_EXPORT libmexclass::proxy::MakeResult Time32Array::make(const
libmexclass::proxy::FunctionArguments& constructor_arguments);
+}
diff --git a/matlab/src/cpp/arrow/matlab/proxy/factory.cc
b/matlab/src/cpp/arrow/matlab/proxy/factory.cc
index ec6a544c4f..554046f600 100644
--- a/matlab/src/cpp/arrow/matlab/proxy/factory.cc
+++ b/matlab/src/cpp/arrow/matlab/proxy/factory.cc
@@ -19,6 +19,7 @@
#include "arrow/matlab/array/proxy/numeric_array.h"
#include "arrow/matlab/array/proxy/string_array.h"
#include "arrow/matlab/array/proxy/timestamp_array.h"
+#include "arrow/matlab/array/proxy/time32_array.h"
#include "arrow/matlab/tabular/proxy/record_batch.h"
#include "arrow/matlab/tabular/proxy/schema.h"
#include "arrow/matlab/error/error.h"
@@ -49,6 +50,7 @@ libmexclass::proxy::MakeResult Factory::make_proxy(const
ClassName& class_name,
REGISTER_PROXY(arrow.array.proxy.BooleanArray ,
arrow::matlab::array::proxy::BooleanArray);
REGISTER_PROXY(arrow.array.proxy.StringArray ,
arrow::matlab::array::proxy::StringArray);
REGISTER_PROXY(arrow.array.proxy.TimestampArray,
arrow::matlab::array::proxy::NumericArray<arrow::TimestampType>);
+ REGISTER_PROXY(arrow.array.proxy.Time32Array ,
arrow::matlab::array::proxy::NumericArray<arrow::Time32Type>);
REGISTER_PROXY(arrow.tabular.proxy.RecordBatch ,
arrow::matlab::tabular::proxy::RecordBatch);
REGISTER_PROXY(arrow.tabular.proxy.Schema ,
arrow::matlab::tabular::proxy::Schema);
REGISTER_PROXY(arrow.type.proxy.Field ,
arrow::matlab::type::proxy::Field);
diff --git a/matlab/src/cpp/arrow/matlab/type/proxy/wrap.cc
b/matlab/src/cpp/arrow/matlab/type/proxy/wrap.cc
index b01148fe1c..39c60fea9b 100644
--- a/matlab/src/cpp/arrow/matlab/type/proxy/wrap.cc
+++ b/matlab/src/cpp/arrow/matlab/type/proxy/wrap.cc
@@ -19,6 +19,7 @@
#include "arrow/matlab/type/proxy/primitive_ctype.h"
#include "arrow/matlab/type/proxy/timestamp_type.h"
+#include "arrow/matlab/type/proxy/time32_type.h"
#include "arrow/matlab/type/proxy/string_type.h"
namespace arrow::matlab::type::proxy {
@@ -50,6 +51,8 @@ namespace arrow::matlab::type::proxy {
return
std::make_shared<PrimitiveCType<double>>(std::static_pointer_cast<arrow::DoubleType>(type));
case ID::TIMESTAMP:
return
std::make_shared<TimestampType>(std::static_pointer_cast<arrow::TimestampType>(type));
+ case ID::TIME32:
+ return
std::make_shared<Time32Type>(std::static_pointer_cast<arrow::Time32Type>(type));
case ID::STRING:
return
std::make_shared<StringType>(std::static_pointer_cast<arrow::StringType>(type));
default:
diff --git a/matlab/src/matlab/+arrow/+array/Time32Array.m
b/matlab/src/matlab/+arrow/+array/Time32Array.m
new file mode 100644
index 0000000000..85babd26a7
--- /dev/null
+++ b/matlab/src/matlab/+arrow/+array/Time32Array.m
@@ -0,0 +1,84 @@
+% arrow.array.Time32Array
+
+% 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.
+
+classdef Time32Array < arrow.array.Array
+
+ properties(Access=private)
+ NullSubstitutionValue = seconds(NaN);
+ end
+
+ methods
+ function obj = Time32Array(proxy)
+ arguments
+ proxy(1, 1) libmexclass.proxy.Proxy {validate(proxy,
"arrow.array.proxy.Time32Array")}
+ end
+ import arrow.internal.proxy.validate
+ [email protected](proxy);
+ end
+
+ function times = toMATLAB(obj)
+ import arrow.type.TimeUnit
+
+ matlabArray = obj.Proxy.toMATLAB();
+ if obj.Type.TimeUnit == TimeUnit.Second
+ times = seconds(matlabArray);
+ else
+ times = milliseconds(matlabArray);
+ end
+ times(~obj.Valid) = obj.NullSubstitutionValue;
+ end
+
+ function times = duration(obj)
+ times = obj.toMATLAB();
+ end
+ end
+
+ methods(Static, Access=private)
+ function ticks = convertDurationToTicks(data, timeUnit)
+ if (timeUnit == arrow.type.TimeUnit.Second)
+ ticks = cast(seconds(data), "int32");
+ else
+ ticks = cast(milliseconds(data), "int32");
+ end
+ end
+ end
+
+ methods(Static)
+ function array = fromMATLAB(data, opts)
+ arguments
+ data
+ opts.TimeUnit(1, 1) TimeUnit {timeUnit("Time32",
opts.TimeUnit)} = TimeUnit.Second
+ opts.InferNulls(1, 1) logical = true
+ opts.Valid
+ end
+
+ import arrow.type.TimeUnit
+ import arrow.array.Time32Array
+ import arrow.internal.validate.temporal.timeUnit
+
+ arrow.internal.validate.type(data, "duration");
+ arrow.internal.validate.shape(data);
+
+ validElements = arrow.internal.validate.parseValidElements(data,
opts);
+ ticks = Time32Array.convertDurationToTicks(data, opts.TimeUnit);
+
+ args = struct(MatlabArray=ticks, Valid=validElements,
TimeUnit=string(opts.TimeUnit));
+ proxy =
arrow.internal.proxy.create("arrow.array.proxy.Time32Array", args);
+ array = Time32Array(proxy);
+ end
+ end
+end
\ No newline at end of file
diff --git a/matlab/src/matlab/+arrow/+type/+traits/Time32Traits.m
b/matlab/src/matlab/+arrow/+type/+traits/Time32Traits.m
new file mode 100644
index 0000000000..844740167c
--- /dev/null
+++ b/matlab/src/matlab/+arrow/+type/+traits/Time32Traits.m
@@ -0,0 +1,29 @@
+% 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.
+
+classdef Time32Traits < arrow.type.traits.TypeTraits
+
+ properties (Constant)
+ ArrayConstructor = @arrow.array.Time32Array
+ ArrayClassName = "arrow.array.Time32Array"
+ ArrayProxyClassName = "arrow.array.proxy.Time32Array"
+ TypeConstructor = @arrow.type.Time32Type;
+ TypeClassName = "arrow.type.Time32Type"
+ TypeProxyClassName = "arrow.type.proxy.Time32Type"
+ MatlabConstructor = @duration
+ MatlabClassName = "duration"
+ end
+
+end
\ No newline at end of file
diff --git a/matlab/src/matlab/+arrow/+type/+traits/traits.m
b/matlab/src/matlab/+arrow/+type/+traits/traits.m
index af59e2822d..0c3628f01e 100644
--- a/matlab/src/matlab/+arrow/+type/+traits/traits.m
+++ b/matlab/src/matlab/+arrow/+type/+traits/traits.m
@@ -48,6 +48,8 @@ function typeTraits = traits(type)
typeTraits = StringTraits();
case ID.Timestamp
typeTraits = TimestampTraits();
+ case ID.Time32
+ typeTraits = Time32Traits();
otherwise
error("arrow:type:traits:UnsupportedArrowTypeID", "Unsupported
Arrow type ID: " + type);
end
diff --git a/matlab/test/arrow/array/tTime32Array.m
b/matlab/test/arrow/array/tTime32Array.m
new file mode 100644
index 0000000000..d885cd80cc
--- /dev/null
+++ b/matlab/test/arrow/array/tTime32Array.m
@@ -0,0 +1,220 @@
+%TTIME32ARRAY Unit tests for arrow.array.Time32Array
+
+% 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.
+
+classdef tTime32Array < matlab.unittest.TestCase
+
+ properties
+ ArrowArrayConstructorFcn = @arrow.array.Time32Array.fromMATLAB
+ end
+
+ properties(TestParameter)
+ Unit = {arrow.type.TimeUnit.Second, arrow.type.TimeUnit.Millisecond}
+ end
+
+ methods (Test)
+ function Basic(tc)
+ times = seconds(1:4);
+ array = tc.ArrowArrayConstructorFcn(times);
+ tc.verifyInstanceOf(array, "arrow.array.Time32Array");
+ end
+
+ function TypeIsTime32(tc)
+ times = seconds(1:4);
+ array = tc.ArrowArrayConstructorFcn(times);
+ tc.verifyTime32Type(array.Type, arrow.type.TimeUnit.Second);
+ end
+
+ function SupportedTimeUnit(tc)
+ import arrow.type.TimeUnit
+ times = seconds(1:4);
+
+ array = tc.ArrowArrayConstructorFcn(times, TimeUnit="Second");
+ tc.verifyTime32Type(array.Type, arrow.type.TimeUnit.Second);
+
+ array = tc.ArrowArrayConstructorFcn(times,
TimeUnit=TimeUnit.Second);
+ tc.verifyTime32Type(array.Type, arrow.type.TimeUnit.Second);
+
+ array = tc.ArrowArrayConstructorFcn(times, TimeUnit="Millisecond");
+ tc.verifyTime32Type(array.Type, arrow.type.TimeUnit.Millisecond);
+
+ array = tc.ArrowArrayConstructorFcn(times,
TimeUnit=TimeUnit.Millisecond);
+ tc.verifyTime32Type(array.Type, arrow.type.TimeUnit.Millisecond);
+ end
+
+ function UnsupportedTimeUnitError(tc)
+ % Verify arrow.array.Time32Array.fromMATLAB() errors if
+ % supplied an unsupported TimeUnit (Microsecond or Nanosecond).
+ import arrow.type.TimeUnit
+ times = seconds(1:4);
+ fcn = @() tc.ArrowArrayConstructorFcn(times,
TimeUnit="Microsecond");
+ tc.verifyError(fcn,
"arrow:validate:temporal:UnsupportedTime32TimeUnit");
+
+ fcn = @() tc.ArrowArrayConstructorFcn(times,
TimeUnit=TimeUnit.Microsecond);
+ tc.verifyError(fcn,
"arrow:validate:temporal:UnsupportedTime32TimeUnit");
+
+ fcn = @() tc.ArrowArrayConstructorFcn(times,
TimeUnit="Nanosecond");
+ tc.verifyError(fcn,
"arrow:validate:temporal:UnsupportedTime32TimeUnit");
+
+ fcn = @() tc.ArrowArrayConstructorFcn(times,
TimeUnit=TimeUnit.Nanosecond);
+ tc.verifyError(fcn,
"arrow:validate:temporal:UnsupportedTime32TimeUnit");
+ end
+
+ function TestLength(testCase)
+ % Verify the Length property.
+
+ times = duration.empty(0, 1);
+ array = testCase.ArrowArrayConstructorFcn(times);
+ testCase.verifyEqual(array.Length, int64(0));
+
+ times = duration(1, 2, 3);
+ array = testCase.ArrowArrayConstructorFcn(times);
+ testCase.verifyEqual(array.Length, int64(1));
+
+ times = duration(1, 2, 3) + hours(0:4);
+ array = testCase.ArrowArrayConstructorFcn(times);
+ testCase.verifyEqual(array.Length, int64(5));
+ end
+
+ function TestToMATLAB(testCase, Unit)
+ % Verify toMATLAB() round-trips the original duration array.
+ times = seconds([100 200 355 400]);
+ array = testCase.ArrowArrayConstructorFcn(times, TimeUnit=Unit);
+ values = toMATLAB(array);
+ testCase.verifyEqual(values, times');
+ end
+
+ function TestDuration(testCase, Unit)
+ % Verify duration() round-trips the original duration array.
+ times = seconds([100 200 355 400]);
+ array = testCase.ArrowArrayConstructorFcn(times, TimeUnit=Unit);
+ values = duration(array);
+ testCase.verifyEqual(values, times');
+ end
+
+ function TestValid(testCase, Unit)
+ % Verify the Valid property returns the expected logical vector.
+ times = seconds([100 200 NaN 355 NaN 400]);
+ arrray = testCase.ArrowArrayConstructorFcn(times, TImeUnit=Unit);
+ testCase.verifyEqual(arrray.Valid, [true; true; false; true;
false; true]);
+ testCase.verifyEqual(toMATLAB(arrray), times');
+ testCase.verifyEqual(duration(arrray), times');
+ end
+
+ function InferNullsTrueNVPair(testCase, Unit)
+ % Verify arrow.array.Time32Array.fromMATLAB() behaves as
+ % expected when InferNulls=true is provided.
+
+ times = seconds([1 2 NaN 4 5 NaN 7]);
+ array = testCase.ArrowArrayConstructorFcn(times, InferNulls=true,
TimeUnit=Unit);
+ expectedValid = [true; true; false; true; true; false; true];
+ testCase.verifyEqual(array.Valid, expectedValid);
+ testCase.verifyEqual(toMATLAB(array), times');
+ testCase.verifyEqual(duration(array), times');
+ end
+
+ function InferNullsFalseNVPair(testCase, Unit)
+ % Verify arrow.array.Time32Array.fromMATLAB() behaves as
+ % expected when InferNulls=false is provided.
+
+ times = seconds([1 2 NaN 4 5 NaN 7]);
+ array = testCase.ArrowArrayConstructorFcn(times, InferNulls=false,
TimeUnit=Unit);
+ expectedValid = true([7 1]);
+ testCase.verifyEqual(array.Valid, expectedValid);
+
+ % If NaN durations were not considered null values, then they
+ % are treated like int32(0) values.
+ expectedTime = times';
+ expectedTime([3 6]) = 0;
+ testCase.verifyEqual(toMATLAB(array), expectedTime);
+ testCase.verifyEqual(duration(array), expectedTime);
+ end
+
+ function TestValidNVPair(testCase, Unit)
+ % Verify arrow.array.Time32Array.fromMATLAB() accepts the Valid
+ % nv-pair, and it behaves as expected.
+
+ times = seconds([1 2 NaN 4 5 NaN 7]);
+
+ % Supply the Valid name-value pair as vector of indices.
+ array = testCase.ArrowArrayConstructorFcn(times, TimeUnit=Unit,
Valid=[1 2 3 5]);
+ testCase.verifyEqual(array.Valid, [true; true; true; false; true;
false; false]);
+ expectedTimes = times';
+ expectedTimes(3) = 0;
+ expectedTimes([4 6 7]) = NaN;
+ testCase.verifyEqual(toMATLAB(array), expectedTimes);
+
+ % Supply the Valid name-value pair as a logical scalar.
+ array = testCase.ArrowArrayConstructorFcn(times, TimeUnit=Unit,
Valid=false);
+ testCase.verifyEqual(array.Valid, false([7 1]));
+ expectedTimes(:) = NaN;
+ testCase.verifyEqual(toMATLAB(array), expectedTimes);
+ end
+
+ function EmptyDurationVector(testCase)
+ % Verify arrow.array.Time32Array.fromMATLAB() accepts any
+ % empty-shaped duration as input.
+
+ times = duration.empty(0, 0);
+ array = testCase.ArrowArrayConstructorFcn(times);
+ testCase.verifyEqual(array.Length, int64(0));
+ testCase.verifyEqual(array.Valid, logical.empty(0, 1));
+ testCase.verifyEqual(toMATLAB(array), duration.empty(0, 1));
+
+ % Test with an N-Dimensional empty array
+ times = duration.empty(0, 1, 0);
+ array = testCase.ArrowArrayConstructorFcn(times);
+ testCase.verifyEqual(array.Length, int64(0));
+ testCase.verifyEqual(array.Valid, logical.empty(0, 1));
+ testCase.verifyEqual(toMATLAB(array), duration.empty(0, 1));
+ end
+
+ function ErrorIfNonVector(testCase)
+ % Verify arrow.array.Time32Array.fromMATLAB() throws an error
+ % if the input provided is not a vector.
+
+ times = duration(200, 45, 34) + hours(0:11);
+ times = reshape(times, 2, 6);
+ fcn = @() testCase.ArrowArrayConstructorFcn(times);
+ testCase.verifyError(fcn, "arrow:array:InvalidShape");
+
+ times = reshape(times, 3, 2, 2);
+ fcn = @() testCase.ArrowArrayConstructorFcn(times);
+ testCase.verifyError(fcn, "arrow:array:InvalidShape");
+ end
+
+ function ErrorIfNonDuration(testCase)
+ % Verify arrow.array.Time32Array.fromMATLAB() throws an error
+ % if not given a duration as input.
+
+ dates = datetime(2023, 4, 6);
+ fcn = @() testCase.ArrowArrayConstructorFcn(dates);
+ testCase.verifyError(fcn, "arrow:array:InvalidType");
+
+ numbers = [1; 2; 3; 4];
+ fcn = @() testCase.ArrowArrayConstructorFcn(numbers);
+ testCase.verifyError(fcn, "arrow:array:InvalidType");
+ end
+ end
+
+ methods
+ function verifyTime32Type(testCase, actual, expectedTimeUnit)
+ testCase.verifyInstanceOf(actual, "arrow.type.Time32Type");
+ testCase.verifyEqual(actual.ID, arrow.type.ID.Time32);
+ testCase.verifyEqual(actual.TimeUnit, expectedTimeUnit);
+ end
+ end
+end
\ No newline at end of file
diff --git a/matlab/test/arrow/type/traits/tTime32Traits.m
b/matlab/test/arrow/type/traits/tTime32Traits.m
new file mode 100644
index 0000000000..52e00a901a
--- /dev/null
+++ b/matlab/test/arrow/type/traits/tTime32Traits.m
@@ -0,0 +1,32 @@
+%TTIME32TRAITS Unit tests for arrow.type.traits.Time32Traits
+
+% 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.
+
+classdef tTime32Traits < hTypeTraits
+
+ properties
+ TraitsConstructor = @arrow.type.traits.Time32Traits
+ ArrayConstructor = @arrow.array.Time32Array
+ ArrayClassName = "arrow.array.Time32Array"
+ ArrayProxyClassName = "arrow.array.proxy.Time32Array"
+ TypeConstructor = @arrow.type.Time32Type
+ TypeClassName = "arrow.type.Time32Type"
+ TypeProxyClassName = "arrow.type.proxy.Time32Type"
+ MatlabConstructor = @duration
+ MatlabClassName = "duration"
+ end
+
+end
\ No newline at end of file
diff --git a/matlab/test/arrow/type/traits/ttraits.m
b/matlab/test/arrow/type/traits/ttraits.m
index 14149a5ebf..3bfde78dbb 100644
--- a/matlab/test/arrow/type/traits/ttraits.m
+++ b/matlab/test/arrow/type/traits/ttraits.m
@@ -151,6 +151,18 @@ classdef ttraits < matlab.unittest.TestCase
testCase.verifyEqual(actualTraits, expectedTraits);
end
+ function TestTime32(testCase)
+ import arrow.type.traits.*
+ import arrow.type.*
+
+ type = ID.Time32;
+ expectedTraits = Time32Traits();
+
+ actualTraits = traits(type);
+
+ testCase.verifyEqual(actualTraits, expectedTraits);
+ end
+
function TestMatlabUInt8(testCase)
import arrow.type.traits.*
diff --git a/matlab/tools/cmake/BuildMatlabArrowInterface.cmake
b/matlab/tools/cmake/BuildMatlabArrowInterface.cmake
index c421cb904e..477d7e6724 100644
--- a/matlab/tools/cmake/BuildMatlabArrowInterface.cmake
+++ b/matlab/tools/cmake/BuildMatlabArrowInterface.cmake
@@ -45,6 +45,7 @@ set(MATLAB_ARROW_LIBMEXCLASS_CLIENT_PROXY_SOURCES
"${CMAKE_SOURCE_DIR}/src/cpp/a
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/array/proxy/boolean_array.cc"
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/array/proxy/string_array.cc"
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/array/proxy/timestamp_array.cc"
+
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/array/proxy/time32_array.cc"
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/array/proxy/wrap.cc"
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/tabular/proxy/record_batch.cc"
"${CMAKE_SOURCE_DIR}/src/cpp/arrow/matlab/tabular/proxy/schema.cc"