## Coverage Report

#### Created: 2025-08-26 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /Users/andrewlamb/Software/arrow-rs/arrow-arith/src/temporal.rs

    Line
    Count
    Source
    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
    //! Defines temporal kernels for time and date related functions.
    19
    20
    use std::sync::Arc;
    21
    22
    use arrow_array::cast::AsArray;
    23
    use cast::as_primitive_array;
    24
    use chrono::{Datelike, TimeZone, Timelike, Utc};
    25
    26
    use arrow_array::temporal_conversions::{
    27
        date32_to_datetime, date64_to_datetime, timestamp_ms_to_datetime, timestamp_ns_to_datetime,
    28
        timestamp_s_to_datetime, timestamp_us_to_datetime, MICROSECONDS, MICROSECONDS_IN_DAY,
    29
        MILLISECONDS, MILLISECONDS_IN_DAY, NANOSECONDS, NANOSECONDS_IN_DAY, SECONDS_IN_DAY,
    30
    };
    31
    use arrow_array::timezone::Tz;
    32
    use arrow_array::types::*;
    33
    use arrow_array::*;
    34
    use arrow_schema::{ArrowError, DataType, IntervalUnit, TimeUnit};
    35
    36
    /// Valid parts to extract from date/time/timestamp arrays.
    37
    ///
    38
    /// See [`date_part`].
    39
    ///
    40
    /// Marked as non-exhaustive as may expand to support more types of
    41
    /// date parts in the future.
    42
    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
    43
    #[non_exhaustive]
    44
    pub enum DatePart {
    45
        /// Quarter of the year, in range `1..=4`
    46
        Quarter,
    47
        /// Calendar year
    48
        Year,
    49
        /// ISO year, computed as per ISO 8601
    50
        YearISO,
    51
        /// Month in the year, in range `1..=12`
    52
        Month,
    53
        /// week of the year, in range `1..=53`, computed as per ISO 8601
    54
        Week,
    55
        /// ISO week of the year, in range `1..=53`
    56
        WeekISO,
    57
        /// Day of the month, in range `1..=31`
    58
        Day,
    59
        /// Day of the week, in range `0..=6`, where Sunday is `0`
    60
        DayOfWeekSunday0,
    61
        /// Day of the week, in range `0..=6`, where Monday is `0`
    62
        DayOfWeekMonday0,
    63
        /// Day of year, in range `1..=366`
    64
        DayOfYear,
    65
        /// Hour of the day, in range `0..=23`
    66
        Hour,
    67
        /// Minute of the hour, in range `0..=59`
    68
        Minute,
    69
        /// Second of the minute, in range `0..=59`
    70
        Second,
    71
        /// Millisecond of the second
    72
        Millisecond,
    73
        /// Microsecond of the second
    74
        Microsecond,
    75
        /// Nanosecond of the second
    76
        Nanosecond,
    77
    }
    78
    79
    impl std::fmt::Display for DatePart {
    80
    0
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    81
    0
            write!(f, "{self:?}")
    82
    0
        }
    83
    }
    84
    85
    /// Returns function to extract relevant [`DatePart`] from types like a
    86
    /// [`NaiveDateTime`] or [`DateTime`].
    87
    ///
    88
    /// [`NaiveDateTime`]: chrono::NaiveDateTime
    89
    /// [`DateTime`]: chrono::DateTime
    90
    0
    fn get_date_time_part_extract_fn<T>(part: DatePart) -> fn(T) -> i32
    91
    0
    where
    92
    0
        T: ChronoDateExt + Datelike + Timelike,
    93
    {
    94
    0
        match part {
    95
    0
            DatePart::Quarter => |d| d.quarter() as i32,
    96
    0
            DatePart::Year => |d| d.year(),
    97
    0
            DatePart::YearISO => |d| d.iso_week().year(),
    98
    0
            DatePart::Month => |d| d.month() as i32,
    99
    0
            DatePart::Week | DatePart::WeekISO => |d| d.iso_week().week() as i32,
    100
    0
            DatePart::Day => |d| d.day() as i32,
    101
    0
            DatePart::DayOfWeekSunday0 => |d| d.num_days_from_sunday(),
    102
    0
            DatePart::DayOfWeekMonday0 => |d| d.num_days_from_monday(),
    103
    0
            DatePart::DayOfYear => |d| d.ordinal() as i32,
    104
    0
            DatePart::Hour => |d| d.hour() as i32,
    105
    0
            DatePart::Minute => |d| d.minute() as i32,
    106
    0
            DatePart::Second => |d| d.second() as i32,
    107
    0
            DatePart::Millisecond => |d| (d.nanosecond() / 1_000_000) as i32,
    108
    0
            DatePart::Microsecond => |d| (d.nanosecond() / 1_000) as i32,
    109
    0
            DatePart::Nanosecond => |d| d.nanosecond() as i32,
    110
        }
    111
    0
    }
    112
    113
    /// Given an array, return a new array with the extracted [`DatePart`] as signed 32-bit
    114
    /// integer values.
    115
    ///
    116
    /// Currently only supports temporal types:
    117
    ///   - Date32/Date64
    118
    ///   - Time32/Time64
    119
    ///   - Timestamp
    120
    ///   - Interval
    121
    ///   - Duration
    122
    ///
    123
    /// Returns an [`Int32Array`] unless input was a dictionary type, in which case returns
    124
    /// the dictionary but with this function applied onto its values.
    125
    ///
    126
    /// If array passed in is not of the above listed types (or is a dictionary array where the
    127
    /// values array isn't of the above listed types), then this function will return an error.
    128
    ///
    129
    /// # Examples
    130
    ///
    131
    /// ```
    132
    /// # use arrow_array::{Int32Array, TimestampMicrosecondArray};
    133
    /// # use arrow_arith::temporal::{DatePart, date_part};
    134
    /// let input: TimestampMicrosecondArray =
    135
    ///     vec![Some(1612025847000000), None, Some(1722015847000000)].into();
    136
    ///
    137
    /// let week = date_part(&input, DatePart::Week).unwrap();
    138
    /// let week_iso = date_part(&input, DatePart::WeekISO).unwrap();
    139
    /// let expected: Int32Array = vec![Some(4), None, Some(30)].into();
    140
    /// assert_eq!(week.as_ref(), &expected);
    141
    /// assert_eq!(week_iso.as_ref(), &expected);
    142
    /// let year_iso = date_part(&input, DatePart::YearISO).unwrap();
    143
    /// let expected: Int32Array = vec![Some(2021), None, Some(2024)].into();
    144
    /// assert_eq!(year_iso.as_ref(), &expected);
    145
    /// ```
    146
    0
    pub fn date_part(array: &dyn Array, part: DatePart) -> Result<ArrayRef, ArrowError> {
    147
    0
        downcast_temporal_array!(
    148
            array => {
    149
    0
                let array = array.date_part(part)?;
    150
    0
                let array = Arc::new(array) as ArrayRef;
    151
    0
                Ok(array)
    152
            }
    153
            DataType::Interval(IntervalUnit::YearMonth) => {
    154
    0
                let array = as_primitive_array::<IntervalYearMonthType>(array).date_part(part)?;
    155
    0
                let array = Arc::new(array) as ArrayRef;
    156
    0
                Ok(array)
    157
            }
    158
            DataType::Interval(IntervalUnit::DayTime) => {
    159
    0
                let array = as_primitive_array::<IntervalDayTimeType>(array).date_part(part)?;
    160
    0
                let array = Arc::new(array) as ArrayRef;
    161
    0
                Ok(array)
    162
            }
    163
            DataType::Interval(IntervalUnit::MonthDayNano) => {
    164
    0
                let array = as_primitive_array::<IntervalMonthDayNanoType>(array).date_part(part)?;
    165
    0
                let array = Arc::new(array) as ArrayRef;
    166
    0
                Ok(array)
    167
            }
    168
            DataType::Duration(TimeUnit::Second) => {
    169
    0
                let array = as_primitive_array::<DurationSecondType>(array).date_part(part)?;
    170
    0
                let array = Arc::new(array) as ArrayRef;
    171
    0
                Ok(array)
    172
            }
    173
            DataType::Duration(TimeUnit::Millisecond) => {
    174
    0
                let array = as_primitive_array::<DurationMillisecondType>(array).date_part(part)?;
    175
    0
                let array = Arc::new(array) as ArrayRef;
    176
    0
                Ok(array)
    177
            }
    178
            DataType::Duration(TimeUnit::Microsecond) => {
    179
    0
                let array = as_primitive_array::<DurationMicrosecondType>(array).date_part(part)?;
    180
    0
                let array = Arc::new(array) as ArrayRef;
    181
    0
                Ok(array)
    182
            }
    183
            DataType::Duration(TimeUnit::Nanosecond) => {
    184
    0
                let array = as_primitive_array::<DurationNanosecondType>(array).date_part(part)?;
    185
    0
                let array = Arc::new(array) as ArrayRef;
    186
    0
                Ok(array)
    187
            }
    188
            DataType::Dictionary(_, _) => {
    189
    0
                let array = array.as_any_dictionary();
    190
    0
                let values = date_part(array.values(), part)?;
    191
    0
                let values = Arc::new(values) as ArrayRef;
    192
    0
                let new_array = array.with_values(values);
    193
    0
                Ok(new_array)
    194
            }
    195
    0
            t => return_compute_error_with!(format!("{part} does not support"), t),
    196
        )
    197
    0
    }
    198
    199
    /// Extract optional [`Tz`] from timestamp data types, returning error
    200
    /// if called with a non-timestamp type.
    201
    0
    fn get_tz(dt: &DataType) -> Result<Option<Tz>, ArrowError> {
    202
    0
        match dt {
    203
    0
            DataType::Timestamp(_, Some(tz)) => Ok(Some(tz.parse::<Tz>()?)),
    204
    0
            DataType::Timestamp(_, None) => Ok(None),
    205
    0
            _ => Err(ArrowError::CastError(format!("Not a timestamp type: {dt}"))),
    206
        }
    207
    0
    }
    208
    209
    /// Implement the specialized functions for extracting date part from temporal arrays.
    210
    trait ExtractDatePartExt {
    211
        fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError>;
    212
    }
    213
    214
    impl ExtractDatePartExt for PrimitiveArray<Time32SecondType> {
    215
    0
        fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
    216
            #[inline]
    217
    0
            fn range_check(s: i32) -> bool {
    218
    0
                (0..SECONDS_IN_DAY as i32).contains(&s)
    219
    0
            }
    220
    0
            match part {
    221
    0
                DatePart::Hour => Ok(self.unary_opt(|s| range_check(s).then_some(s / 3_600))),
    222
    0
                DatePart::Minute => Ok(self.unary_opt(|s| range_check(s).then_some((s / 60) % 60))),
    223
    0
                DatePart::Second => Ok(self.unary_opt(|s| range_check(s).then_some(s % 60))),
    224
                // Time32Second only encodes number of seconds, so these will always be 0 (if in valid range)
    225
                DatePart::Millisecond | DatePart::Microsecond | DatePart::Nanosecond => {
    226
    0
                    Ok(self.unary_opt(|s| range_check(s).then_some(0)))
    227
                }
    228
    0
                _ => return_compute_error_with!(format!("{part} does not support"), self.data_type()),
    229
            }
    230
    0
        }
    231
    }
    232
    233
    impl ExtractDatePartExt for PrimitiveArray<Time32MillisecondType> {
    234
    0
        fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
    235
            #[inline]
    236
    0
            fn range_check(ms: i32) -> bool {
    237
    0
                (0..MILLISECONDS_IN_DAY as i32).contains(&ms)
    238
    0
            }
    239
    0
            let milliseconds = MILLISECONDS as i32;
    240
    0
            match part {
    241
                DatePart::Hour => {
    242
    0
                    Ok(self.unary_opt(|ms| range_check(ms).then_some(ms / 3_600 / milliseconds)))
    243
                }
    244
                DatePart::Minute => {
    245
    0
                    Ok(self.unary_opt(|ms| range_check(ms).then_some((ms / 60 / milliseconds) % 60)))
    246
                }
    247
                DatePart::Second => {
    248
    0
                    Ok(self.unary_opt(|ms| range_check(ms).then_some((ms / milliseconds) % 60)))
    249
                }
    250
                DatePart::Millisecond => {
    251
    0
                    Ok(self.unary_opt(|ms| range_check(ms).then_some(ms % milliseconds)))
    252
                }
    253
                DatePart::Microsecond => {
    254
    0
                    Ok(self.unary_opt(|ms| range_check(ms).then_some((ms % milliseconds) * 1_000)))
    255
                }
    256
                DatePart::Nanosecond => {
    257
    0
                    Ok(self.unary_opt(|ms| range_check(ms).then_some((ms % milliseconds) * 1_000_000)))
    258
                }
    259
    0
                _ => return_compute_error_with!(format!("{part} does not support"), self.data_type()),
    260
            }
    261
    0
        }
    262
    }
    263
    264
    impl ExtractDatePartExt for PrimitiveArray<Time64MicrosecondType> {
    265
    0
        fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
    266
            #[inline]
    267
    0
            fn range_check(us: i64) -> bool {
    268
    0
                (0..MICROSECONDS_IN_DAY).contains(&us)
    269
    0
            }
    270
    0
            match part {
    271
                DatePart::Hour => {
    272
    0
                    Ok(self
    273
    0
                        .unary_opt(|us| range_check(us).then_some((us / 3_600 / MICROSECONDS) as i32)))
    274
                }
    275
    0
                DatePart::Minute => Ok(self
    276
    0
                    .unary_opt(|us| range_check(us).then_some(((us / 60 / MICROSECONDS) % 60) as i32))),
    277
                DatePart::Second => {
    278
    0
                    Ok(self
    279
    0
                        .unary_opt(|us| range_check(us).then_some(((us / MICROSECONDS) % 60) as i32)))
    280
                }
    281
    0
                DatePart::Millisecond => Ok(self
    282
    0
                    .unary_opt(|us| range_check(us).then_some(((us % MICROSECONDS) / 1_000) as i32))),
    283
                DatePart::Microsecond => {
    284
    0
                    Ok(self.unary_opt(|us| range_check(us).then_some((us % MICROSECONDS) as i32)))
    285
                }
    286
    0
                DatePart::Nanosecond => Ok(self
    287
    0
                    .unary_opt(|us| range_check(us).then_some(((us % MICROSECONDS) * 1_000) as i32))),
    288
    0
                _ => return_compute_error_with!(format!("{part} does not support"), self.data_type()),
    289
            }
    290
    0
        }
    291
    }
    292
    293
    impl ExtractDatePartExt for PrimitiveArray<Time64NanosecondType> {
    294
    0
        fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
    295
            #[inline]
    296
    0
            fn range_check(ns: i64) -> bool {
    297
    0
                (0..NANOSECONDS_IN_DAY).contains(&ns)
    298
    0
            }
    299
    0
            match part {
    300
                DatePart::Hour => {
    301
    0
                    Ok(self
    302
    0
                        .unary_opt(|ns| range_check(ns).then_some((ns / 3_600 / NANOSECONDS) as i32)))
    303
                }
    304
    0
                DatePart::Minute => Ok(self
    305
    0
                    .unary_opt(|ns| range_check(ns).then_some(((ns / 60 / NANOSECONDS) % 60) as i32))),
    306
                DatePart::Second => Ok(
    307
    0
                    self.unary_opt(|ns| range_check(ns).then_some(((ns / NANOSECONDS) % 60) as i32))
    308
                ),
    309
    0
                DatePart::Millisecond => Ok(self.unary_opt(|ns| {
    310
    0
                    range_check(ns).then_some(((ns % NANOSECONDS) / 1_000_000) as i32)
    311
    0
                })),
    312
                DatePart::Microsecond => {
    313
    0
                    Ok(self
    314
    0
                        .unary_opt(|ns| range_check(ns).then_some(((ns % NANOSECONDS) / 1_000) as i32)))
    315
                }
    316
                DatePart::Nanosecond => {
    317
    0
                    Ok(self.unary_opt(|ns| range_check(ns).then_some((ns % NANOSECONDS) as i32)))
    318
                }
    319
    0
                _ => return_compute_error_with!(format!("{part} does not support"), self.data_type()),
    320
            }
    321
    0
        }
    322
    }
    323
    324
    impl ExtractDatePartExt for PrimitiveArray<Date32Type> {
    325
    0
        fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
    326
            // Date32 only encodes number of days, so these will always be 0
    327
            if let DatePart::Hour
    328
            | DatePart::Minute
    329
            | DatePart::Second
    330
            | DatePart::Millisecond
    331
            | DatePart::Microsecond
    332
    0
            | DatePart::Nanosecond = part
    333
            {
    334
    0
                Ok(Int32Array::new(
    335
    0
                    vec![0; self.len()].into(),
    336
    0
                    self.nulls().cloned(),
    337
    0
                ))
    338
            } else {
    339
    0
                let map_func = get_date_time_part_extract_fn(part);
    340
    0
                Ok(self.unary_opt(|d| date32_to_datetime(d).map(map_func)))
    341
            }
    342
    0
        }
    343
    }
    344
    345
    impl ExtractDatePartExt for PrimitiveArray<Date64Type> {
    346
    0
        fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
    347
    0
            let map_func = get_date_time_part_extract_fn(part);
    348
    0
            Ok(self.unary_opt(|d| date64_to_datetime(d).map(map_func)))
    349
    0
        }
    350
    }
    351
    352
    impl ExtractDatePartExt for PrimitiveArray<TimestampSecondType> {
    353
    0
        fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
    354
            // TimestampSecond only encodes number of seconds, so these will always be 0
    355
    0
            let array =
    356
    0
                if let DatePart::Millisecond | DatePart::Microsecond | DatePart::Nanosecond = part {
    357
    0
                    Int32Array::new(vec![0; self.len()].into(), self.nulls().cloned())
    358
    0
                } else if let Some(tz) = get_tz(self.data_type())? {
    359
    0
                    let map_func = get_date_time_part_extract_fn(part);
    360
    0
                    self.unary_opt(|d| {
    361
    0
                        timestamp_s_to_datetime(d)
    362
    0
                            .map(|c| Utc.from_utc_datetime(&c).with_timezone(&tz))
    363
    0
                            .map(map_func)
    364
    0
                    })
    365
                } else {
    366
    0
                    let map_func = get_date_time_part_extract_fn(part);
    367
    0
                    self.unary_opt(|d| timestamp_s_to_datetime(d).map(map_func))
    368
                };
    369
    0
            Ok(array)
    370
    0
        }
    371
    }
    372
    373
    impl ExtractDatePartExt for PrimitiveArray<TimestampMillisecondType> {
    374
    0
        fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
    375
    0
            let array = if let Some(tz) = get_tz(self.data_type())? {
    376
    0
                let map_func = get_date_time_part_extract_fn(part);
    377
    0
                self.unary_opt(|d| {
    378
    0
                    timestamp_ms_to_datetime(d)
    379
    0
                        .map(|c| Utc.from_utc_datetime(&c).with_timezone(&tz))
    380
    0
                        .map(map_func)
    381
    0
                })
    382
            } else {
    383
    0
                let map_func = get_date_time_part_extract_fn(part);
    384
    0
                self.unary_opt(|d| timestamp_ms_to_datetime(d).map(map_func))
    385
            };
    386
    0
            Ok(array)
    387
    0
        }
    388
    }
    389
    390
    impl ExtractDatePartExt for PrimitiveArray<TimestampMicrosecondType> {
    391
    0
        fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
    392
    0
            let array = if let Some(tz) = get_tz(self.data_type())? {
    393
    0
                let map_func = get_date_time_part_extract_fn(part);
    394
    0
                self.unary_opt(|d| {
    395
    0
                    timestamp_us_to_datetime(d)
    396
    0
                        .map(|c| Utc.from_utc_datetime(&c).with_timezone(&tz))
    397
    0
                        .map(map_func)
    398
    0
                })
    399
            } else {
    400
    0
                let map_func = get_date_time_part_extract_fn(part);
    401
    0
                self.unary_opt(|d| timestamp_us_to_datetime(d).map(map_func))
    402
            };
    403
    0
            Ok(array)
    404
    0
        }
    405
    }
    406
    407
    impl ExtractDatePartExt for PrimitiveArray<TimestampNanosecondType> {
    408
    0
        fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
    409
    0
            let array = if let Some(tz) = get_tz(self.data_type())? {
    410
    0
                let map_func = get_date_time_part_extract_fn(part);
    411
    0
                self.unary_opt(|d| {
    412
    0
                    timestamp_ns_to_datetime(d)
    413
    0
                        .map(|c| Utc.from_utc_datetime(&c).with_timezone(&tz))
    414
    0
                        .map(map_func)
    415
    0
                })
    416
            } else {
    417
    0
                let map_func = get_date_time_part_extract_fn(part);
    418
    0
                self.unary_opt(|d| timestamp_ns_to_datetime(d).map(map_func))
    419
            };
    420
    0
            Ok(array)
    421
    0
        }
    422
    }
    423
    424
    impl ExtractDatePartExt for PrimitiveArray<IntervalYearMonthType> {
    425
    0
        fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
    426
    0
            match part {
    427
    0
                DatePart::Year => Ok(self.unary_opt(|d| Some(d / 12))),
    428
    0
                DatePart::Month => Ok(self.unary_opt(|d| Some(d % 12))),
    429
    430
                DatePart::Quarter
    431
                | DatePart::Week
    432
                | DatePart::WeekISO
    433
                | DatePart::YearISO
    434
                | DatePart::Day
    435
                | DatePart::DayOfWeekSunday0
    436
                | DatePart::DayOfWeekMonday0
    437
                | DatePart::DayOfYear
    438
                | DatePart::Hour
    439
                | DatePart::Minute
    440
                | DatePart::Second
    441
                | DatePart::Millisecond
    442
                | DatePart::Microsecond
    443
                | DatePart::Nanosecond => {
    444
    0
                    return_compute_error_with!(format!("{part} does not support"), self.data_type())
    445
                }
    446
            }
    447
    0
        }
    448
    }
    449
    450
    impl ExtractDatePartExt for PrimitiveArray<IntervalDayTimeType> {
    451
    0
        fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
    452
    0
            match part {
    453
    0
                DatePart::Week => Ok(self.unary_opt(|d| Some(d.days / 7))),
    454
    0
                DatePart::Day => Ok(self.unary_opt(|d| Some(d.days))),
    455
    0
                DatePart::Hour => Ok(self.unary_opt(|d| Some(d.milliseconds / (60 * 60 * 1_000)))),
    456
    0
                DatePart::Minute => Ok(self.unary_opt(|d| Some(d.milliseconds / (60 * 1_000) % 60))),
    457
    0
                DatePart::Second => Ok(self.unary_opt(|d| Some(d.milliseconds / 1_000 % 60))),
    458
    0
                DatePart::Millisecond => Ok(self.unary_opt(|d| Some(d.milliseconds % (60 * 1_000)))),
    459
                DatePart::Microsecond => {
    460
    0
                    Ok(self.unary_opt(|d| (d.milliseconds % (60 * 1_000)).checked_mul(1_000)))
    461
                }
    462
                DatePart::Nanosecond => {
    463
    0
                    Ok(self.unary_opt(|d| (d.milliseconds % (60 * 1_000)).checked_mul(1_000_000)))
    464
                }
    465
    466
                DatePart::Quarter
    467
                | DatePart::Year
    468
                | DatePart::YearISO
    469
                | DatePart::WeekISO
    470
                | DatePart::Month
    471
                | DatePart::DayOfWeekSunday0
    472
                | DatePart::DayOfWeekMonday0
    473
                | DatePart::DayOfYear => {
    474
    0
                    return_compute_error_with!(format!("{part} does not support"), self.data_type())
    475
                }
    476
            }
    477
    0
        }
    478
    }
    479
    480
    impl ExtractDatePartExt for PrimitiveArray<IntervalMonthDayNanoType> {
    481
    0
        fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
    482
    0
            match part {
    483
    0
                DatePart::Year => Ok(self.unary_opt(|d: IntervalMonthDayNano| Some(d.months / 12))),
    484
    0
                DatePart::Month => Ok(self.unary_opt(|d: IntervalMonthDayNano| Some(d.months % 12))),
    485
    0
                DatePart::Week => Ok(self.unary_opt(|d: IntervalMonthDayNano| Some(d.days / 7))),
    486
    0
                DatePart::Day => Ok(self.unary_opt(|d: IntervalMonthDayNano| Some(d.days))),
    487
                DatePart::Hour => {
    488
    0
                    Ok(self.unary_opt(|d| (d.nanoseconds / (60 * 60 * 1_000_000_000)).try_into().ok()))
    489
                }
    490
                DatePart::Minute => {
    491
    0
                    Ok(self.unary_opt(|d| (d.nanoseconds / (60 * 1_000_000_000) % 60).try_into().ok()))
    492
                }
    493
                DatePart::Second => {
    494
    0
                    Ok(self.unary_opt(|d| ((d.nanoseconds / 1_000_000_000) % 60).try_into().ok()))
    495
                }
    496
    0
                DatePart::Millisecond => Ok(self.unary_opt(|d| {
    497
    0
                    (d.nanoseconds % (60 * 1_000_000_000) / 1_000_000)
    498
    0
                        .try_into()
    499
    0
                        .ok()
    500
    0
                })),
    501
    0
                DatePart::Microsecond => Ok(self.unary_opt(|d| {
    502
    0
                    (d.nanoseconds % (60 * 1_000_000_000) / 1_000)
    503
    0
                        .try_into()
    504
    0
                        .ok()
    505
    0
                })),
    506
                DatePart::Nanosecond => {
    507
    0
                    Ok(self.unary_opt(|d| (d.nanoseconds % (60 * 1_000_000_000)).try_into().ok()))
    508
                }
    509
    510
                DatePart::Quarter
    511
                | DatePart::WeekISO
    512
                | DatePart::YearISO
    513
                | DatePart::DayOfWeekSunday0
    514
                | DatePart::DayOfWeekMonday0
    515
                | DatePart::DayOfYear => {
    516
    0
                    return_compute_error_with!(format!("{part} does not support"), self.data_type())
    517
                }
    518
            }
    519
    0
        }
    520
    }
    521
    522
    impl ExtractDatePartExt for PrimitiveArray<DurationSecondType> {
    523
    0
        fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
    524
    0
            match part {
    525
    0
                DatePart::Week => Ok(self.unary_opt(|d| (d / (60 * 60 * 24 * 7)).try_into().ok())),
    526
    0
                DatePart::Day => Ok(self.unary_opt(|d| (d / (60 * 60 * 24)).try_into().ok())),
    527
    0
                DatePart::Hour => Ok(self.unary_opt(|d| (d / (60 * 60)).try_into().ok())),
    528
    0
                DatePart::Minute => Ok(self.unary_opt(|d| (d / 60).try_into().ok())),
    529
    0
                DatePart::Second => Ok(self.unary_opt(|d| d.try_into().ok())),
    530
                DatePart::Millisecond => {
    531
    0
                    Ok(self.unary_opt(|d| d.checked_mul(1_000).and_then(|d| d.try_into().ok())))
    532
                }
    533
                DatePart::Microsecond => {
    534
    0
                    Ok(self.unary_opt(|d| d.checked_mul(1_000_000).and_then(|d| d.try_into().ok())))
    535
                }
    536
                DatePart::Nanosecond => Ok(
    537
    0
                    self.unary_opt(|d| d.checked_mul(1_000_000_000).and_then(|d| d.try_into().ok()))
    538
                ),
    539
    540
                DatePart::Year
    541
                | DatePart::YearISO
    542
                | DatePart::WeekISO
    543
                | DatePart::Quarter
    544
                | DatePart::Month
    545
                | DatePart::DayOfWeekSunday0
    546
                | DatePart::DayOfWeekMonday0
    547
                | DatePart::DayOfYear => {
    548
    0
                    return_compute_error_with!(format!("{part} does not support"), self.data_type())
    549
                }
    550
            }
    551
    0
        }
    552
    }
    553
    554
    impl ExtractDatePartExt for PrimitiveArray<DurationMillisecondType> {
    555
    0
        fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
    556
    0
            match part {
    557
                DatePart::Week => {
    558
    0
                    Ok(self.unary_opt(|d| (d / (1_000 * 60 * 60 * 24 * 7)).try_into().ok()))
    559
                }
    560
    0
                DatePart::Day => Ok(self.unary_opt(|d| (d / (1_000 * 60 * 60 * 24)).try_into().ok())),
    561
    0
                DatePart::Hour => Ok(self.unary_opt(|d| (d / (1_000 * 60 * 60)).try_into().ok())),
    562
    0
                DatePart::Minute => Ok(self.unary_opt(|d| (d / (1_000 * 60)).try_into().ok())),
    563
    0
                DatePart::Second => Ok(self.unary_opt(|d| (d / 1_000).try_into().ok())),
    564
    0
                DatePart::Millisecond => Ok(self.unary_opt(|d| d.try_into().ok())),
    565
                DatePart::Microsecond => {
    566
    0
                    Ok(self.unary_opt(|d| d.checked_mul(1_000).and_then(|d| d.try_into().ok())))
    567
                }
    568
                DatePart::Nanosecond => {
    569
    0
                    Ok(self.unary_opt(|d| d.checked_mul(1_000_000).and_then(|d| d.try_into().ok())))
    570
                }
    571
    572
                DatePart::Year
    573
                | DatePart::YearISO
    574
                | DatePart::WeekISO
    575
                | DatePart::Quarter
    576
                | DatePart::Month
    577
                | DatePart::DayOfWeekSunday0
    578
                | DatePart::DayOfWeekMonday0
    579
                | DatePart::DayOfYear => {
    580
    0
                    return_compute_error_with!(format!("{part} does not support"), self.data_type())
    581
                }
    582
            }
    583
    0
        }
    584
    }
    585
    586
    impl ExtractDatePartExt for PrimitiveArray<DurationMicrosecondType> {
    587
    0
        fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
    588
    0
            match part {
    589
                DatePart::Week => {
    590
    0
                    Ok(self.unary_opt(|d| (d / (1_000_000 * 60 * 60 * 24 * 7)).try_into().ok()))
    591
                }
    592
                DatePart::Day => {
    593
    0
                    Ok(self.unary_opt(|d| (d / (1_000_000 * 60 * 60 * 24)).try_into().ok()))
    594
                }
    595
    0
                DatePart::Hour => Ok(self.unary_opt(|d| (d / (1_000_000 * 60 * 60)).try_into().ok())),
    596
    0
                DatePart::Minute => Ok(self.unary_opt(|d| (d / (1_000_000 * 60)).try_into().ok())),
    597
    0
                DatePart::Second => Ok(self.unary_opt(|d| (d / 1_000_000).try_into().ok())),
    598
    0
                DatePart::Millisecond => Ok(self.unary_opt(|d| (d / 1_000).try_into().ok())),
    599
    0
                DatePart::Microsecond => Ok(self.unary_opt(|d| d.try_into().ok())),
    600
                DatePart::Nanosecond => {
    601
    0
                    Ok(self.unary_opt(|d| d.checked_mul(1_000).and_then(|d| d.try_into().ok())))
    602
                }
    603
    604
                DatePart::Year
    605
                | DatePart::YearISO
    606
                | DatePart::WeekISO
    607
                | DatePart::Quarter
    608
                | DatePart::Month
    609
                | DatePart::DayOfWeekSunday0
    610
                | DatePart::DayOfWeekMonday0
    611
                | DatePart::DayOfYear => {
    612
    0
                    return_compute_error_with!(format!("{part} does not support"), self.data_type())
    613
                }
    614
            }
    615
    0
        }
    616
    }
    617
    618
    impl ExtractDatePartExt for PrimitiveArray<DurationNanosecondType> {
    619
    0
        fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
    620
    0
            match part {
    621
                DatePart::Week => {
    622
    0
                    Ok(self.unary_opt(|d| (d / (1_000_000_000 * 60 * 60 * 24 * 7)).try_into().ok()))
    623
                }
    624
                DatePart::Day => {
    625
    0
                    Ok(self.unary_opt(|d| (d / (1_000_000_000 * 60 * 60 * 24)).try_into().ok()))
    626
                }
    627
                DatePart::Hour => {
    628
    0
                    Ok(self.unary_opt(|d| (d / (1_000_000_000 * 60 * 60)).try_into().ok()))
    629
                }
    630
    0
                DatePart::Minute => Ok(self.unary_opt(|d| (d / (1_000_000_000 * 60)).try_into().ok())),
    631
    0
                DatePart::Second => Ok(self.unary_opt(|d| (d / 1_000_000_000).try_into().ok())),
    632
    0
                DatePart::Millisecond => Ok(self.unary_opt(|d| (d / 1_000_000).try_into().ok())),
    633
    0
                DatePart::Microsecond => Ok(self.unary_opt(|d| (d / 1_000).try_into().ok())),
    634
    0
                DatePart::Nanosecond => Ok(self.unary_opt(|d| d.try_into().ok())),
    635
    636
                DatePart::Year
    637
                | DatePart::YearISO
    638
                | DatePart::WeekISO
    639
                | DatePart::Quarter
    640
                | DatePart::Month
    641
                | DatePart::DayOfWeekSunday0
    642
                | DatePart::DayOfWeekMonday0
    643
                | DatePart::DayOfYear => {
    644
    0
                    return_compute_error_with!(format!("{part} does not support"), self.data_type())
    645
                }
    646
            }
    647
    0
        }
    648
    }
    649
    650
    macro_rules! return_compute_error_with {
    651
        ($msg:expr, $param:expr) => {
    652
            return { Err(ArrowError::ComputeError(format!("{}: {:?}", $msg, $param))) }
    653
        };
    654
    }
    655
    656
    pub(crate) use return_compute_error_with;
    657
    658
    // Internal trait, which is used for mapping values from DateLike structures
    659
    trait ChronoDateExt {
    660
        /// Returns the day of week; Monday is encoded as `0`, Tuesday as `1`, etc.
    661
        fn num_days_from_monday(&self) -> i32;
    662
    663
        /// Returns the day of week; Sunday is encoded as `0`, Monday as `1`, etc.
    664
        fn num_days_from_sunday(&self) -> i32;
    665
    }
    666
    667
    impl<T: Datelike> ChronoDateExt for T {
    668
    0
        fn num_days_from_monday(&self) -> i32 {
    669
    0
            self.weekday().num_days_from_monday() as i32
    670
    0
        }
    671
    672
    0
        fn num_days_from_sunday(&self) -> i32 {
    673
    0
            self.weekday().num_days_from_sunday() as i32
    674
    0
        }
    675
    }
    676
    677
    #[cfg(test)]
    678
    mod tests {
    679
        use super::*;
    680
    681
        /// Used to integrate new [`date_part()`] method with deprecated shims such as
    682
        /// [`hour()`] and [`week()`].
    683
        fn date_part_primitive<T: ArrowTemporalType>(
    684
            array: &PrimitiveArray<T>,
    685
            part: DatePart,
    686
        ) -> Result<Int32Array, ArrowError> {
    687
            let array = date_part(array, part)?;
    688
            Ok(array.as_primitive::<Int32Type>().to_owned())
    689
        }
    690
    691
        #[test]
    692
        fn test_temporal_array_date64_hour() {
    693
            let a: PrimitiveArray<Date64Type> =
    694
                vec![Some(1514764800000), None, Some(1550636625000)].into();
    695
    696
            let b = date_part_primitive(&a, DatePart::Hour).unwrap();
    697
            assert_eq!(0, b.value(0));
    698
            assert!(!b.is_valid(1));
    699
            assert_eq!(4, b.value(2));
    700
        }
    701
    702
        #[test]
    703
        fn test_temporal_array_date32_hour() {
    704
            let a: PrimitiveArray<Date32Type> = vec![Some(15147), None, Some(15148)].into();
    705
    706
            let b = date_part_primitive(&a, DatePart::Hour).unwrap();
    707
            assert_eq!(0, b.value(0));
    708
            assert!(!b.is_valid(1));
    709
            assert_eq!(0, b.value(2));
    710
        }
    711
    712
        #[test]
    713
        fn test_temporal_array_time32_second_hour() {
    714
            let a: PrimitiveArray<Time32SecondType> = vec![37800, 86339].into();
    715
    716
            let b = date_part_primitive(&a, DatePart::Hour).unwrap();
    717
            assert_eq!(10, b.value(0));
    718
            assert_eq!(23, b.value(1));
    719
        }
    720
    721
        #[test]
    722
        fn test_temporal_array_time64_micro_hour() {
    723
            let a: PrimitiveArray<Time64MicrosecondType> = vec![37800000000, 86339000000].into();
    724
    725
            let b = date_part_primitive(&a, DatePart::Hour).unwrap();
    726
            assert_eq!(10, b.value(0));
    727
            assert_eq!(23, b.value(1));
    728
        }
    729
    730
        #[test]
    731
        fn test_temporal_array_timestamp_micro_hour() {
    732
            let a: TimestampMicrosecondArray = vec![37800000000, 86339000000].into();
    733
    734
            let b = date_part_primitive(&a, DatePart::Hour).unwrap();
    735
            assert_eq!(10, b.value(0));
    736
            assert_eq!(23, b.value(1));
    737
        }
    738
    739
        #[test]
    740
        fn test_temporal_array_date64_year() {
    741
            let a: PrimitiveArray<Date64Type> =
    742
                vec![Some(1514764800000), None, Some(1550636625000)].into();
    743
    744
            let b = date_part_primitive(&a, DatePart::Year).unwrap();
    745
            assert_eq!(2018, b.value(0));
    746
            assert!(!b.is_valid(1));
    747
            assert_eq!(2019, b.value(2));
    748
        }
    749
    750
        #[test]
    751
        fn test_temporal_array_date32_year() {
    752
            let a: PrimitiveArray<Date32Type> = vec![Some(15147), None, Some(15448)].into();
    753
    754
            let b = date_part_primitive(&a, DatePart::Year).unwrap();
    755
            assert_eq!(2011, b.value(0));
    756
            assert!(!b.is_valid(1));
    757
            assert_eq!(2012, b.value(2));
    758
        }
    759
    760
        #[test]
    761
        fn test_temporal_array_date64_quarter() {
    762
            //1514764800000 -> 2018-01-01
    763
            //1566275025000 -> 2019-08-20
    764
            let a: PrimitiveArray<Date64Type> =
    765
                vec![Some(1514764800000), None, Some(1566275025000)].into();
    766
    767
            let b = date_part_primitive(&a, DatePart::Quarter).unwrap();
    768
            assert_eq!(1, b.value(0));
    769
            assert!(!b.is_valid(1));
    770
            assert_eq!(3, b.value(2));
    771
        }
    772
    773
        #[test]
    774
        fn test_temporal_array_date32_quarter() {
    775
            let a: PrimitiveArray<Date32Type> = vec![Some(1), None, Some(300)].into();
    776
    777
            let b = date_part_primitive(&a, DatePart::Quarter).unwrap();
    778
            assert_eq!(1, b.value(0));
    779
            assert!(!b.is_valid(1));
    780
            assert_eq!(4, b.value(2));
    781
        }
    782
    783
        #[test]
    784
        fn test_temporal_array_timestamp_quarter_with_timezone() {
    785
            // 24 * 60 * 60 = 86400
    786
            let a = TimestampSecondArray::from(vec![86400 * 90]).with_timezone("+00:00".to_string());
    787
            let b = date_part_primitive(&a, DatePart::Quarter).unwrap();
    788
            assert_eq!(2, b.value(0));
    789
            let a = TimestampSecondArray::from(vec![86400 * 90]).with_timezone("-10:00".to_string());
    790
            let b = date_part_primitive(&a, DatePart::Quarter).unwrap();
    791
            assert_eq!(1, b.value(0));
    792
        }
    793
    794
        #[test]
    795
        fn test_temporal_array_date64_month() {
    796
            //1514764800000 -> 2018-01-01
    797
            //1550636625000 -> 2019-02-20
    798
            let a: PrimitiveArray<Date64Type> =
    799
                vec![Some(1514764800000), None, Some(1550636625000)].into();
    800
    801
            let b = date_part_primitive(&a, DatePart::Month).unwrap();
    802
            assert_eq!(1, b.value(0));
    803
            assert!(!b.is_valid(1));
    804
            assert_eq!(2, b.value(2));
    805
        }
    806
    807
        #[test]
    808
        fn test_temporal_array_date32_month() {
    809
            let a: PrimitiveArray<Date32Type> = vec![Some(1), None, Some(31)].into();
    810
    811
            let b = date_part_primitive(&a, DatePart::Month).unwrap();
    812
            assert_eq!(1, b.value(0));
    813
            assert!(!b.is_valid(1));
    814
            assert_eq!(2, b.value(2));
    815
        }
    816
    817
        #[test]
    818
        fn test_temporal_array_timestamp_month_with_timezone() {
    819
            // 24 * 60 * 60 = 86400
    820
            let a = TimestampSecondArray::from(vec![86400 * 31]).with_timezone("+00:00".to_string());
    821
            let b = date_part_primitive(&a, DatePart::Month).unwrap();
    822
            assert_eq!(2, b.value(0));
    823
            let a = TimestampSecondArray::from(vec![86400 * 31]).with_timezone("-10:00".to_string());
    824
            let b = date_part_primitive(&a, DatePart::Month).unwrap();
    825
            assert_eq!(1, b.value(0));
    826
        }
    827
    828
        #[test]
    829
        fn test_temporal_array_timestamp_day_with_timezone() {
    830
            // 24 * 60 * 60 = 86400
    831
            let a = TimestampSecondArray::from(vec![86400]).with_timezone("+00:00".to_string());
    832
            let b = date_part_primitive(&a, DatePart::Day).unwrap();
    833
            assert_eq!(2, b.value(0));
    834
            let a = TimestampSecondArray::from(vec![86400]).with_timezone("-10:00".to_string());
    835
            let b = date_part_primitive(&a, DatePart::Day).unwrap();
    836
            assert_eq!(1, b.value(0));
    837
        }
    838
    839
        #[test]
    840
        fn test_temporal_array_date64_weekday() {
    841
            //1514764800000 -> 2018-01-01 (Monday)
    842
            //1550636625000 -> 2019-02-20 (Wednesday)
    843
            let a: PrimitiveArray<Date64Type> =
    844
                vec![Some(1514764800000), None, Some(1550636625000)].into();
    845
    846
            let b = date_part_primitive(&a, DatePart::DayOfWeekMonday0).unwrap();
    847
            assert_eq!(0, b.value(0));
    848
            assert!(!b.is_valid(1));
    849
            assert_eq!(2, b.value(2));
    850
        }
    851
    852
        #[test]
    853
        fn test_temporal_array_date64_weekday0() {
    854
            //1483228800000 -> 2017-01-01 (Sunday)
    855
            //1514764800000 -> 2018-01-01 (Monday)
    856
            //1550636625000 -> 2019-02-20 (Wednesday)
    857
            let a: PrimitiveArray<Date64Type> = vec![
    858
                Some(1483228800000),
    859
                None,
    860
                Some(1514764800000),
    861
                Some(1550636625000),
    862
            ]
    863
            .into();
    864
    865
            let b = date_part_primitive(&a, DatePart::DayOfWeekSunday0).unwrap();
    866
            assert_eq!(0, b.value(0));
    867
            assert!(!b.is_valid(1));
    868
            assert_eq!(1, b.value(2));
    869
            assert_eq!(3, b.value(3));
    870
        }
    871
    872
        #[test]
    873
        fn test_temporal_array_date64_day() {
    874
            //1514764800000 -> 2018-01-01
    875
            //1550636625000 -> 2019-02-20
    876
            let a: PrimitiveArray<Date64Type> =
    877
                vec![Some(1514764800000), None, Some(1550636625000)].into();
    878
    879
            let b = date_part_primitive(&a, DatePart::Day).unwrap();
    880
            assert_eq!(1, b.value(0));
    881
            assert!(!b.is_valid(1));
    882
            assert_eq!(20, b.value(2));
    883
        }
    884
    885
        #[test]
    886
        fn test_temporal_array_date32_day() {
    887
            let a: PrimitiveArray<Date32Type> = vec![Some(0), None, Some(31)].into();
    888
    889
            let b = date_part_primitive(&a, DatePart::Day).unwrap();
    890
            assert_eq!(1, b.value(0));
    891
            assert!(!b.is_valid(1));
    892
            assert_eq!(1, b.value(2));
    893
        }
    894
    895
        #[test]
    896
        fn test_temporal_array_date64_doy() {
    897
            //1483228800000 -> 2017-01-01 (Sunday)
    898
            //1514764800000 -> 2018-01-01
    899
            //1550636625000 -> 2019-02-20
    900
            let a: PrimitiveArray<Date64Type> = vec![
    901
                Some(1483228800000),
    902
                Some(1514764800000),
    903
                None,
    904
                Some(1550636625000),
    905
            ]
    906
            .into();
    907
    908
            let b = date_part_primitive(&a, DatePart::DayOfYear).unwrap();
    909
            assert_eq!(1, b.value(0));
    910
            assert_eq!(1, b.value(1));
    911
            assert!(!b.is_valid(2));
    912
            assert_eq!(51, b.value(3));
    913
        }
    914
    915
        #[test]
    916
        fn test_temporal_array_timestamp_micro_year() {
    917
            let a: TimestampMicrosecondArray =
    918
                vec![Some(1612025847000000), None, Some(1722015847000000)].into();
    919
    920
            let b = date_part_primitive(&a, DatePart::Year).unwrap();
    921
            assert_eq!(2021, b.value(0));
    922
            assert!(!b.is_valid(1));
    923
            assert_eq!(2024, b.value(2));
    924
        }
    925
    926
        #[test]
    927
        fn test_temporal_array_date64_minute() {
    928
            let a: PrimitiveArray<Date64Type> =
    929
                vec![Some(1514764800000), None, Some(1550636625000)].into();
    930
    931
            let b = date_part_primitive(&a, DatePart::Minute).unwrap();
    932
            assert_eq!(0, b.value(0));
    933
            assert!(!b.is_valid(1));
    934
            assert_eq!(23, b.value(2));
    935
        }
    936
    937
        #[test]
    938
        fn test_temporal_array_timestamp_micro_minute() {
    939
            let a: TimestampMicrosecondArray =
    940
                vec![Some(1612025847000000), None, Some(1722015847000000)].into();
    941
    942
            let b = date_part_primitive(&a, DatePart::Minute).unwrap();
    943
            assert_eq!(57, b.value(0));
    944
            assert!(!b.is_valid(1));
    945
            assert_eq!(44, b.value(2));
    946
        }
    947
    948
        #[test]
    949
        fn test_temporal_array_date32_week() {
    950
            let a: PrimitiveArray<Date32Type> = vec![Some(0), None, Some(7)].into();
    951
    952
            let b = date_part_primitive(&a, DatePart::Week).unwrap();
    953
            assert_eq!(1, b.value(0));
    954
            assert!(!b.is_valid(1));
    955
            assert_eq!(2, b.value(2));
    956
        }
    957
    958
        #[test]
    959
        fn test_temporal_array_date64_week() {
    960
            // 1646116175000 -> 2022.03.01 , 1641171600000 -> 2022.01.03
    961
            // 1640998800000 -> 2022.01.01
    962
            let a: PrimitiveArray<Date64Type> = vec![
    963
                Some(1646116175000),
    964
                None,
    965
                Some(1641171600000),
    966
                Some(1640998800000),
    967
            ]
    968
            .into();
    969
    970
            let b = date_part_primitive(&a, DatePart::Week).unwrap();
    971
            assert_eq!(9, b.value(0));
    972
            assert!(!b.is_valid(1));
    973
            assert_eq!(1, b.value(2));
    974
            assert_eq!(52, b.value(3));
    975
        }
    976
    977
        #[test]
    978
        fn test_temporal_array_timestamp_micro_week() {
    979
            //1612025847000000 -> 2021.1.30
    980
            //1722015847000000 -> 2024.7.27
    981
            let a: TimestampMicrosecondArray =
    982
                vec![Some(1612025847000000), None, Some(1722015847000000)].into();
    983
    984
            let b = date_part_primitive(&a, DatePart::Week).unwrap();
    985
            assert_eq!(4, b.value(0));
    986
            assert!(!b.is_valid(1));
    987
            assert_eq!(30, b.value(2));
    988
        }
    989
    990
        #[test]
    991
        fn test_temporal_array_date64_second() {
    992
            let a: PrimitiveArray<Date64Type> =
    993
                vec![Some(1514764800000), None, Some(1550636625000)].into();
    994
    995
            let b = date_part_primitive(&a, DatePart::Second).unwrap();
    996
            assert_eq!(0, b.value(0));
    997
            assert!(!b.is_valid(1));
    998
            assert_eq!(45, b.value(2));
    999
        }
    1000
    1001
        #[test]
    1002
        fn test_temporal_array_timestamp_micro_second() {
    1003
            let a: TimestampMicrosecondArray =
    1004
                vec![Some(1612025847000000), None, Some(1722015847000000)].into();
    1005
    1006
            let b = date_part_primitive(&a, DatePart::Second).unwrap();
    1007
            assert_eq!(27, b.value(0));
    1008
            assert!(!b.is_valid(1));
    1009
            assert_eq!(7, b.value(2));
    1010
        }
    1011
    1012
        #[test]
    1013
        fn test_temporal_array_timestamp_second_with_timezone() {
    1014
            let a = TimestampSecondArray::from(vec![10, 20]).with_timezone("+00:00".to_string());
    1015
            let b = date_part_primitive(&a, DatePart::Second).unwrap();
    1016
            assert_eq!(10, b.value(0));
    1017
            assert_eq!(20, b.value(1));
    1018
        }
    1019
    1020
        #[test]
    1021
        fn test_temporal_array_timestamp_minute_with_timezone() {
    1022
            let a = TimestampSecondArray::from(vec![0, 60]).with_timezone("+00:50".to_string());
    1023
            let b = date_part_primitive(&a, DatePart::Minute).unwrap();
    1024
            assert_eq!(50, b.value(0));
    1025
            assert_eq!(51, b.value(1));
    1026
        }
    1027
    1028
        #[test]
    1029
        fn test_temporal_array_timestamp_minute_with_negative_timezone() {
    1030
            let a = TimestampSecondArray::from(vec![60 * 55]).with_timezone("-00:50".to_string());
    1031
            let b = date_part_primitive(&a, DatePart::Minute).unwrap();
    1032
            assert_eq!(5, b.value(0));
    1033
        }
    1034
    1035
        #[test]
    1036
        fn test_temporal_array_timestamp_hour_with_timezone() {
    1037
            let a = TimestampSecondArray::from(vec![60 * 60 * 10]).with_timezone("+01:00".to_string());
    1038
            let b = date_part_primitive(&a, DatePart::Hour).unwrap();
    1039
            assert_eq!(11, b.value(0));
    1040
        }
    1041
    1042
        #[test]
    1043
        fn test_temporal_array_timestamp_hour_with_timezone_without_colon() {
    1044
            let a = TimestampSecondArray::from(vec![60 * 60 * 10]).with_timezone("+0100".to_string());
    1045
            let b = date_part_primitive(&a, DatePart::Hour).unwrap();
    1046
            assert_eq!(11, b.value(0));
    1047
        }
    1048
    1049
        #[test]
    1050
        fn test_temporal_array_timestamp_hour_with_timezone_without_minutes() {
    1051
            let a = TimestampSecondArray::from(vec![60 * 60 * 10]).with_timezone("+01".to_string());
    1052
            let b = date_part_primitive(&a, DatePart::Hour).unwrap();
    1053
            assert_eq!(11, b.value(0));
    1054
        }
    1055
    1056
        #[test]
    1057
        fn test_temporal_array_timestamp_hour_with_timezone_without_initial_sign() {
    1058
            let a = TimestampSecondArray::from(vec![60 * 60 * 10]).with_timezone("0100".to_string());
    1059
            let err = date_part_primitive(&a, DatePart::Hour)
    1060
                .unwrap_err()
    1061
                .to_string();
    1062
            assert!(err.contains("Invalid timezone"), "{}", err);
    1063
        }
    1064
    1065
        #[test]
    1066
        fn test_temporal_array_timestamp_hour_with_timezone_with_only_colon() {
    1067
            let a = TimestampSecondArray::from(vec![60 * 60 * 10]).with_timezone("01:00".to_string());
    1068
            let err = date_part_primitive(&a, DatePart::Hour)
    1069
                .unwrap_err()
    1070
                .to_string();
    1071
            assert!(err.contains("Invalid timezone"), "{}", err);
    1072
        }
    1073
    1074
        #[test]
    1075
        fn test_temporal_array_timestamp_week_without_timezone() {
    1076
            // 1970-01-01T00:00:00                     -> 1970-01-01T00:00:00 Thursday (week 1)
    1077
            // 1970-01-01T00:00:00 + 4 days            -> 1970-01-05T00:00:00 Monday   (week 2)
    1078
            // 1970-01-01T00:00:00 + 4 days - 1 second -> 1970-01-04T23:59:59 Sunday   (week 1)
    1079
            let a = TimestampSecondArray::from(vec![0, 86400 * 4, 86400 * 4 - 1]);
    1080
            let b = date_part_primitive(&a, DatePart::Week).unwrap();
    1081
            assert_eq!(1, b.value(0));
    1082
            assert_eq!(2, b.value(1));
    1083
            assert_eq!(1, b.value(2));
    1084
        }
    1085
    1086
        #[test]
    1087
        fn test_temporal_array_timestamp_week_with_timezone() {
    1088
            // 1970-01-01T01:00:00+01:00                     -> 1970-01-01T01:00:00+01:00 Thursday (week 1)
    1089
            // 1970-01-01T01:00:00+01:00 + 4 days            -> 1970-01-05T01:00:00+01:00 Monday   (week 2)
    1090
            // 1970-01-01T01:00:00+01:00 + 4 days - 1 second -> 1970-01-05T00:59:59+01:00 Monday   (week 2)
    1091
            let a = TimestampSecondArray::from(vec![0, 86400 * 4, 86400 * 4 - 1])
    1092
                .with_timezone("+01:00".to_string());
    1093
            let b = date_part_primitive(&a, DatePart::Week).unwrap();
    1094
            assert_eq!(1, b.value(0));
    1095
            assert_eq!(2, b.value(1));
    1096
            assert_eq!(2, b.value(2));
    1097
        }
    1098
    1099
        #[test]
    1100
        fn test_hour_minute_second_dictionary_array() {
    1101
            let a = TimestampSecondArray::from(vec![
    1102
                60 * 60 * 10 + 61,
    1103
                60 * 60 * 20 + 122,
    1104
                60 * 60 * 30 + 183,
    1105
            ])
    1106
            .with_timezone("+01:00".to_string());
    1107
    1108
            let keys = Int8Array::from_iter_values([0_i8, 0, 1, 2, 1]);
    1109
            let dict = DictionaryArray::try_new(keys.clone(), Arc::new(a)).unwrap();
    1110
    1111
            let b = date_part(&dict, DatePart::Hour).unwrap();
    1112
    1113
            let expected_dict =
    1114
                DictionaryArray::new(keys.clone(), Arc::new(Int32Array::from(vec![11, 21, 7])));
    1115
            let expected = Arc::new(expected_dict) as ArrayRef;
    1116
            assert_eq!(&expected, &b);
    1117
    1118
            let b = date_part(&dict, DatePart::Minute).unwrap();
    1119
    1120
            let b_old = date_part(&dict, DatePart::Minute).unwrap();
    1121
    1122
            let expected_dict =
    1123
                DictionaryArray::new(keys.clone(), Arc::new(Int32Array::from(vec![1, 2, 3])));
    1124
            let expected = Arc::new(expected_dict) as ArrayRef;
    1125
            assert_eq!(&expected, &b);
    1126
            assert_eq!(&expected, &b_old);
    1127
    1128
            let b = date_part(&dict, DatePart::Second).unwrap();
    1129
    1130
            let b_old = date_part(&dict, DatePart::Second).unwrap();
    1131
    1132
            let expected_dict =
    1133
                DictionaryArray::new(keys.clone(), Arc::new(Int32Array::from(vec![1, 2, 3])));
    1134
            let expected = Arc::new(expected_dict) as ArrayRef;
    1135
            assert_eq!(&expected, &b);
    1136
            assert_eq!(&expected, &b_old);
    1137
    1138
            let b = date_part(&dict, DatePart::Nanosecond).unwrap();
    1139
    1140
            let expected_dict =
    1141
                DictionaryArray::new(keys, Arc::new(Int32Array::from(vec![0, 0, 0, 0, 0])));
    1142
            let expected = Arc::new(expected_dict) as ArrayRef;
    1143
            assert_eq!(&expected, &b);
    1144
        }
    1145
    1146
        #[test]
    1147
        fn test_year_dictionary_array() {
    1148
            let a: PrimitiveArray<Date64Type> = vec![Some(1514764800000), Some(1550636625000)].into();
    1149
    1150
            let keys = Int8Array::from_iter_values([0_i8, 1, 1, 0]);
    1151
            let dict = DictionaryArray::new(keys.clone(), Arc::new(a));
    1152
    1153
            let b = date_part(&dict, DatePart::Year).unwrap();
    1154
    1155
            let expected_dict = DictionaryArray::new(
    1156
                keys,
    1157
                Arc::new(Int32Array::from(vec![2018, 2019, 2019, 2018])),
    1158
            );
    1159
            let expected = Arc::new(expected_dict) as ArrayRef;
    1160
            assert_eq!(&expected, &b);
    1161
        }
    1162
    1163
        #[test]
    1164
        fn test_quarter_month_dictionary_array() {
    1165
            //1514764800000 -> 2018-01-01
    1166
            //1566275025000 -> 2019-08-20
    1167
            let a: PrimitiveArray<Date64Type> = vec![Some(1514764800000), Some(1566275025000)].into();
    1168
    1169
            let keys = Int8Array::from_iter_values([0_i8, 1, 1, 0]);
    1170
            let dict = DictionaryArray::new(keys.clone(), Arc::new(a));
    1171
    1172
            let b = date_part(&dict, DatePart::Quarter).unwrap();
    1173
    1174
            let expected =
    1175
                DictionaryArray::new(keys.clone(), Arc::new(Int32Array::from(vec![1, 3, 3, 1])));
    1176
            assert_eq!(b.as_ref(), &expected);
    1177
    1178
            let b = date_part(&dict, DatePart::Month).unwrap();
    1179
    1180
            let expected = DictionaryArray::new(keys, Arc::new(Int32Array::from(vec![1, 8, 8, 1])));
    1181
            assert_eq!(b.as_ref(), &expected);
    1182
        }
    1183
    1184
        #[test]
    1185
        fn test_num_days_from_monday_sunday_day_doy_week_dictionary_array() {
    1186
            //1514764800000 -> 2018-01-01 (Monday)
    1187
            //1550636625000 -> 2019-02-20 (Wednesday)
    1188
            let a: PrimitiveArray<Date64Type> = vec![Some(1514764800000), Some(1550636625000)].into();
    1189
    1190
            let keys = Int8Array::from(vec![Some(0_i8), Some(1), Some(1), Some(0), None]);
    1191
            let dict = DictionaryArray::new(keys.clone(), Arc::new(a));
    1192
    1193
            let b = date_part(&dict, DatePart::DayOfWeekMonday0).unwrap();
    1194
    1195
            let a = Int32Array::from(vec![Some(0), Some(2), Some(2), Some(0), None]);
    1196
            let expected = DictionaryArray::new(keys.clone(), Arc::new(a));
    1197
            assert_eq!(b.as_ref(), &expected);
    1198
    1199
            let b = date_part(&dict, DatePart::DayOfWeekSunday0).unwrap();
    1200
    1201
            let a = Int32Array::from(vec![Some(1), Some(3), Some(3), Some(1), None]);
    1202
            let expected = DictionaryArray::new(keys.clone(), Arc::new(a));
    1203
            assert_eq!(b.as_ref(), &expected);
    1204
    1205
            let b = date_part(&dict, DatePart::Day).unwrap();
    1206
    1207
            let a = Int32Array::from(vec![Some(1), Some(20), Some(20), Some(1), None]);
    1208
            let expected = DictionaryArray::new(keys.clone(), Arc::new(a));
    1209
            assert_eq!(b.as_ref(), &expected);
    1210
    1211
            let b = date_part(&dict, DatePart::DayOfYear).unwrap();
    1212
    1213
            let a = Int32Array::from(vec![Some(1), Some(51), Some(51), Some(1), None]);
    1214
            let expected = DictionaryArray::new(keys.clone(), Arc::new(a));
    1215
            assert_eq!(b.as_ref(), &expected);
    1216
    1217
            let b = date_part(&dict, DatePart::Week).unwrap();
    1218
    1219
            let a = Int32Array::from(vec![Some(1), Some(8), Some(8), Some(1), None]);
    1220
            let expected = DictionaryArray::new(keys, Arc::new(a));
    1221
            assert_eq!(b.as_ref(), &expected);
    1222
        }
    1223
    1224
        #[test]
    1225
        fn test_temporal_array_date64_nanosecond() {
    1226
            // new Date(1667328721453)
    1227
            // Tue Nov 01 2022 11:52:01 GMT-0700 (Pacific Daylight Time)
    1228
            //
    1229
            // new Date(1667328721453).getMilliseconds()
    1230
            // 453
    1231
    1232
            let a: PrimitiveArray<Date64Type> = vec![None, Some(1667328721453)].into();
    1233
    1234
            let b = date_part_primitive(&a, DatePart::Nanosecond).unwrap();
    1235
            assert!(!b.is_valid(0));
    1236
            assert_eq!(453_000_000, b.value(1));
    1237
    1238
            let keys = Int8Array::from(vec![Some(0_i8), Some(1), Some(1)]);
    1239
            let dict = DictionaryArray::new(keys.clone(), Arc::new(a));
    1240
            let b = date_part(&dict, DatePart::Nanosecond).unwrap();
    1241
    1242
            let a = Int32Array::from(vec![None, Some(453_000_000)]);
    1243
            let expected_dict = DictionaryArray::new(keys, Arc::new(a));
    1244
            let expected = Arc::new(expected_dict) as ArrayRef;
    1245
            assert_eq!(&expected, &b);
    1246
        }
    1247
    1248
        #[test]
    1249
        fn test_temporal_array_date64_microsecond() {
    1250
            let a: PrimitiveArray<Date64Type> = vec![None, Some(1667328721453)].into();
    1251
    1252
            let b = date_part_primitive(&a, DatePart::Microsecond).unwrap();
    1253
            assert!(!b.is_valid(0));
    1254
            assert_eq!(453_000, b.value(1));
    1255
    1256
            let keys = Int8Array::from(vec![Some(0_i8), Some(1), Some(1)]);
    1257
            let dict = DictionaryArray::new(keys.clone(), Arc::new(a));
    1258
            let b = date_part(&dict, DatePart::Microsecond).unwrap();
    1259
    1260
            let a = Int32Array::from(vec![None, Some(453_000)]);
    1261
            let expected_dict = DictionaryArray::new(keys, Arc::new(a));
    1262
            let expected = Arc::new(expected_dict) as ArrayRef;
    1263
            assert_eq!(&expected, &b);
    1264
        }
    1265
    1266
        #[test]
    1267
        fn test_temporal_array_date64_millisecond() {
    1268
            let a: PrimitiveArray<Date64Type> = vec![None, Some(1667328721453)].into();
    1269
    1270
            let b = date_part_primitive(&a, DatePart::Millisecond).unwrap();
    1271
            assert!(!b.is_valid(0));
    1272
            assert_eq!(453, b.value(1));
    1273
    1274
            let keys = Int8Array::from(vec![Some(0_i8), Some(1), Some(1)]);
    1275
            let dict = DictionaryArray::new(keys.clone(), Arc::new(a));
    1276
            let b = date_part(&dict, DatePart::Millisecond).unwrap();
    1277
    1278
            let a = Int32Array::from(vec![None, Some(453)]);
    1279
            let expected_dict = DictionaryArray::new(keys, Arc::new(a));
    1280
            let expected = Arc::new(expected_dict) as ArrayRef;
    1281
            assert_eq!(&expected, &b);
    1282
        }
    1283
    1284
        #[test]
    1285
        fn test_temporal_array_time64_nanoseconds() {
    1286
            // 23:32:50.123456789
    1287
            let input: Time64NanosecondArray = vec![Some(84_770_123_456_789)].into();
    1288
    1289
            let actual = date_part(&input, DatePart::Hour).unwrap();
    1290
            let actual = actual.as_primitive::<Int32Type>();
    1291
            assert_eq!(23, actual.value(0));
    1292
    1293
            let actual = date_part(&input, DatePart::Minute).unwrap();
    1294
            let actual = actual.as_primitive::<Int32Type>();
    1295
            assert_eq!(32, actual.value(0));
    1296
    1297
            let actual = date_part(&input, DatePart::Second).unwrap();
    1298
            let actual = actual.as_primitive::<Int32Type>();
    1299
            assert_eq!(50, actual.value(0));
    1300
    1301
            let actual = date_part(&input, DatePart::Millisecond).unwrap();
    1302
            let actual = actual.as_primitive::<Int32Type>();
    1303
            assert_eq!(123, actual.value(0));
    1304
    1305
            let actual = date_part(&input, DatePart::Microsecond).unwrap();
    1306
            let actual = actual.as_primitive::<Int32Type>();
    1307
            assert_eq!(123_456, actual.value(0));
    1308
    1309
            let actual = date_part(&input, DatePart::Nanosecond).unwrap();
    1310
            let actual = actual.as_primitive::<Int32Type>();
    1311
            assert_eq!(123_456_789, actual.value(0));
    1312
    1313
            // invalid values should turn into null
    1314
            let input: Time64NanosecondArray = vec![
    1315
                Some(-1),
    1316
                Some(86_400_000_000_000),
    1317
                Some(86_401_000_000_000),
    1318
                None,
    1319
            ]
    1320
            .into();
    1321
            let actual = date_part(&input, DatePart::Hour).unwrap();
    1322
            let actual = actual.as_primitive::<Int32Type>();
    1323
            let expected: Int32Array = vec![None, None, None, None].into();
    1324
            assert_eq!(&expected, actual);
    1325
        }
    1326
    1327
        #[test]
    1328
        fn test_temporal_array_time64_microseconds() {
    1329
            // 23:32:50.123456
    1330
            let input: Time64MicrosecondArray = vec![Some(84_770_123_456)].into();
    1331
    1332
            let actual = date_part(&input, DatePart::Hour).unwrap();
    1333
            let actual = actual.as_primitive::<Int32Type>();
    1334
            assert_eq!(23, actual.value(0));
    1335
    1336
            let actual = date_part(&input, DatePart::Minute).unwrap();
    1337
            let actual = actual.as_primitive::<Int32Type>();
    1338
            assert_eq!(32, actual.value(0));
    1339
    1340
            let actual = date_part(&input, DatePart::Second).unwrap();
    1341
            let actual = actual.as_primitive::<Int32Type>();
    1342
            assert_eq!(50, actual.value(0));
    1343
    1344
            let actual = date_part(&input, DatePart::Millisecond).unwrap();
    1345
            let actual = actual.as_primitive::<Int32Type>();
    1346
            assert_eq!(123, actual.value(0));
    1347
    1348
            let actual = date_part(&input, DatePart::Microsecond).unwrap();
    1349
            let actual = actual.as_primitive::<Int32Type>();
    1350
            assert_eq!(123_456, actual.value(0));
    1351
    1352
            let actual = date_part(&input, DatePart::Nanosecond).unwrap();
    1353
            let actual = actual.as_primitive::<Int32Type>();
    1354
            assert_eq!(123_456_000, actual.value(0));
    1355
    1356
            // invalid values should turn into null
    1357
            let input: Time64MicrosecondArray =
    1358
                vec![Some(-1), Some(86_400_000_000), Some(86_401_000_000), None].into();
    1359
            let actual = date_part(&input, DatePart::Hour).unwrap();
    1360
            let actual = actual.as_primitive::<Int32Type>();
    1361
            let expected: Int32Array = vec![None, None, None, None].into();
    1362
            assert_eq!(&expected, actual);
    1363
        }
    1364
    1365
        #[test]
    1366
        fn test_temporal_array_time32_milliseconds() {
    1367
            // 23:32:50.123
    1368
            let input: Time32MillisecondArray = vec![Some(84_770_123)].into();
    1369
    1370
            let actual = date_part(&input, DatePart::Hour).unwrap();
    1371
            let actual = actual.as_primitive::<Int32Type>();
    1372
            assert_eq!(23, actual.value(0));
    1373
    1374
            let actual = date_part(&input, DatePart::Minute).unwrap();
    1375
            let actual = actual.as_primitive::<Int32Type>();
    1376
            assert_eq!(32, actual.value(0));
    1377
    1378
            let actual = date_part(&input, DatePart::Second).unwrap();
    1379
            let actual = actual.as_primitive::<Int32Type>();
    1380
            assert_eq!(50, actual.value(0));
    1381
    1382
            let actual = date_part(&input, DatePart::Millisecond).unwrap();
    1383
            let actual = actual.as_primitive::<Int32Type>();
    1384
            assert_eq!(123, actual.value(0));
    1385
    1386
            let actual = date_part(&input, DatePart::Microsecond).unwrap();
    1387
            let actual = actual.as_primitive::<Int32Type>();
    1388
            assert_eq!(123_000, actual.value(0));
    1389
    1390
            let actual = date_part(&input, DatePart::Nanosecond).unwrap();
    1391
            let actual = actual.as_primitive::<Int32Type>();
    1392
            assert_eq!(123_000_000, actual.value(0));
    1393
    1394
            // invalid values should turn into null
    1395
            let input: Time32MillisecondArray =
    1396
                vec![Some(-1), Some(86_400_000), Some(86_401_000), None].into();
    1397
            let actual = date_part(&input, DatePart::Hour).unwrap();
    1398
            let actual = actual.as_primitive::<Int32Type>();
    1399
            let expected: Int32Array = vec![None, None, None, None].into();
    1400
            assert_eq!(&expected, actual);
    1401
        }
    1402
    1403
        #[test]
    1404
        fn test_temporal_array_time32_seconds() {
    1405
            // 23:32:50
    1406
            let input: Time32SecondArray = vec![84_770].into();
    1407
    1408
            let actual = date_part(&input, DatePart::Hour).unwrap();
    1409
            let actual = actual.as_primitive::<Int32Type>();
    1410
            assert_eq!(23, actual.value(0));
    1411
    1412
            let actual = date_part(&input, DatePart::Minute).unwrap();
    1413
            let actual = actual.as_primitive::<Int32Type>();
    1414
            assert_eq!(32, actual.value(0));
    1415
    1416
            let actual = date_part(&input, DatePart::Second).unwrap();
    1417
            let actual = actual.as_primitive::<Int32Type>();
    1418
            assert_eq!(50, actual.value(0));
    1419
    1420
            let actual = date_part(&input, DatePart::Millisecond).unwrap();
    1421
            let actual = actual.as_primitive::<Int32Type>();
    1422
            assert_eq!(0, actual.value(0));
    1423
    1424
            let actual = date_part(&input, DatePart::Microsecond).unwrap();
    1425
            let actual = actual.as_primitive::<Int32Type>();
    1426
            assert_eq!(0, actual.value(0));
    1427
    1428
            let actual = date_part(&input, DatePart::Nanosecond).unwrap();
    1429
            let actual = actual.as_primitive::<Int32Type>();
    1430
            assert_eq!(0, actual.value(0));
    1431
    1432
            // invalid values should turn into null
    1433
            let input: Time32SecondArray = vec![Some(-1), Some(86_400), Some(86_401), None].into();
    1434
            let actual = date_part(&input, DatePart::Hour).unwrap();
    1435
            let actual = actual.as_primitive::<Int32Type>();
    1436
            let expected: Int32Array = vec![None, None, None, None].into();
    1437
            assert_eq!(&expected, actual);
    1438
        }
    1439
    1440
        #[test]
    1441
        fn test_temporal_array_time_invalid_parts() {
    1442
            fn ensure_returns_error(array: &dyn Array) {
    1443
                let invalid_parts = [
    1444
                    DatePart::Quarter,
    1445
                    DatePart::Year,
    1446
                    DatePart::Month,
    1447
                    DatePart::Week,
    1448
                    DatePart::Day,
    1449
                    DatePart::DayOfWeekSunday0,
    1450
                    DatePart::DayOfWeekMonday0,
    1451
                    DatePart::DayOfYear,
    1452
                ];
    1453
    1454
                for part in invalid_parts {
    1455
                    let err = date_part(array, part).unwrap_err();
    1456
                    let expected = format!(
    1457
                        "Compute error: {part} does not support: {}",
    1458
                        array.data_type()
    1459
                    );
    1460
                    assert_eq!(expected, err.to_string());
    1461
                }
    1462
            }
    1463
    1464
            ensure_returns_error(&Time32SecondArray::from(vec![0]));
    1465
            ensure_returns_error(&Time32MillisecondArray::from(vec![0]));
    1466
            ensure_returns_error(&Time64MicrosecondArray::from(vec![0]));
    1467
            ensure_returns_error(&Time64NanosecondArray::from(vec![0]));
    1468
        }
    1469
    1470
        #[test]
    1471
        fn test_interval_year_month_array() {
    1472
            let input: IntervalYearMonthArray = vec![0, 5, 24].into();
    1473
    1474
            let actual = date_part(&input, DatePart::Year).unwrap();
    1475
            let actual = actual.as_primitive::<Int32Type>();
    1476
            assert_eq!(0, actual.value(0));
    1477
            assert_eq!(0, actual.value(1));
    1478
            assert_eq!(2, actual.value(2));
    1479
    1480
            let actual = date_part(&input, DatePart::Month).unwrap();
    1481
            let actual = actual.as_primitive::<Int32Type>();
    1482
            assert_eq!(0, actual.value(0));
    1483
            assert_eq!(5, actual.value(1));
    1484
            assert_eq!(0, actual.value(2));
    1485
    1486
            assert!(date_part(&input, DatePart::Day).is_err());
    1487
            assert!(date_part(&input, DatePart::Week).is_err());
    1488
        }
    1489
    1490
        // IntervalDayTimeType week, day, hour, minute, second, milli, u, nano;
    1491
        // invalid month, year; ignores the other part
    1492
        #[test]
    1493
        fn test_interval_day_time_array() {
    1494
            let input: IntervalDayTimeArray = vec![
    1495
                IntervalDayTime::ZERO,
    1496
                IntervalDayTime::new(10, 42),   // 10d, 42ms
    1497
                IntervalDayTime::new(10, 1042), // 10d, 1s, 42ms
    1498
                IntervalDayTime::new(10, MILLISECONDS_IN_DAY as i32 + 1), // 10d, 24h, 1ms
    1499
                IntervalDayTime::new(
    1500
                    6,
    1501
                    (MILLISECONDS * 60 * 60 * 4 + MILLISECONDS * 60 * 22 + MILLISECONDS * 11 + 3)
    1502
                        as i32,
    1503
                ), // 6d, 4h, 22m, 11s, 3ms
    1504
            ]
    1505
            .into();
    1506
    1507
            // Time doesn't affect days.
    1508
            let actual = date_part(&input, DatePart::Day).unwrap();
    1509
            let actual = actual.as_primitive::<Int32Type>();
    1510
            assert_eq!(0, actual.value(0));
    1511
            assert_eq!(10, actual.value(1));
    1512
            assert_eq!(10, actual.value(2));
    1513
            assert_eq!(10, actual.value(3));
    1514
            assert_eq!(6, actual.value(4));
    1515
    1516
            let actual = date_part(&input, DatePart::Week).unwrap();
    1517
            let actual = actual.as_primitive::<Int32Type>();
    1518
            assert_eq!(0, actual.value(0));
    1519
            assert_eq!(1, actual.value(1));
    1520
            assert_eq!(1, actual.value(2));
    1521
            assert_eq!(1, actual.value(3));
    1522
            assert_eq!(0, actual.value(4));
    1523
    1524
            // Days doesn't affect time.
    1525
            let actual = date_part(&input, DatePart::Hour).unwrap();
    1526
            let actual = actual.as_primitive::<Int32Type>();
    1527
            assert_eq!(0, actual.value(0));
    1528
            assert_eq!(0, actual.value(1));
    1529
            assert_eq!(0, actual.value(2));
    1530
            assert_eq!(24, actual.value(3));
    1531
            assert_eq!(4, actual.value(4));
    1532
    1533
            let actual = date_part(&input, DatePart::Minute).unwrap();
    1534
            let actual = actual.as_primitive::<Int32Type>();
    1535
            assert_eq!(0, actual.value(0));
    1536
            assert_eq!(0, actual.value(1));
    1537
            assert_eq!(0, actual.value(2));
    1538
            assert_eq!(0, actual.value(3));
    1539
            assert_eq!(22, actual.value(4));
    1540
    1541
            let actual = date_part(&input, DatePart::Second).unwrap();
    1542
            let actual = actual.as_primitive::<Int32Type>();
    1543
            assert_eq!(0, actual.value(0));
    1544
            assert_eq!(0, actual.value(1));
    1545
            assert_eq!(1, actual.value(2));
    1546
            assert_eq!(0, actual.value(3));
    1547
            assert_eq!(11, actual.value(4));
    1548
    1549
            let actual = date_part(&input, DatePart::Millisecond).unwrap();
    1550
            let actual = actual.as_primitive::<Int32Type>();
    1551
            assert_eq!(0, actual.value(0));
    1552
            assert_eq!(42, actual.value(1));
    1553
            assert_eq!(1042, actual.value(2));
    1554
            assert_eq!(1, actual.value(3));
    1555
            assert_eq!(11003, actual.value(4));
    1556
    1557
            let actual = date_part(&input, DatePart::Microsecond).unwrap();
    1558
            let actual = actual.as_primitive::<Int32Type>();
    1559
            assert_eq!(0, actual.value(0));
    1560
            assert_eq!(42_000, actual.value(1));
    1561
            assert_eq!(1_042_000, actual.value(2));
    1562
            assert_eq!(1_000, actual.value(3));
    1563
            assert_eq!(11_003_000, actual.value(4));
    1564
    1565
            let actual = date_part(&input, DatePart::Nanosecond).unwrap();
    1566
            let actual = actual.as_primitive::<Int32Type>();
    1567
            assert_eq!(0, actual.value(0));
    1568
            assert_eq!(42_000_000, actual.value(1));
    1569
            assert_eq!(1_042_000_000, actual.value(2));
    1570
            assert_eq!(1_000_000, actual.value(3));
    1571
            // Overflow returns zero.
    1572
            assert_eq!(0, actual.value(4));
    1573
    1574
            // Month and year are not valid (since days in month varies).
    1575
            assert!(date_part(&input, DatePart::Month).is_err());
    1576
            assert!(date_part(&input, DatePart::Year).is_err());
    1577
        }
    1578
    1579
        // IntervalMonthDayNanoType year -> nano;
    1580
        // days don't affect months, time doesn't affect days, time doesn't affect months (and vice versa)
    1581
        #[test]
    1582
        fn test_interval_month_day_nano_array() {
    1583
            let input: IntervalMonthDayNanoArray = vec![
    1584
                IntervalMonthDayNano::ZERO,
    1585
                IntervalMonthDayNano::new(5, 10, 42), // 5m, 1w, 3d, 42ns
    1586
                IntervalMonthDayNano::new(16, 35, NANOSECONDS_IN_DAY + 1), // 1y, 4m, 5w, 24h, 1ns
    1587
                IntervalMonthDayNano::new(
    1588
                    0,
    1589
                    0,
    1590
                    NANOSECONDS * 60 * 60 * 4
    1591
                        + NANOSECONDS * 60 * 22
    1592
                        + NANOSECONDS * 11
    1593
                        + 1_000_000 * 33
    1594
                        + 1_000 * 44
    1595
                        + 5,
    1596
                ), // 4hr, 22m, 11s, 33ms, 44us, 5ns
    1597
            ]
    1598
            .into();
    1599
    1600
            // Year and month follow from month, but are not affected by days or nanos.
    1601
            let actual = date_part(&input, DatePart::Year).unwrap();
    1602
            let actual = actual.as_primitive::<Int32Type>();
    1603
            assert_eq!(0, actual.value(0));
    1604
            assert_eq!(0, actual.value(1));
    1605
            assert_eq!(1, actual.value(2));
    1606
            assert_eq!(0, actual.value(3));
    1607
    1608
            let actual = date_part(&input, DatePart::Month).unwrap();
    1609
            let actual = actual.as_primitive::<Int32Type>();
    1610
            assert_eq!(0, actual.value(0));
    1611
            assert_eq!(5, actual.value(1));
    1612
            assert_eq!(4, actual.value(2));
    1613
            assert_eq!(0, actual.value(3));
    1614
    1615
            // Week and day follow from day, but are not affected by months or nanos.
    1616
            let actual = date_part(&input, DatePart::Week).unwrap();
    1617
            let actual = actual.as_primitive::<Int32Type>();
    1618
            assert_eq!(0, actual.value(0));
    1619
            assert_eq!(1, actual.value(1));
    1620
            assert_eq!(5, actual.value(2));
    1621
            assert_eq!(0, actual.value(3));
    1622
    1623
            let actual = date_part(&input, DatePart::Day).unwrap();
    1624
            let actual = actual.as_primitive::<Int32Type>();
    1625
            assert_eq!(0, actual.value(0));
    1626
            assert_eq!(10, actual.value(1));
    1627
            assert_eq!(35, actual.value(2));
    1628
            assert_eq!(0, actual.value(3));
    1629
    1630
            // Times follow from nanos, but are not affected by months or days.
    1631
            let actual = date_part(&input, DatePart::Hour).unwrap();
    1632
            let actual = actual.as_primitive::<Int32Type>();
    1633
            assert_eq!(0, actual.value(0));
    1634
            assert_eq!(0, actual.value(1));
    1635
            assert_eq!(24, actual.value(2));
    1636
            assert_eq!(4, actual.value(3));
    1637
    1638
            let actual = date_part(&input, DatePart::Minute).unwrap();
    1639
            let actual = actual.as_primitive::<Int32Type>();
    1640
            assert_eq!(0, actual.value(0));
    1641
            assert_eq!(0, actual.value(1));
    1642
            assert_eq!(0, actual.value(2));
    1643
            assert_eq!(22, actual.value(3));
    1644
    1645
            let actual = date_part(&input, DatePart::Second).unwrap();
    1646
            let actual = actual.as_primitive::<Int32Type>();
    1647
            assert_eq!(0, actual.value(0));
    1648
            assert_eq!(0, actual.value(1));
    1649
            assert_eq!(0, actual.value(2));
    1650
            assert_eq!(11, actual.value(3));
    1651
    1652
            let actual = date_part(&input, DatePart::Millisecond).unwrap();
    1653
            let actual = actual.as_primitive::<Int32Type>();
    1654
            assert_eq!(0, actual.value(0));
    1655
            assert_eq!(0, actual.value(1));
    1656
            assert_eq!(0, actual.value(2));
    1657
            assert_eq!(11_033, actual.value(3));
    1658
    1659
            let actual = date_part(&input, DatePart::Microsecond).unwrap();
    1660
            let actual = actual.as_primitive::<Int32Type>();
    1661
            assert_eq!(0, actual.value(0));
    1662
            assert_eq!(0, actual.value(1));
    1663
            assert_eq!(0, actual.value(2));
    1664
            assert_eq!(11_033_044, actual.value(3));
    1665
    1666
            let actual = date_part(&input, DatePart::Nanosecond).unwrap();
    1667
            let actual = actual.as_primitive::<Int32Type>();
    1668
            assert_eq!(0, actual.value(0));
    1669
            assert_eq!(42, actual.value(1));
    1670
            assert_eq!(1, actual.value(2));
    1671
            // Overflow returns zero.
    1672
            assert_eq!(0, actual.value(3));
    1673
        }
    1674
    1675
        #[test]
    1676
        fn test_interval_array_invalid_parts() {
    1677
            fn ensure_returns_error(array: &dyn Array) {
    1678
                let invalid_parts = [
    1679
                    DatePart::Quarter,
    1680
                    DatePart::DayOfWeekSunday0,
    1681
                    DatePart::DayOfWeekMonday0,
    1682
                    DatePart::DayOfYear,
    1683
                ];
    1684
    1685
                for part in invalid_parts {
    1686
                    let err = date_part(array, part).unwrap_err();
    1687
                    let expected = format!(
    1688
                        "Compute error: {part} does not support: {}",
    1689
                        array.data_type()
    1690
                    );
    1691
                    assert_eq!(expected, err.to_string());
    1692
                }
    1693
            }
    1694
    1695
            ensure_returns_error(&IntervalYearMonthArray::from(vec![0]));
    1696
            ensure_returns_error(&IntervalDayTimeArray::from(vec![IntervalDayTime::ZERO]));
    1697
            ensure_returns_error(&IntervalMonthDayNanoArray::from(vec![
    1698
                IntervalMonthDayNano::ZERO,
    1699
            ]));
    1700
        }
    1701
    1702
        #[test]
    1703
        fn test_duration_second() {
    1704
            let input: DurationSecondArray = vec![0, 42, 60 * 60 * 24 + 1].into();
    1705
    1706
            let actual = date_part(&input, DatePart::Second).unwrap();
    1707
            let actual = actual.as_primitive::<Int32Type>();
    1708
            assert_eq!(0, actual.value(0));
    1709
            assert_eq!(42, actual.value(1));
    1710
            assert_eq!(60 * 60 * 24 + 1, actual.value(2));
    1711
    1712
            let actual = date_part(&input, DatePart::Millisecond).unwrap();
    1713
            let actual = actual.as_primitive::<Int32Type>();
    1714
            assert_eq!(0, actual.value(0));
    1715
            assert_eq!(42_000, actual.value(1));
    1716
            assert_eq!((60 * 60 * 24 + 1) * 1_000, actual.value(2));
    1717
    1718
            let actual = date_part(&input, DatePart::Microsecond).unwrap();
    1719
            let actual = actual.as_primitive::<Int32Type>();
    1720
            assert_eq!(0, actual.value(0));
    1721
            assert_eq!(42_000_000, actual.value(1));
    1722
            assert_eq!(0, actual.value(2));
    1723
    1724
            let actual = date_part(&input, DatePart::Nanosecond).unwrap();
    1725
            let actual = actual.as_primitive::<Int32Type>();
    1726
            assert_eq!(0, actual.value(0));
    1727
            assert_eq!(0, actual.value(1));
    1728
            assert_eq!(0, actual.value(2));
    1729
        }
    1730
    1731
        #[test]
    1732
        fn test_duration_millisecond() {
    1733
            let input: DurationMillisecondArray = vec![0, 42, 60 * 60 * 24 + 1].into();
    1734
    1735
            let actual = date_part(&input, DatePart::Second).unwrap();
    1736
            let actual = actual.as_primitive::<Int32Type>();
    1737
            assert_eq!(0, actual.value(0));
    1738
            assert_eq!(0, actual.value(1));
    1739
            assert_eq!((60 * 60 * 24 + 1) / 1_000, actual.value(2));
    1740
    1741
            let actual = date_part(&input, DatePart::Millisecond).unwrap();
    1742
            let actual = actual.as_primitive::<Int32Type>();
    1743
            assert_eq!(0, actual.value(0));
    1744
            assert_eq!(42, actual.value(1));
    1745
            assert_eq!(60 * 60 * 24 + 1, actual.value(2));
    1746
    1747
            let actual = date_part(&input, DatePart::Microsecond).unwrap();
    1748
            let actual = actual.as_primitive::<Int32Type>();
    1749
            assert_eq!(0, actual.value(0));
    1750
            assert_eq!(42_000, actual.value(1));
    1751
            assert_eq!((60 * 60 * 24 + 1) * 1_000, actual.value(2));
    1752
    1753
            let actual = date_part(&input, DatePart::Nanosecond).unwrap();
    1754
            let actual = actual.as_primitive::<Int32Type>();
    1755
            assert_eq!(0, actual.value(0));
    1756
            assert_eq!(42_000_000, actual.value(1));
    1757
            assert_eq!(0, actual.value(2));
    1758
        }
    1759
    1760
        #[test]
    1761
        fn test_duration_microsecond() {
    1762
            let input: DurationMicrosecondArray = vec![0, 42, 60 * 60 * 24 + 1].into();
    1763
    1764
            let actual = date_part(&input, DatePart::Second).unwrap();
    1765
            let actual = actual.as_primitive::<Int32Type>();
    1766
            assert_eq!(0, actual.value(0));
    1767
            assert_eq!(0, actual.value(1));
    1768
            assert_eq!(0, actual.value(2));
    1769
    1770
            let actual = date_part(&input, DatePart::Millisecond).unwrap();
    1771
            let actual = actual.as_primitive::<Int32Type>();
    1772
            assert_eq!(0, actual.value(0));
    1773
            assert_eq!(0, actual.value(1));
    1774
            assert_eq!((60 * 60 * 24 + 1) / 1_000, actual.value(2));
    1775
    1776
            let actual = date_part(&input, DatePart::Microsecond).unwrap();
    1777
            let actual = actual.as_primitive::<Int32Type>();
    1778
            assert_eq!(0, actual.value(0));
    1779
            assert_eq!(42, actual.value(1));
    1780
            assert_eq!(60 * 60 * 24 + 1, actual.value(2));
    1781
    1782
            let actual = date_part(&input, DatePart::Nanosecond).unwrap();
    1783
            let actual = actual.as_primitive::<Int32Type>();
    1784
            assert_eq!(0, actual.value(0));
    1785
            assert_eq!(42_000, actual.value(1));
    1786
            assert_eq!((60 * 60 * 24 + 1) * 1_000, actual.value(2));
    1787
        }
    1788
    1789
        #[test]
    1790
        fn test_duration_nanosecond() {
    1791
            let input: DurationNanosecondArray = vec![0, 42, 60 * 60 * 24 + 1].into();
    1792
    1793
            let actual = date_part(&input, DatePart::Second).unwrap();
    1794
            let actual = actual.as_primitive::<Int32Type>();
    1795
            assert_eq!(0, actual.value(0));
    1796
            assert_eq!(0, actual.value(1));
    1797
            assert_eq!(0, actual.value(2));
    1798
    1799
            let actual = date_part(&input, DatePart::Millisecond).unwrap();
    1800
            let actual = actual.as_primitive::<Int32Type>();
    1801
            assert_eq!(0, actual.value(0));
    1802
            assert_eq!(0, actual.value(1));
    1803
            assert_eq!(0, actual.value(2));
    1804
    1805
            let actual = date_part(&input, DatePart::Microsecond).unwrap();
    1806
            let actual = actual.as_primitive::<Int32Type>();
    1807
            assert_eq!(0, actual.value(0));
    1808
            assert_eq!(0, actual.value(1));
    1809
            assert_eq!((60 * 60 * 24 + 1) / 1_000, actual.value(2));
    1810
    1811
            let actual = date_part(&input, DatePart::Nanosecond).unwrap();
    1812
            let actual = actual.as_primitive::<Int32Type>();
    1813
            assert_eq!(0, actual.value(0));
    1814
            assert_eq!(42, actual.value(1));
    1815
            assert_eq!(60 * 60 * 24 + 1, actual.value(2));
    1816
        }
    1817
    1818
        #[test]
    1819
        fn test_duration_invalid_parts() {
    1820
            fn ensure_returns_error(array: &dyn Array) {
    1821
                let invalid_parts = [
    1822
                    DatePart::Year,
    1823
                    DatePart::Quarter,
    1824
                    DatePart::Month,
    1825
                    DatePart::DayOfWeekSunday0,
    1826
                    DatePart::DayOfWeekMonday0,
    1827
                    DatePart::DayOfYear,
    1828
                ];
    1829
    1830
                for part in invalid_parts {
    1831
                    let err = date_part(array, part).unwrap_err();
    1832
                    let expected = format!(
    1833
                        "Compute error: {part} does not support: {}",
    1834
                        array.data_type()
    1835
                    );
    1836
                    assert_eq!(expected, err.to_string());
    1837
                }
    1838
            }
    1839
    1840
            ensure_returns_error(&DurationSecondArray::from(vec![0]));
    1841
            ensure_returns_error(&DurationMillisecondArray::from(vec![0]));
    1842
            ensure_returns_error(&DurationMicrosecondArray::from(vec![0]));
    1843
            ensure_returns_error(&DurationNanosecondArray::from(vec![0]));
    1844
        }
    1845
    1846
        const TIMESTAMP_SECOND_1970_01_01: i64 = 0;
    1847
        const TIMESTAMP_SECOND_2018_01_01: i64 = 1_514_764_800;
    1848
        const TIMESTAMP_SECOND_2019_02_20: i64 = 1_550_636_625;
    1849
        const SECONDS_IN_DAY: i64 = 24 * 60 * 60;
    1850
        // In 2018 the ISO year and calendar year start on the same date— 2018-01-01 or 2018-W01-1
    1851
        #[test]
    1852
        fn test_temporal_array_date64_week_iso() {
    1853
            let a: PrimitiveArray<Date64Type> = vec![
    1854
                Some(TIMESTAMP_SECOND_2018_01_01 * 1000),
    1855
                Some(TIMESTAMP_SECOND_2019_02_20 * 1000),
    1856
            ]
    1857
            .into();
    1858
    1859
            let b = date_part(&a, DatePart::WeekISO).unwrap();
    1860
            let actual = b.as_primitive::<Int32Type>();
    1861
            assert_eq!(1, actual.value(0));
    1862
            assert_eq!(8, actual.value(1));
    1863
        }
    1864
    1865
        #[test]
    1866
        fn test_temporal_array_date64_year_iso() {
    1867
            let a: PrimitiveArray<Date64Type> = vec![
    1868
                Some(TIMESTAMP_SECOND_2018_01_01 * 1000),
    1869
                Some(TIMESTAMP_SECOND_2019_02_20 * 1000),
    1870
            ]
    1871
            .into();
    1872
    1873
            let b = date_part(&a, DatePart::YearISO).unwrap();
    1874
            let actual = b.as_primitive::<Int32Type>();
    1875
            assert_eq!(2018, actual.value(0));
    1876
            assert_eq!(2019, actual.value(1));
    1877
        }
    1878
    1879
        #[test]
    1880
        fn test_temporal_array_timestamp_week_iso() {
    1881
            let a = TimestampSecondArray::from(vec![
    1882
                TIMESTAMP_SECOND_1970_01_01, // 0 and is Thursday
    1883
                SECONDS_IN_DAY * 4,          //  Monday of week 2
    1884
                SECONDS_IN_DAY * 4 - 1,      // Sunday of week 1
    1885
            ]);
    1886
            let b = date_part(&a, DatePart::WeekISO).unwrap();
    1887
            let actual = b.as_primitive::<Int32Type>();
    1888
            assert_eq!(1, actual.value(0));
    1889
            assert_eq!(2, actual.value(1));
    1890
            assert_eq!(1, actual.value(2));
    1891
        }
    1892
    1893
        #[test]
    1894
        fn test_temporal_array_timestamp_year_iso() {
    1895
            let a = TimestampSecondArray::from(vec![
    1896
                TIMESTAMP_SECOND_1970_01_01,
    1897
                SECONDS_IN_DAY * 4,
    1898
                SECONDS_IN_DAY * 4 - 1,
    1899
            ]);
    1900
            let b = date_part(&a, DatePart::YearISO).unwrap();
    1901
            let actual = b.as_primitive::<Int32Type>();
    1902
            assert_eq!(1970, actual.value(0));
    1903
            assert_eq!(1970, actual.value(1));
    1904
            assert_eq!(1970, actual.value(2));
    1905
        }
    1906
    1907
        const TIMESTAMP_SECOND_2015_12_28: i64 = 1_451_260_800;
    1908
        const TIMESTAMP_SECOND_2016_01_03: i64 = 1_451_779_200;
    1909
        // January 1st 2016 is a Friday, so 2015 week 53 runs from
    1910
        // 2015-12-28 to 2016-01-03 inclusive, and
    1911
        // 2016 week 1 runs from 2016-01-04 to 2016-01-10 inclusive.
    1912
        #[test]
    1913
        fn test_temporal_array_date64_week_iso_edge_cases() {
    1914
            let a: PrimitiveArray<Date64Type> = vec![
    1915
                Some(TIMESTAMP_SECOND_2015_12_28 * 1000),
    1916
                Some(TIMESTAMP_SECOND_2016_01_03 * 1000),
    1917
                Some((TIMESTAMP_SECOND_2016_01_03 + SECONDS_IN_DAY) * 1000),
    1918
            ]
    1919
            .into();
    1920
    1921
            let b = date_part(&a, DatePart::WeekISO).unwrap();
    1922
            let actual = b.as_primitive::<Int32Type>();
    1923
            assert_eq!(53, actual.value(0));
    1924
            assert_eq!(53, actual.value(1));
    1925
            assert_eq!(1, actual.value(2));
    1926
        }
    1927
    1928
        #[test]
    1929
        fn test_temporal_array_date64_year_iso_edge_cases() {
    1930
            let a: PrimitiveArray<Date64Type> = vec![
    1931
                Some(TIMESTAMP_SECOND_2015_12_28 * 1000),
    1932
                Some(TIMESTAMP_SECOND_2016_01_03 * 1000),
    1933
                Some((TIMESTAMP_SECOND_2016_01_03 + SECONDS_IN_DAY) * 1000),
    1934
            ]
    1935
            .into();
    1936
    1937
            let b = date_part(&a, DatePart::YearISO).unwrap();
    1938
            let actual = b.as_primitive::<Int32Type>();
    1939
            assert_eq!(2015, actual.value(0));
    1940
            assert_eq!(2015, actual.value(1));
    1941
            assert_eq!(2016, actual.value(2));
    1942
        }
    1943
    1944
        #[test]
    1945
        fn test_temporal_array_timestamp_week_iso_edge_cases() {
    1946
            let a = TimestampSecondArray::from(vec![
    1947
                TIMESTAMP_SECOND_2015_12_28,
    1948
                TIMESTAMP_SECOND_2016_01_03,
    1949
                TIMESTAMP_SECOND_2016_01_03 + SECONDS_IN_DAY,
    1950
            ]);
    1951
            let b = date_part(&a, DatePart::WeekISO).unwrap();
    1952
            let actual = b.as_primitive::<Int32Type>();
    1953
            assert_eq!(53, actual.value(0));
    1954
            assert_eq!(53, actual.value(1));
    1955
            assert_eq!(1, actual.value(2));
    1956
        }
    1957
    1958
        #[test]
    1959
        fn test_temporal_array_timestamp_year_iso_edge_cases() {
    1960
            let a = TimestampSecondArray::from(vec![
    1961
                TIMESTAMP_SECOND_2015_12_28,
    1962
                TIMESTAMP_SECOND_2016_01_03,
    1963
                TIMESTAMP_SECOND_2016_01_03 + SECONDS_IN_DAY,
    1964
            ]);
    1965
            let b = date_part(&a, DatePart::YearISO).unwrap();
    1966
            let actual = b.as_primitive::<Int32Type>();
    1967
            assert_eq!(2015, actual.value(0));
    1968
            assert_eq!(2015, actual.value(1));
    1969
            assert_eq!(2016, actual.value(2));
    1970
        }
    1971
    }