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"

Reply via email to