1use std::sync::Arc;
21
22use arrow_array::cast::AsArray;
23use cast::as_primitive_array;
24use chrono::{Datelike, NaiveDateTime, Offset, TimeZone, Timelike, Utc};
25
26use 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};
31use arrow_array::timezone::Tz;
32use arrow_array::types::*;
33use arrow_array::*;
34use arrow_buffer::ArrowNativeType;
35use arrow_schema::{ArrowError, DataType, IntervalUnit, TimeUnit};
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq)]
44#[non_exhaustive]
45pub enum DatePart {
46 Quarter,
48 Year,
50 Month,
52 Week,
54 Day,
56 DayOfWeekSunday0,
58 DayOfWeekMonday0,
60 DayOfYear,
62 Hour,
64 Minute,
66 Second,
68 Millisecond,
70 Microsecond,
72 Nanosecond,
74}
75
76impl std::fmt::Display for DatePart {
77 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78 write!(f, "{:?}", self)
79 }
80}
81
82fn get_date_time_part_extract_fn<T>(part: DatePart) -> fn(T) -> i32
87where
88 T: ChronoDateExt + Datelike + Timelike,
89{
90 match part {
91 DatePart::Quarter => |d| d.quarter() as i32,
92 DatePart::Year => |d| d.year(),
93 DatePart::Month => |d| d.month() as i32,
94 DatePart::Week => |d| d.iso_week().week() as i32,
95 DatePart::Day => |d| d.day() as i32,
96 DatePart::DayOfWeekSunday0 => |d| d.num_days_from_sunday(),
97 DatePart::DayOfWeekMonday0 => |d| d.num_days_from_monday(),
98 DatePart::DayOfYear => |d| d.ordinal() as i32,
99 DatePart::Hour => |d| d.hour() as i32,
100 DatePart::Minute => |d| d.minute() as i32,
101 DatePart::Second => |d| d.second() as i32,
102 DatePart::Millisecond => |d| (d.nanosecond() / 1_000_000) as i32,
103 DatePart::Microsecond => |d| (d.nanosecond() / 1_000) as i32,
104 DatePart::Nanosecond => |d| (d.nanosecond()) as i32,
105 }
106}
107
108pub fn date_part(array: &dyn Array, part: DatePart) -> Result<ArrayRef, ArrowError> {
137 downcast_temporal_array!(
138 array => {
139 let array = array.date_part(part)?;
140 let array = Arc::new(array) as ArrayRef;
141 Ok(array)
142 }
143 DataType::Interval(IntervalUnit::YearMonth) => {
144 let array = as_primitive_array::<IntervalYearMonthType>(array).date_part(part)?;
145 let array = Arc::new(array) as ArrayRef;
146 Ok(array)
147 }
148 DataType::Interval(IntervalUnit::DayTime) => {
149 let array = as_primitive_array::<IntervalDayTimeType>(array).date_part(part)?;
150 let array = Arc::new(array) as ArrayRef;
151 Ok(array)
152 }
153 DataType::Interval(IntervalUnit::MonthDayNano) => {
154 let array = as_primitive_array::<IntervalMonthDayNanoType>(array).date_part(part)?;
155 let array = Arc::new(array) as ArrayRef;
156 Ok(array)
157 }
158 DataType::Duration(TimeUnit::Second) => {
159 let array = as_primitive_array::<DurationSecondType>(array).date_part(part)?;
160 let array = Arc::new(array) as ArrayRef;
161 Ok(array)
162 }
163 DataType::Duration(TimeUnit::Millisecond) => {
164 let array = as_primitive_array::<DurationMillisecondType>(array).date_part(part)?;
165 let array = Arc::new(array) as ArrayRef;
166 Ok(array)
167 }
168 DataType::Duration(TimeUnit::Microsecond) => {
169 let array = as_primitive_array::<DurationMicrosecondType>(array).date_part(part)?;
170 let array = Arc::new(array) as ArrayRef;
171 Ok(array)
172 }
173 DataType::Duration(TimeUnit::Nanosecond) => {
174 let array = as_primitive_array::<DurationNanosecondType>(array).date_part(part)?;
175 let array = Arc::new(array) as ArrayRef;
176 Ok(array)
177 }
178 DataType::Dictionary(_, _) => {
179 let array = array.as_any_dictionary();
180 let values = date_part(array.values(), part)?;
181 let values = Arc::new(values) as ArrayRef;
182 let new_array = array.with_values(values);
183 Ok(new_array)
184 }
185 t => return_compute_error_with!(format!("{part} does not support"), t),
186 )
187}
188
189fn date_part_primitive<T: ArrowTemporalType>(
192 array: &PrimitiveArray<T>,
193 part: DatePart,
194) -> Result<Int32Array, ArrowError> {
195 let array = date_part(array, part)?;
196 Ok(array.as_primitive::<Int32Type>().to_owned())
197}
198
199fn get_tz(dt: &DataType) -> Result<Option<Tz>, ArrowError> {
202 match dt {
203 DataType::Timestamp(_, Some(tz)) => Ok(Some(tz.parse::<Tz>()?)),
204 DataType::Timestamp(_, None) => Ok(None),
205 _ => Err(ArrowError::CastError(format!("Not a timestamp type: {dt}"))),
206 }
207}
208
209trait ExtractDatePartExt {
211 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError>;
212}
213
214impl ExtractDatePartExt for PrimitiveArray<Time32SecondType> {
215 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
216 #[inline]
217 fn range_check(s: i32) -> bool {
218 (0..SECONDS_IN_DAY as i32).contains(&s)
219 }
220 match part {
221 DatePart::Hour => Ok(self.unary_opt(|s| range_check(s).then_some(s / 3_600))),
222 DatePart::Minute => Ok(self.unary_opt(|s| range_check(s).then_some((s / 60) % 60))),
223 DatePart::Second => Ok(self.unary_opt(|s| range_check(s).then_some(s % 60))),
224 DatePart::Millisecond | DatePart::Microsecond | DatePart::Nanosecond => {
226 Ok(self.unary_opt(|s| range_check(s).then_some(0)))
227 }
228 _ => return_compute_error_with!(format!("{part} does not support"), self.data_type()),
229 }
230 }
231}
232
233impl ExtractDatePartExt for PrimitiveArray<Time32MillisecondType> {
234 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
235 #[inline]
236 fn range_check(ms: i32) -> bool {
237 (0..MILLISECONDS_IN_DAY as i32).contains(&ms)
238 }
239 let milliseconds = MILLISECONDS as i32;
240 match part {
241 DatePart::Hour => {
242 Ok(self.unary_opt(|ms| range_check(ms).then_some(ms / 3_600 / milliseconds)))
243 }
244 DatePart::Minute => {
245 Ok(self.unary_opt(|ms| range_check(ms).then_some((ms / 60 / milliseconds) % 60)))
246 }
247 DatePart::Second => {
248 Ok(self.unary_opt(|ms| range_check(ms).then_some((ms / milliseconds) % 60)))
249 }
250 DatePart::Millisecond => {
251 Ok(self.unary_opt(|ms| range_check(ms).then_some(ms % milliseconds)))
252 }
253 DatePart::Microsecond => {
254 Ok(self.unary_opt(|ms| range_check(ms).then_some((ms % milliseconds) * 1_000)))
255 }
256 DatePart::Nanosecond => {
257 Ok(self.unary_opt(|ms| range_check(ms).then_some((ms % milliseconds) * 1_000_000)))
258 }
259 _ => return_compute_error_with!(format!("{part} does not support"), self.data_type()),
260 }
261 }
262}
263
264impl ExtractDatePartExt for PrimitiveArray<Time64MicrosecondType> {
265 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
266 #[inline]
267 fn range_check(us: i64) -> bool {
268 (0..MICROSECONDS_IN_DAY).contains(&us)
269 }
270 match part {
271 DatePart::Hour => {
272 Ok(self
273 .unary_opt(|us| range_check(us).then_some((us / 3_600 / MICROSECONDS) as i32)))
274 }
275 DatePart::Minute => Ok(self
276 .unary_opt(|us| range_check(us).then_some(((us / 60 / MICROSECONDS) % 60) as i32))),
277 DatePart::Second => {
278 Ok(self
279 .unary_opt(|us| range_check(us).then_some(((us / MICROSECONDS) % 60) as i32)))
280 }
281 DatePart::Millisecond => Ok(self
282 .unary_opt(|us| range_check(us).then_some(((us % MICROSECONDS) / 1_000) as i32))),
283 DatePart::Microsecond => {
284 Ok(self.unary_opt(|us| range_check(us).then_some((us % MICROSECONDS) as i32)))
285 }
286 DatePart::Nanosecond => Ok(self
287 .unary_opt(|us| range_check(us).then_some(((us % MICROSECONDS) * 1_000) as i32))),
288 _ => return_compute_error_with!(format!("{part} does not support"), self.data_type()),
289 }
290 }
291}
292
293impl ExtractDatePartExt for PrimitiveArray<Time64NanosecondType> {
294 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
295 #[inline]
296 fn range_check(ns: i64) -> bool {
297 (0..NANOSECONDS_IN_DAY).contains(&ns)
298 }
299 match part {
300 DatePart::Hour => {
301 Ok(self
302 .unary_opt(|ns| range_check(ns).then_some((ns / 3_600 / NANOSECONDS) as i32)))
303 }
304 DatePart::Minute => Ok(self
305 .unary_opt(|ns| range_check(ns).then_some(((ns / 60 / NANOSECONDS) % 60) as i32))),
306 DatePart::Second => Ok(
307 self.unary_opt(|ns| range_check(ns).then_some(((ns / NANOSECONDS) % 60) as i32))
308 ),
309 DatePart::Millisecond => Ok(self.unary_opt(|ns| {
310 range_check(ns).then_some(((ns % NANOSECONDS) / 1_000_000) as i32)
311 })),
312 DatePart::Microsecond => {
313 Ok(self
314 .unary_opt(|ns| range_check(ns).then_some(((ns % NANOSECONDS) / 1_000) as i32)))
315 }
316 DatePart::Nanosecond => {
317 Ok(self.unary_opt(|ns| range_check(ns).then_some((ns % NANOSECONDS) as i32)))
318 }
319 _ => return_compute_error_with!(format!("{part} does not support"), self.data_type()),
320 }
321 }
322}
323
324impl ExtractDatePartExt for PrimitiveArray<Date32Type> {
325 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
326 if let DatePart::Hour
328 | DatePart::Minute
329 | DatePart::Second
330 | DatePart::Millisecond
331 | DatePart::Microsecond
332 | DatePart::Nanosecond = part
333 {
334 Ok(Int32Array::new(
335 vec![0; self.len()].into(),
336 self.nulls().cloned(),
337 ))
338 } else {
339 let map_func = get_date_time_part_extract_fn(part);
340 Ok(self.unary_opt(|d| date32_to_datetime(d).map(map_func)))
341 }
342 }
343}
344
345impl ExtractDatePartExt for PrimitiveArray<Date64Type> {
346 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
347 let map_func = get_date_time_part_extract_fn(part);
348 Ok(self.unary_opt(|d| date64_to_datetime(d).map(map_func)))
349 }
350}
351
352impl ExtractDatePartExt for PrimitiveArray<TimestampSecondType> {
353 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
354 let array =
356 if let DatePart::Millisecond | DatePart::Microsecond | DatePart::Nanosecond = part {
357 Int32Array::new(vec![0; self.len()].into(), self.nulls().cloned())
358 } else if let Some(tz) = get_tz(self.data_type())? {
359 let map_func = get_date_time_part_extract_fn(part);
360 self.unary_opt(|d| {
361 timestamp_s_to_datetime(d)
362 .map(|c| Utc.from_utc_datetime(&c).with_timezone(&tz))
363 .map(map_func)
364 })
365 } else {
366 let map_func = get_date_time_part_extract_fn(part);
367 self.unary_opt(|d| timestamp_s_to_datetime(d).map(map_func))
368 };
369 Ok(array)
370 }
371}
372
373impl ExtractDatePartExt for PrimitiveArray<TimestampMillisecondType> {
374 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
375 let array = if let Some(tz) = get_tz(self.data_type())? {
376 let map_func = get_date_time_part_extract_fn(part);
377 self.unary_opt(|d| {
378 timestamp_ms_to_datetime(d)
379 .map(|c| Utc.from_utc_datetime(&c).with_timezone(&tz))
380 .map(map_func)
381 })
382 } else {
383 let map_func = get_date_time_part_extract_fn(part);
384 self.unary_opt(|d| timestamp_ms_to_datetime(d).map(map_func))
385 };
386 Ok(array)
387 }
388}
389
390impl ExtractDatePartExt for PrimitiveArray<TimestampMicrosecondType> {
391 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
392 let array = if let Some(tz) = get_tz(self.data_type())? {
393 let map_func = get_date_time_part_extract_fn(part);
394 self.unary_opt(|d| {
395 timestamp_us_to_datetime(d)
396 .map(|c| Utc.from_utc_datetime(&c).with_timezone(&tz))
397 .map(map_func)
398 })
399 } else {
400 let map_func = get_date_time_part_extract_fn(part);
401 self.unary_opt(|d| timestamp_us_to_datetime(d).map(map_func))
402 };
403 Ok(array)
404 }
405}
406
407impl ExtractDatePartExt for PrimitiveArray<TimestampNanosecondType> {
408 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
409 let array = if let Some(tz) = get_tz(self.data_type())? {
410 let map_func = get_date_time_part_extract_fn(part);
411 self.unary_opt(|d| {
412 timestamp_ns_to_datetime(d)
413 .map(|c| Utc.from_utc_datetime(&c).with_timezone(&tz))
414 .map(map_func)
415 })
416 } else {
417 let map_func = get_date_time_part_extract_fn(part);
418 self.unary_opt(|d| timestamp_ns_to_datetime(d).map(map_func))
419 };
420 Ok(array)
421 }
422}
423
424impl ExtractDatePartExt for PrimitiveArray<IntervalYearMonthType> {
425 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
426 match part {
427 DatePart::Year => Ok(self.unary_opt(|d| Some(d / 12))),
428 DatePart::Month => Ok(self.unary_opt(|d| Some(d % 12))),
429
430 DatePart::Quarter
431 | DatePart::Week
432 | DatePart::Day
433 | DatePart::DayOfWeekSunday0
434 | DatePart::DayOfWeekMonday0
435 | DatePart::DayOfYear
436 | DatePart::Hour
437 | DatePart::Minute
438 | DatePart::Second
439 | DatePart::Millisecond
440 | DatePart::Microsecond
441 | DatePart::Nanosecond => {
442 return_compute_error_with!(format!("{part} does not support"), self.data_type())
443 }
444 }
445 }
446}
447
448impl ExtractDatePartExt for PrimitiveArray<IntervalDayTimeType> {
449 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
450 match part {
451 DatePart::Week => Ok(self.unary_opt(|d| Some(d.days / 7))),
452 DatePart::Day => Ok(self.unary_opt(|d| Some(d.days))),
453 DatePart::Hour => Ok(self.unary_opt(|d| Some(d.milliseconds / (60 * 60 * 1_000)))),
454 DatePart::Minute => Ok(self.unary_opt(|d| Some(d.milliseconds / (60 * 1_000)))),
455 DatePart::Second => Ok(self.unary_opt(|d| Some(d.milliseconds / 1_000))),
456 DatePart::Millisecond => Ok(self.unary_opt(|d| Some(d.milliseconds))),
457 DatePart::Microsecond => Ok(self.unary_opt(|d| d.milliseconds.checked_mul(1_000))),
458 DatePart::Nanosecond => Ok(self.unary_opt(|d| d.milliseconds.checked_mul(1_000_000))),
459
460 DatePart::Quarter
461 | DatePart::Year
462 | DatePart::Month
463 | DatePart::DayOfWeekSunday0
464 | DatePart::DayOfWeekMonday0
465 | DatePart::DayOfYear => {
466 return_compute_error_with!(format!("{part} does not support"), self.data_type())
467 }
468 }
469 }
470}
471
472impl ExtractDatePartExt for PrimitiveArray<IntervalMonthDayNanoType> {
473 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
474 match part {
475 DatePart::Year => Ok(self.unary_opt(|d: IntervalMonthDayNano| Some(d.months / 12))),
476 DatePart::Month => Ok(self.unary_opt(|d: IntervalMonthDayNano| Some(d.months))),
477 DatePart::Week => Ok(self.unary_opt(|d: IntervalMonthDayNano| Some(d.days / 7))),
478 DatePart::Day => Ok(self.unary_opt(|d: IntervalMonthDayNano| Some(d.days))),
479 DatePart::Hour => {
480 Ok(self.unary_opt(|d| (d.nanoseconds / (60 * 60 * 1_000_000_000)).try_into().ok()))
481 }
482 DatePart::Minute => {
483 Ok(self.unary_opt(|d| (d.nanoseconds / (60 * 1_000_000_000)).try_into().ok()))
484 }
485 DatePart::Second => {
486 Ok(self.unary_opt(|d| (d.nanoseconds / 1_000_000_000).try_into().ok()))
487 }
488 DatePart::Millisecond => {
489 Ok(self.unary_opt(|d| (d.nanoseconds / 1_000_000).try_into().ok()))
490 }
491 DatePart::Microsecond => {
492 Ok(self.unary_opt(|d| (d.nanoseconds / 1_000).try_into().ok()))
493 }
494 DatePart::Nanosecond => Ok(self.unary_opt(|d| d.nanoseconds.try_into().ok())),
495
496 DatePart::Quarter
497 | DatePart::DayOfWeekSunday0
498 | DatePart::DayOfWeekMonday0
499 | DatePart::DayOfYear => {
500 return_compute_error_with!(format!("{part} does not support"), self.data_type())
501 }
502 }
503 }
504}
505
506impl ExtractDatePartExt for PrimitiveArray<DurationSecondType> {
507 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
508 match part {
509 DatePart::Week => Ok(self.unary_opt(|d| (d / (60 * 60 * 24 * 7)).try_into().ok())),
510 DatePart::Day => Ok(self.unary_opt(|d| (d / (60 * 60 * 24)).try_into().ok())),
511 DatePart::Hour => Ok(self.unary_opt(|d| (d / (60 * 60)).try_into().ok())),
512 DatePart::Minute => Ok(self.unary_opt(|d| (d / 60).try_into().ok())),
513 DatePart::Second => Ok(self.unary_opt(|d| d.try_into().ok())),
514 DatePart::Millisecond => {
515 Ok(self.unary_opt(|d| d.checked_mul(1_000).and_then(|d| d.try_into().ok())))
516 }
517 DatePart::Microsecond => {
518 Ok(self.unary_opt(|d| d.checked_mul(1_000_000).and_then(|d| d.try_into().ok())))
519 }
520 DatePart::Nanosecond => Ok(
521 self.unary_opt(|d| d.checked_mul(1_000_000_000).and_then(|d| d.try_into().ok()))
522 ),
523
524 DatePart::Year
525 | DatePart::Quarter
526 | DatePart::Month
527 | DatePart::DayOfWeekSunday0
528 | DatePart::DayOfWeekMonday0
529 | DatePart::DayOfYear => {
530 return_compute_error_with!(format!("{part} does not support"), self.data_type())
531 }
532 }
533 }
534}
535
536impl ExtractDatePartExt for PrimitiveArray<DurationMillisecondType> {
537 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
538 match part {
539 DatePart::Week => {
540 Ok(self.unary_opt(|d| (d / (1_000 * 60 * 60 * 24 * 7)).try_into().ok()))
541 }
542 DatePart::Day => Ok(self.unary_opt(|d| (d / (1_000 * 60 * 60 * 24)).try_into().ok())),
543 DatePart::Hour => Ok(self.unary_opt(|d| (d / (1_000 * 60 * 60)).try_into().ok())),
544 DatePart::Minute => Ok(self.unary_opt(|d| (d / (1_000 * 60)).try_into().ok())),
545 DatePart::Second => Ok(self.unary_opt(|d| (d / 1_000).try_into().ok())),
546 DatePart::Millisecond => Ok(self.unary_opt(|d| d.try_into().ok())),
547 DatePart::Microsecond => {
548 Ok(self.unary_opt(|d| d.checked_mul(1_000).and_then(|d| d.try_into().ok())))
549 }
550 DatePart::Nanosecond => {
551 Ok(self.unary_opt(|d| d.checked_mul(1_000_000).and_then(|d| d.try_into().ok())))
552 }
553
554 DatePart::Year
555 | DatePart::Quarter
556 | DatePart::Month
557 | DatePart::DayOfWeekSunday0
558 | DatePart::DayOfWeekMonday0
559 | DatePart::DayOfYear => {
560 return_compute_error_with!(format!("{part} does not support"), self.data_type())
561 }
562 }
563 }
564}
565
566impl ExtractDatePartExt for PrimitiveArray<DurationMicrosecondType> {
567 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
568 match part {
569 DatePart::Week => {
570 Ok(self.unary_opt(|d| (d / (1_000_000 * 60 * 60 * 24 * 7)).try_into().ok()))
571 }
572 DatePart::Day => {
573 Ok(self.unary_opt(|d| (d / (1_000_000 * 60 * 60 * 24)).try_into().ok()))
574 }
575 DatePart::Hour => Ok(self.unary_opt(|d| (d / (1_000_000 * 60 * 60)).try_into().ok())),
576 DatePart::Minute => Ok(self.unary_opt(|d| (d / (1_000_000 * 60)).try_into().ok())),
577 DatePart::Second => Ok(self.unary_opt(|d| (d / 1_000_000).try_into().ok())),
578 DatePart::Millisecond => Ok(self.unary_opt(|d| (d / 1_000).try_into().ok())),
579 DatePart::Microsecond => Ok(self.unary_opt(|d| d.try_into().ok())),
580 DatePart::Nanosecond => {
581 Ok(self.unary_opt(|d| d.checked_mul(1_000).and_then(|d| d.try_into().ok())))
582 }
583
584 DatePart::Year
585 | DatePart::Quarter
586 | DatePart::Month
587 | DatePart::DayOfWeekSunday0
588 | DatePart::DayOfWeekMonday0
589 | DatePart::DayOfYear => {
590 return_compute_error_with!(format!("{part} does not support"), self.data_type())
591 }
592 }
593 }
594}
595
596impl ExtractDatePartExt for PrimitiveArray<DurationNanosecondType> {
597 fn date_part(&self, part: DatePart) -> Result<Int32Array, ArrowError> {
598 match part {
599 DatePart::Week => {
600 Ok(self.unary_opt(|d| (d / (1_000_000_000 * 60 * 60 * 24 * 7)).try_into().ok()))
601 }
602 DatePart::Day => {
603 Ok(self.unary_opt(|d| (d / (1_000_000_000 * 60 * 60 * 24)).try_into().ok()))
604 }
605 DatePart::Hour => {
606 Ok(self.unary_opt(|d| (d / (1_000_000_000 * 60 * 60)).try_into().ok()))
607 }
608 DatePart::Minute => Ok(self.unary_opt(|d| (d / (1_000_000_000 * 60)).try_into().ok())),
609 DatePart::Second => Ok(self.unary_opt(|d| (d / 1_000_000_000).try_into().ok())),
610 DatePart::Millisecond => Ok(self.unary_opt(|d| (d / 1_000_000).try_into().ok())),
611 DatePart::Microsecond => Ok(self.unary_opt(|d| (d / 1_000).try_into().ok())),
612 DatePart::Nanosecond => Ok(self.unary_opt(|d| d.try_into().ok())),
613
614 DatePart::Year
615 | DatePart::Quarter
616 | DatePart::Month
617 | DatePart::DayOfWeekSunday0
618 | DatePart::DayOfWeekMonday0
619 | DatePart::DayOfYear => {
620 return_compute_error_with!(format!("{part} does not support"), self.data_type())
621 }
622 }
623 }
624}
625
626macro_rules! return_compute_error_with {
627 ($msg:expr, $param:expr) => {
628 return { Err(ArrowError::ComputeError(format!("{}: {:?}", $msg, $param))) }
629 };
630}
631
632pub(crate) use return_compute_error_with;
633
634trait ChronoDateExt {
636 fn quarter(&self) -> u32;
638
639 fn quarter0(&self) -> u32;
641
642 fn num_days_from_monday(&self) -> i32;
644
645 fn num_days_from_sunday(&self) -> i32;
647}
648
649impl<T: Datelike> ChronoDateExt for T {
650 fn quarter(&self) -> u32 {
651 self.quarter0() + 1
652 }
653
654 fn quarter0(&self) -> u32 {
655 self.month0() / 3
656 }
657
658 fn num_days_from_monday(&self) -> i32 {
659 self.weekday().num_days_from_monday() as i32
660 }
661
662 fn num_days_from_sunday(&self) -> i32 {
663 self.weekday().num_days_from_sunday() as i32
664 }
665}
666
667#[deprecated(note = "Use arrow_array::timezone::Tz instead")]
673pub fn using_chrono_tz_and_utc_naive_date_time(
674 tz: &str,
675 utc: NaiveDateTime,
676) -> Option<chrono::offset::FixedOffset> {
677 let tz: Tz = tz.parse().ok()?;
678 Some(tz.offset_from_utc_datetime(&utc).fix())
679}
680
681#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
685pub fn hour_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
686 date_part(array, DatePart::Hour)
687}
688
689#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
692pub fn hour<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
693where
694 T: ArrowTemporalType + ArrowNumericType,
695 i64: From<T::Native>,
696{
697 date_part_primitive(array, DatePart::Hour)
698}
699
700#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
704pub fn year_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
705 date_part(array, DatePart::Year)
706}
707
708#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
710pub fn year<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
711where
712 T: ArrowTemporalType + ArrowNumericType,
713 i64: From<T::Native>,
714{
715 date_part_primitive(array, DatePart::Year)
716}
717
718#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
722pub fn quarter_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
723 date_part(array, DatePart::Quarter)
724}
725
726#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
729pub fn quarter<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
730where
731 T: ArrowTemporalType + ArrowNumericType,
732 i64: From<T::Native>,
733{
734 date_part_primitive(array, DatePart::Quarter)
735}
736
737#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
741pub fn month_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
742 date_part(array, DatePart::Month)
743}
744
745#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
748pub fn month<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
749where
750 T: ArrowTemporalType + ArrowNumericType,
751 i64: From<T::Native>,
752{
753 date_part_primitive(array, DatePart::Month)
754}
755
756#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
766pub fn num_days_from_monday_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
767 date_part(array, DatePart::DayOfWeekMonday0)
768}
769
770#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
777pub fn num_days_from_monday<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
778where
779 T: ArrowTemporalType + ArrowNumericType,
780 i64: From<T::Native>,
781{
782 date_part_primitive(array, DatePart::DayOfWeekMonday0)
783}
784
785#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
795pub fn num_days_from_sunday_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
796 date_part(array, DatePart::DayOfWeekSunday0)
797}
798
799#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
806pub fn num_days_from_sunday<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
807where
808 T: ArrowTemporalType + ArrowNumericType,
809 i64: From<T::Native>,
810{
811 date_part_primitive(array, DatePart::DayOfWeekSunday0)
812}
813
814#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
819pub fn day_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
820 date_part(array, DatePart::Day)
821}
822
823#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
825pub fn day<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
826where
827 T: ArrowTemporalType + ArrowNumericType,
828 i64: From<T::Native>,
829{
830 date_part_primitive(array, DatePart::Day)
831}
832
833#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
839pub fn doy_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
840 date_part(array, DatePart::DayOfYear)
841}
842
843#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
847pub fn doy<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
848where
849 T: ArrowTemporalType + ArrowNumericType,
850 T::Native: ArrowNativeType,
851 i64: From<T::Native>,
852{
853 date_part_primitive(array, DatePart::DayOfYear)
854}
855
856#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
858pub fn minute<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
859where
860 T: ArrowTemporalType + ArrowNumericType,
861 i64: From<T::Native>,
862{
863 date_part_primitive(array, DatePart::Minute)
864}
865
866#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
870pub fn week_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
871 date_part(array, DatePart::Week)
872}
873
874#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
876pub fn week<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
877where
878 T: ArrowTemporalType + ArrowNumericType,
879 i64: From<T::Native>,
880{
881 date_part_primitive(array, DatePart::Week)
882}
883
884#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
886pub fn second<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
887where
888 T: ArrowTemporalType + ArrowNumericType,
889 i64: From<T::Native>,
890{
891 date_part_primitive(array, DatePart::Second)
892}
893
894#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
896pub fn nanosecond<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
897where
898 T: ArrowTemporalType + ArrowNumericType,
899 i64: From<T::Native>,
900{
901 date_part_primitive(array, DatePart::Nanosecond)
902}
903
904#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
908pub fn nanosecond_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
909 date_part(array, DatePart::Nanosecond)
910}
911
912#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
914pub fn microsecond<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
915where
916 T: ArrowTemporalType + ArrowNumericType,
917 i64: From<T::Native>,
918{
919 date_part_primitive(array, DatePart::Microsecond)
920}
921
922#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
926pub fn microsecond_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
927 date_part(array, DatePart::Microsecond)
928}
929
930#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
932pub fn millisecond<T>(array: &PrimitiveArray<T>) -> Result<Int32Array, ArrowError>
933where
934 T: ArrowTemporalType + ArrowNumericType,
935 i64: From<T::Native>,
936{
937 date_part_primitive(array, DatePart::Millisecond)
938}
939
940#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
944pub fn millisecond_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
945 date_part(array, DatePart::Millisecond)
946}
947
948#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
952pub fn minute_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
953 date_part(array, DatePart::Minute)
954}
955
956#[deprecated(since = "51.0.0", note = "Use `date_part` instead")]
960pub fn second_dyn(array: &dyn Array) -> Result<ArrayRef, ArrowError> {
961 date_part(array, DatePart::Second)
962}
963
964#[cfg(test)]
965#[allow(deprecated)]
966mod tests {
967 use super::*;
968
969 #[test]
970 fn test_temporal_array_date64_hour() {
971 let a: PrimitiveArray<Date64Type> =
972 vec![Some(1514764800000), None, Some(1550636625000)].into();
973
974 let b = hour(&a).unwrap();
975 assert_eq!(0, b.value(0));
976 assert!(!b.is_valid(1));
977 assert_eq!(4, b.value(2));
978 }
979
980 #[test]
981 fn test_temporal_array_date32_hour() {
982 let a: PrimitiveArray<Date32Type> = vec![Some(15147), None, Some(15148)].into();
983
984 let b = hour(&a).unwrap();
985 assert_eq!(0, b.value(0));
986 assert!(!b.is_valid(1));
987 assert_eq!(0, b.value(2));
988 }
989
990 #[test]
991 fn test_temporal_array_time32_second_hour() {
992 let a: PrimitiveArray<Time32SecondType> = vec![37800, 86339].into();
993
994 let b = hour(&a).unwrap();
995 assert_eq!(10, b.value(0));
996 assert_eq!(23, b.value(1));
997 }
998
999 #[test]
1000 fn test_temporal_array_time64_micro_hour() {
1001 let a: PrimitiveArray<Time64MicrosecondType> = vec![37800000000, 86339000000].into();
1002
1003 let b = hour(&a).unwrap();
1004 assert_eq!(10, b.value(0));
1005 assert_eq!(23, b.value(1));
1006 }
1007
1008 #[test]
1009 fn test_temporal_array_timestamp_micro_hour() {
1010 let a: TimestampMicrosecondArray = vec![37800000000, 86339000000].into();
1011
1012 let b = hour(&a).unwrap();
1013 assert_eq!(10, b.value(0));
1014 assert_eq!(23, b.value(1));
1015 }
1016
1017 #[test]
1018 fn test_temporal_array_date64_year() {
1019 let a: PrimitiveArray<Date64Type> =
1020 vec![Some(1514764800000), None, Some(1550636625000)].into();
1021
1022 let b = year(&a).unwrap();
1023 assert_eq!(2018, b.value(0));
1024 assert!(!b.is_valid(1));
1025 assert_eq!(2019, b.value(2));
1026 }
1027
1028 #[test]
1029 fn test_temporal_array_date32_year() {
1030 let a: PrimitiveArray<Date32Type> = vec![Some(15147), None, Some(15448)].into();
1031
1032 let b = year(&a).unwrap();
1033 assert_eq!(2011, b.value(0));
1034 assert!(!b.is_valid(1));
1035 assert_eq!(2012, b.value(2));
1036 }
1037
1038 #[test]
1039 fn test_temporal_array_date64_quarter() {
1040 let a: PrimitiveArray<Date64Type> =
1043 vec![Some(1514764800000), None, Some(1566275025000)].into();
1044
1045 let b = quarter(&a).unwrap();
1046 assert_eq!(1, b.value(0));
1047 assert!(!b.is_valid(1));
1048 assert_eq!(3, b.value(2));
1049 }
1050
1051 #[test]
1052 fn test_temporal_array_date32_quarter() {
1053 let a: PrimitiveArray<Date32Type> = vec![Some(1), None, Some(300)].into();
1054
1055 let b = quarter(&a).unwrap();
1056 assert_eq!(1, b.value(0));
1057 assert!(!b.is_valid(1));
1058 assert_eq!(4, b.value(2));
1059 }
1060
1061 #[test]
1062 fn test_temporal_array_timestamp_quarter_with_timezone() {
1063 let a = TimestampSecondArray::from(vec![86400 * 90]).with_timezone("+00:00".to_string());
1065 let b = quarter(&a).unwrap();
1066 assert_eq!(2, b.value(0));
1067 let a = TimestampSecondArray::from(vec![86400 * 90]).with_timezone("-10:00".to_string());
1068 let b = quarter(&a).unwrap();
1069 assert_eq!(1, b.value(0));
1070 }
1071
1072 #[test]
1073 fn test_temporal_array_date64_month() {
1074 let a: PrimitiveArray<Date64Type> =
1077 vec![Some(1514764800000), None, Some(1550636625000)].into();
1078
1079 let b = month(&a).unwrap();
1080 assert_eq!(1, b.value(0));
1081 assert!(!b.is_valid(1));
1082 assert_eq!(2, b.value(2));
1083 }
1084
1085 #[test]
1086 fn test_temporal_array_date32_month() {
1087 let a: PrimitiveArray<Date32Type> = vec![Some(1), None, Some(31)].into();
1088
1089 let b = month(&a).unwrap();
1090 assert_eq!(1, b.value(0));
1091 assert!(!b.is_valid(1));
1092 assert_eq!(2, b.value(2));
1093 }
1094
1095 #[test]
1096 fn test_temporal_array_timestamp_month_with_timezone() {
1097 let a = TimestampSecondArray::from(vec![86400 * 31]).with_timezone("+00:00".to_string());
1099 let b = month(&a).unwrap();
1100 assert_eq!(2, b.value(0));
1101 let a = TimestampSecondArray::from(vec![86400 * 31]).with_timezone("-10:00".to_string());
1102 let b = month(&a).unwrap();
1103 assert_eq!(1, b.value(0));
1104 }
1105
1106 #[test]
1107 fn test_temporal_array_timestamp_day_with_timezone() {
1108 let a = TimestampSecondArray::from(vec![86400]).with_timezone("+00:00".to_string());
1110 let b = day(&a).unwrap();
1111 assert_eq!(2, b.value(0));
1112 let a = TimestampSecondArray::from(vec![86400]).with_timezone("-10:00".to_string());
1113 let b = day(&a).unwrap();
1114 assert_eq!(1, b.value(0));
1115 }
1116
1117 #[test]
1118 fn test_temporal_array_date64_weekday() {
1119 let a: PrimitiveArray<Date64Type> =
1122 vec![Some(1514764800000), None, Some(1550636625000)].into();
1123
1124 let b = num_days_from_monday(&a).unwrap();
1125 assert_eq!(0, b.value(0));
1126 assert!(!b.is_valid(1));
1127 assert_eq!(2, b.value(2));
1128 }
1129
1130 #[test]
1131 fn test_temporal_array_date64_weekday0() {
1132 let a: PrimitiveArray<Date64Type> = vec![
1136 Some(1483228800000),
1137 None,
1138 Some(1514764800000),
1139 Some(1550636625000),
1140 ]
1141 .into();
1142
1143 let b = num_days_from_sunday(&a).unwrap();
1144 assert_eq!(0, b.value(0));
1145 assert!(!b.is_valid(1));
1146 assert_eq!(1, b.value(2));
1147 assert_eq!(3, b.value(3));
1148 }
1149
1150 #[test]
1151 fn test_temporal_array_date64_day() {
1152 let a: PrimitiveArray<Date64Type> =
1155 vec![Some(1514764800000), None, Some(1550636625000)].into();
1156
1157 let b = day(&a).unwrap();
1158 assert_eq!(1, b.value(0));
1159 assert!(!b.is_valid(1));
1160 assert_eq!(20, b.value(2));
1161 }
1162
1163 #[test]
1164 fn test_temporal_array_date32_day() {
1165 let a: PrimitiveArray<Date32Type> = vec![Some(0), None, Some(31)].into();
1166
1167 let b = day(&a).unwrap();
1168 assert_eq!(1, b.value(0));
1169 assert!(!b.is_valid(1));
1170 assert_eq!(1, b.value(2));
1171 }
1172
1173 #[test]
1174 fn test_temporal_array_date64_doy() {
1175 let a: PrimitiveArray<Date64Type> = vec![
1179 Some(1483228800000),
1180 Some(1514764800000),
1181 None,
1182 Some(1550636625000),
1183 ]
1184 .into();
1185
1186 let b = doy(&a).unwrap();
1187 assert_eq!(1, b.value(0));
1188 assert_eq!(1, b.value(1));
1189 assert!(!b.is_valid(2));
1190 assert_eq!(51, b.value(3));
1191 }
1192
1193 #[test]
1194 fn test_temporal_array_timestamp_micro_year() {
1195 let a: TimestampMicrosecondArray =
1196 vec![Some(1612025847000000), None, Some(1722015847000000)].into();
1197
1198 let b = year(&a).unwrap();
1199 assert_eq!(2021, b.value(0));
1200 assert!(!b.is_valid(1));
1201 assert_eq!(2024, b.value(2));
1202 }
1203
1204 #[test]
1205 fn test_temporal_array_date64_minute() {
1206 let a: PrimitiveArray<Date64Type> =
1207 vec![Some(1514764800000), None, Some(1550636625000)].into();
1208
1209 let b = minute(&a).unwrap();
1210 assert_eq!(0, b.value(0));
1211 assert!(!b.is_valid(1));
1212 assert_eq!(23, b.value(2));
1213 }
1214
1215 #[test]
1216 fn test_temporal_array_timestamp_micro_minute() {
1217 let a: TimestampMicrosecondArray =
1218 vec![Some(1612025847000000), None, Some(1722015847000000)].into();
1219
1220 let b = minute(&a).unwrap();
1221 assert_eq!(57, b.value(0));
1222 assert!(!b.is_valid(1));
1223 assert_eq!(44, b.value(2));
1224 }
1225
1226 #[test]
1227 fn test_temporal_array_date32_week() {
1228 let a: PrimitiveArray<Date32Type> = vec![Some(0), None, Some(7)].into();
1229
1230 let b = week(&a).unwrap();
1231 assert_eq!(1, b.value(0));
1232 assert!(!b.is_valid(1));
1233 assert_eq!(2, b.value(2));
1234 }
1235
1236 #[test]
1237 fn test_temporal_array_date64_week() {
1238 let a: PrimitiveArray<Date64Type> = vec![
1241 Some(1646116175000),
1242 None,
1243 Some(1641171600000),
1244 Some(1640998800000),
1245 ]
1246 .into();
1247
1248 let b = week(&a).unwrap();
1249 assert_eq!(9, b.value(0));
1250 assert!(!b.is_valid(1));
1251 assert_eq!(1, b.value(2));
1252 assert_eq!(52, b.value(3));
1253 }
1254
1255 #[test]
1256 fn test_temporal_array_timestamp_micro_week() {
1257 let a: TimestampMicrosecondArray =
1260 vec![Some(1612025847000000), None, Some(1722015847000000)].into();
1261
1262 let b = week(&a).unwrap();
1263 assert_eq!(4, b.value(0));
1264 assert!(!b.is_valid(1));
1265 assert_eq!(30, b.value(2));
1266 }
1267
1268 #[test]
1269 fn test_temporal_array_date64_second() {
1270 let a: PrimitiveArray<Date64Type> =
1271 vec![Some(1514764800000), None, Some(1550636625000)].into();
1272
1273 let b = second(&a).unwrap();
1274 assert_eq!(0, b.value(0));
1275 assert!(!b.is_valid(1));
1276 assert_eq!(45, b.value(2));
1277 }
1278
1279 #[test]
1280 fn test_temporal_array_timestamp_micro_second() {
1281 let a: TimestampMicrosecondArray =
1282 vec![Some(1612025847000000), None, Some(1722015847000000)].into();
1283
1284 let b = second(&a).unwrap();
1285 assert_eq!(27, b.value(0));
1286 assert!(!b.is_valid(1));
1287 assert_eq!(7, b.value(2));
1288 }
1289
1290 #[test]
1291 fn test_temporal_array_timestamp_second_with_timezone() {
1292 let a = TimestampSecondArray::from(vec![10, 20]).with_timezone("+00:00".to_string());
1293 let b = second(&a).unwrap();
1294 assert_eq!(10, b.value(0));
1295 assert_eq!(20, b.value(1));
1296 }
1297
1298 #[test]
1299 fn test_temporal_array_timestamp_minute_with_timezone() {
1300 let a = TimestampSecondArray::from(vec![0, 60]).with_timezone("+00:50".to_string());
1301 let b = minute(&a).unwrap();
1302 assert_eq!(50, b.value(0));
1303 assert_eq!(51, b.value(1));
1304 }
1305
1306 #[test]
1307 fn test_temporal_array_timestamp_minute_with_negative_timezone() {
1308 let a = TimestampSecondArray::from(vec![60 * 55]).with_timezone("-00:50".to_string());
1309 let b = minute(&a).unwrap();
1310 assert_eq!(5, b.value(0));
1311 }
1312
1313 #[test]
1314 fn test_temporal_array_timestamp_hour_with_timezone() {
1315 let a = TimestampSecondArray::from(vec![60 * 60 * 10]).with_timezone("+01:00".to_string());
1316 let b = hour(&a).unwrap();
1317 assert_eq!(11, b.value(0));
1318 }
1319
1320 #[test]
1321 fn test_temporal_array_timestamp_hour_with_timezone_without_colon() {
1322 let a = TimestampSecondArray::from(vec![60 * 60 * 10]).with_timezone("+0100".to_string());
1323 let b = hour(&a).unwrap();
1324 assert_eq!(11, b.value(0));
1325 }
1326
1327 #[test]
1328 fn test_temporal_array_timestamp_hour_with_timezone_without_minutes() {
1329 let a = TimestampSecondArray::from(vec![60 * 60 * 10]).with_timezone("+01".to_string());
1330 let b = hour(&a).unwrap();
1331 assert_eq!(11, b.value(0));
1332 }
1333
1334 #[test]
1335 fn test_temporal_array_timestamp_hour_with_timezone_without_initial_sign() {
1336 let a = TimestampSecondArray::from(vec![60 * 60 * 10]).with_timezone("0100".to_string());
1337 let err = hour(&a).unwrap_err().to_string();
1338 assert!(err.contains("Invalid timezone"), "{}", err);
1339 }
1340
1341 #[test]
1342 fn test_temporal_array_timestamp_hour_with_timezone_with_only_colon() {
1343 let a = TimestampSecondArray::from(vec![60 * 60 * 10]).with_timezone("01:00".to_string());
1344 let err = hour(&a).unwrap_err().to_string();
1345 assert!(err.contains("Invalid timezone"), "{}", err);
1346 }
1347
1348 #[test]
1349 fn test_temporal_array_timestamp_week_without_timezone() {
1350 let a = TimestampSecondArray::from(vec![0, 86400 * 4, 86400 * 4 - 1]);
1354 let b = week(&a).unwrap();
1355 assert_eq!(1, b.value(0));
1356 assert_eq!(2, b.value(1));
1357 assert_eq!(1, b.value(2));
1358 }
1359
1360 #[test]
1361 fn test_temporal_array_timestamp_week_with_timezone() {
1362 let a = TimestampSecondArray::from(vec![0, 86400 * 4, 86400 * 4 - 1])
1366 .with_timezone("+01:00".to_string());
1367 let b = week(&a).unwrap();
1368 assert_eq!(1, b.value(0));
1369 assert_eq!(2, b.value(1));
1370 assert_eq!(2, b.value(2));
1371 }
1372
1373 #[test]
1374 fn test_hour_minute_second_dictionary_array() {
1375 let a = TimestampSecondArray::from(vec![
1376 60 * 60 * 10 + 61,
1377 60 * 60 * 20 + 122,
1378 60 * 60 * 30 + 183,
1379 ])
1380 .with_timezone("+01:00".to_string());
1381
1382 let keys = Int8Array::from_iter_values([0_i8, 0, 1, 2, 1]);
1383 let dict = DictionaryArray::try_new(keys.clone(), Arc::new(a)).unwrap();
1384
1385 let b = hour_dyn(&dict).unwrap();
1386
1387 let expected_dict =
1388 DictionaryArray::new(keys.clone(), Arc::new(Int32Array::from(vec![11, 21, 7])));
1389 let expected = Arc::new(expected_dict) as ArrayRef;
1390 assert_eq!(&expected, &b);
1391
1392 let b = date_part(&dict, DatePart::Minute).unwrap();
1393
1394 let b_old = minute_dyn(&dict).unwrap();
1395
1396 let expected_dict =
1397 DictionaryArray::new(keys.clone(), Arc::new(Int32Array::from(vec![1, 2, 3])));
1398 let expected = Arc::new(expected_dict) as ArrayRef;
1399 assert_eq!(&expected, &b);
1400 assert_eq!(&expected, &b_old);
1401
1402 let b = date_part(&dict, DatePart::Second).unwrap();
1403
1404 let b_old = second_dyn(&dict).unwrap();
1405
1406 let expected_dict =
1407 DictionaryArray::new(keys.clone(), Arc::new(Int32Array::from(vec![1, 2, 3])));
1408 let expected = Arc::new(expected_dict) as ArrayRef;
1409 assert_eq!(&expected, &b);
1410 assert_eq!(&expected, &b_old);
1411
1412 let b = date_part(&dict, DatePart::Nanosecond).unwrap();
1413
1414 let expected_dict =
1415 DictionaryArray::new(keys, Arc::new(Int32Array::from(vec![0, 0, 0, 0, 0])));
1416 let expected = Arc::new(expected_dict) as ArrayRef;
1417 assert_eq!(&expected, &b);
1418 }
1419
1420 #[test]
1421 fn test_year_dictionary_array() {
1422 let a: PrimitiveArray<Date64Type> = vec![Some(1514764800000), Some(1550636625000)].into();
1423
1424 let keys = Int8Array::from_iter_values([0_i8, 1, 1, 0]);
1425 let dict = DictionaryArray::new(keys.clone(), Arc::new(a));
1426
1427 let b = year_dyn(&dict).unwrap();
1428
1429 let expected_dict = DictionaryArray::new(
1430 keys,
1431 Arc::new(Int32Array::from(vec![2018, 2019, 2019, 2018])),
1432 );
1433 let expected = Arc::new(expected_dict) as ArrayRef;
1434 assert_eq!(&expected, &b);
1435 }
1436
1437 #[test]
1438 fn test_quarter_month_dictionary_array() {
1439 let a: PrimitiveArray<Date64Type> = vec![Some(1514764800000), Some(1566275025000)].into();
1442
1443 let keys = Int8Array::from_iter_values([0_i8, 1, 1, 0]);
1444 let dict = DictionaryArray::new(keys.clone(), Arc::new(a));
1445
1446 let b = quarter_dyn(&dict).unwrap();
1447
1448 let expected =
1449 DictionaryArray::new(keys.clone(), Arc::new(Int32Array::from(vec![1, 3, 3, 1])));
1450 assert_eq!(b.as_ref(), &expected);
1451
1452 let b = month_dyn(&dict).unwrap();
1453
1454 let expected = DictionaryArray::new(keys, Arc::new(Int32Array::from(vec![1, 8, 8, 1])));
1455 assert_eq!(b.as_ref(), &expected);
1456 }
1457
1458 #[test]
1459 fn test_num_days_from_monday_sunday_day_doy_week_dictionary_array() {
1460 let a: PrimitiveArray<Date64Type> = vec![Some(1514764800000), Some(1550636625000)].into();
1463
1464 let keys = Int8Array::from(vec![Some(0_i8), Some(1), Some(1), Some(0), None]);
1465 let dict = DictionaryArray::new(keys.clone(), Arc::new(a));
1466
1467 let b = num_days_from_monday_dyn(&dict).unwrap();
1468
1469 let a = Int32Array::from(vec![Some(0), Some(2), Some(2), Some(0), None]);
1470 let expected = DictionaryArray::new(keys.clone(), Arc::new(a));
1471 assert_eq!(b.as_ref(), &expected);
1472
1473 let b = num_days_from_sunday_dyn(&dict).unwrap();
1474
1475 let a = Int32Array::from(vec![Some(1), Some(3), Some(3), Some(1), None]);
1476 let expected = DictionaryArray::new(keys.clone(), Arc::new(a));
1477 assert_eq!(b.as_ref(), &expected);
1478
1479 let b = day_dyn(&dict).unwrap();
1480
1481 let a = Int32Array::from(vec![Some(1), Some(20), Some(20), Some(1), None]);
1482 let expected = DictionaryArray::new(keys.clone(), Arc::new(a));
1483 assert_eq!(b.as_ref(), &expected);
1484
1485 let b = doy_dyn(&dict).unwrap();
1486
1487 let a = Int32Array::from(vec![Some(1), Some(51), Some(51), Some(1), None]);
1488 let expected = DictionaryArray::new(keys.clone(), Arc::new(a));
1489 assert_eq!(b.as_ref(), &expected);
1490
1491 let b = week_dyn(&dict).unwrap();
1492
1493 let a = Int32Array::from(vec![Some(1), Some(8), Some(8), Some(1), None]);
1494 let expected = DictionaryArray::new(keys, Arc::new(a));
1495 assert_eq!(b.as_ref(), &expected);
1496 }
1497
1498 #[test]
1499 fn test_temporal_array_date64_nanosecond() {
1500 let a: PrimitiveArray<Date64Type> = vec![None, Some(1667328721453)].into();
1507
1508 let b = nanosecond(&a).unwrap();
1509 assert!(!b.is_valid(0));
1510 assert_eq!(453_000_000, b.value(1));
1511
1512 let keys = Int8Array::from(vec![Some(0_i8), Some(1), Some(1)]);
1513 let dict = DictionaryArray::new(keys.clone(), Arc::new(a));
1514 let b = nanosecond_dyn(&dict).unwrap();
1515
1516 let a = Int32Array::from(vec![None, Some(453_000_000)]);
1517 let expected_dict = DictionaryArray::new(keys, Arc::new(a));
1518 let expected = Arc::new(expected_dict) as ArrayRef;
1519 assert_eq!(&expected, &b);
1520 }
1521
1522 #[test]
1523 fn test_temporal_array_date64_microsecond() {
1524 let a: PrimitiveArray<Date64Type> = vec![None, Some(1667328721453)].into();
1525
1526 let b = microsecond(&a).unwrap();
1527 assert!(!b.is_valid(0));
1528 assert_eq!(453_000, b.value(1));
1529
1530 let keys = Int8Array::from(vec![Some(0_i8), Some(1), Some(1)]);
1531 let dict = DictionaryArray::new(keys.clone(), Arc::new(a));
1532 let b = microsecond_dyn(&dict).unwrap();
1533
1534 let a = Int32Array::from(vec![None, Some(453_000)]);
1535 let expected_dict = DictionaryArray::new(keys, Arc::new(a));
1536 let expected = Arc::new(expected_dict) as ArrayRef;
1537 assert_eq!(&expected, &b);
1538 }
1539
1540 #[test]
1541 fn test_temporal_array_date64_millisecond() {
1542 let a: PrimitiveArray<Date64Type> = vec![None, Some(1667328721453)].into();
1543
1544 let b = millisecond(&a).unwrap();
1545 assert!(!b.is_valid(0));
1546 assert_eq!(453, b.value(1));
1547
1548 let keys = Int8Array::from(vec![Some(0_i8), Some(1), Some(1)]);
1549 let dict = DictionaryArray::new(keys.clone(), Arc::new(a));
1550 let b = millisecond_dyn(&dict).unwrap();
1551
1552 let a = Int32Array::from(vec![None, Some(453)]);
1553 let expected_dict = DictionaryArray::new(keys, Arc::new(a));
1554 let expected = Arc::new(expected_dict) as ArrayRef;
1555 assert_eq!(&expected, &b);
1556 }
1557
1558 #[test]
1559 fn test_temporal_array_time64_nanoseconds() {
1560 let input: Time64NanosecondArray = vec![Some(84_770_123_456_789)].into();
1562
1563 let actual = date_part(&input, DatePart::Hour).unwrap();
1564 let actual = actual.as_primitive::<Int32Type>();
1565 assert_eq!(23, actual.value(0));
1566
1567 let actual = date_part(&input, DatePart::Minute).unwrap();
1568 let actual = actual.as_primitive::<Int32Type>();
1569 assert_eq!(32, actual.value(0));
1570
1571 let actual = date_part(&input, DatePart::Second).unwrap();
1572 let actual = actual.as_primitive::<Int32Type>();
1573 assert_eq!(50, actual.value(0));
1574
1575 let actual = date_part(&input, DatePart::Millisecond).unwrap();
1576 let actual = actual.as_primitive::<Int32Type>();
1577 assert_eq!(123, actual.value(0));
1578
1579 let actual = date_part(&input, DatePart::Microsecond).unwrap();
1580 let actual = actual.as_primitive::<Int32Type>();
1581 assert_eq!(123_456, actual.value(0));
1582
1583 let actual = date_part(&input, DatePart::Nanosecond).unwrap();
1584 let actual = actual.as_primitive::<Int32Type>();
1585 assert_eq!(123_456_789, actual.value(0));
1586
1587 let input: Time64NanosecondArray = vec![
1589 Some(-1),
1590 Some(86_400_000_000_000),
1591 Some(86_401_000_000_000),
1592 None,
1593 ]
1594 .into();
1595 let actual = date_part(&input, DatePart::Hour).unwrap();
1596 let actual = actual.as_primitive::<Int32Type>();
1597 let expected: Int32Array = vec![None, None, None, None].into();
1598 assert_eq!(&expected, actual);
1599 }
1600
1601 #[test]
1602 fn test_temporal_array_time64_microseconds() {
1603 let input: Time64MicrosecondArray = vec![Some(84_770_123_456)].into();
1605
1606 let actual = date_part(&input, DatePart::Hour).unwrap();
1607 let actual = actual.as_primitive::<Int32Type>();
1608 assert_eq!(23, actual.value(0));
1609
1610 let actual = date_part(&input, DatePart::Minute).unwrap();
1611 let actual = actual.as_primitive::<Int32Type>();
1612 assert_eq!(32, actual.value(0));
1613
1614 let actual = date_part(&input, DatePart::Second).unwrap();
1615 let actual = actual.as_primitive::<Int32Type>();
1616 assert_eq!(50, actual.value(0));
1617
1618 let actual = date_part(&input, DatePart::Millisecond).unwrap();
1619 let actual = actual.as_primitive::<Int32Type>();
1620 assert_eq!(123, actual.value(0));
1621
1622 let actual = date_part(&input, DatePart::Microsecond).unwrap();
1623 let actual = actual.as_primitive::<Int32Type>();
1624 assert_eq!(123_456, actual.value(0));
1625
1626 let actual = date_part(&input, DatePart::Nanosecond).unwrap();
1627 let actual = actual.as_primitive::<Int32Type>();
1628 assert_eq!(123_456_000, actual.value(0));
1629
1630 let input: Time64MicrosecondArray =
1632 vec![Some(-1), Some(86_400_000_000), Some(86_401_000_000), None].into();
1633 let actual = date_part(&input, DatePart::Hour).unwrap();
1634 let actual = actual.as_primitive::<Int32Type>();
1635 let expected: Int32Array = vec![None, None, None, None].into();
1636 assert_eq!(&expected, actual);
1637 }
1638
1639 #[test]
1640 fn test_temporal_array_time32_milliseconds() {
1641 let input: Time32MillisecondArray = vec![Some(84_770_123)].into();
1643
1644 let actual = date_part(&input, DatePart::Hour).unwrap();
1645 let actual = actual.as_primitive::<Int32Type>();
1646 assert_eq!(23, actual.value(0));
1647
1648 let actual = date_part(&input, DatePart::Minute).unwrap();
1649 let actual = actual.as_primitive::<Int32Type>();
1650 assert_eq!(32, actual.value(0));
1651
1652 let actual = date_part(&input, DatePart::Second).unwrap();
1653 let actual = actual.as_primitive::<Int32Type>();
1654 assert_eq!(50, actual.value(0));
1655
1656 let actual = date_part(&input, DatePart::Millisecond).unwrap();
1657 let actual = actual.as_primitive::<Int32Type>();
1658 assert_eq!(123, actual.value(0));
1659
1660 let actual = date_part(&input, DatePart::Microsecond).unwrap();
1661 let actual = actual.as_primitive::<Int32Type>();
1662 assert_eq!(123_000, actual.value(0));
1663
1664 let actual = date_part(&input, DatePart::Nanosecond).unwrap();
1665 let actual = actual.as_primitive::<Int32Type>();
1666 assert_eq!(123_000_000, actual.value(0));
1667
1668 let input: Time32MillisecondArray =
1670 vec![Some(-1), Some(86_400_000), Some(86_401_000), None].into();
1671 let actual = date_part(&input, DatePart::Hour).unwrap();
1672 let actual = actual.as_primitive::<Int32Type>();
1673 let expected: Int32Array = vec![None, None, None, None].into();
1674 assert_eq!(&expected, actual);
1675 }
1676
1677 #[test]
1678 fn test_temporal_array_time32_seconds() {
1679 let input: Time32SecondArray = vec![84_770].into();
1681
1682 let actual = date_part(&input, DatePart::Hour).unwrap();
1683 let actual = actual.as_primitive::<Int32Type>();
1684 assert_eq!(23, actual.value(0));
1685
1686 let actual = date_part(&input, DatePart::Minute).unwrap();
1687 let actual = actual.as_primitive::<Int32Type>();
1688 assert_eq!(32, actual.value(0));
1689
1690 let actual = date_part(&input, DatePart::Second).unwrap();
1691 let actual = actual.as_primitive::<Int32Type>();
1692 assert_eq!(50, actual.value(0));
1693
1694 let actual = date_part(&input, DatePart::Millisecond).unwrap();
1695 let actual = actual.as_primitive::<Int32Type>();
1696 assert_eq!(0, actual.value(0));
1697
1698 let actual = date_part(&input, DatePart::Microsecond).unwrap();
1699 let actual = actual.as_primitive::<Int32Type>();
1700 assert_eq!(0, actual.value(0));
1701
1702 let actual = date_part(&input, DatePart::Nanosecond).unwrap();
1703 let actual = actual.as_primitive::<Int32Type>();
1704 assert_eq!(0, actual.value(0));
1705
1706 let input: Time32SecondArray = vec![Some(-1), Some(86_400), Some(86_401), None].into();
1708 let actual = date_part(&input, DatePart::Hour).unwrap();
1709 let actual = actual.as_primitive::<Int32Type>();
1710 let expected: Int32Array = vec![None, None, None, None].into();
1711 assert_eq!(&expected, actual);
1712 }
1713
1714 #[test]
1715 fn test_temporal_array_time_invalid_parts() {
1716 fn ensure_returns_error(array: &dyn Array) {
1717 let invalid_parts = [
1718 DatePart::Quarter,
1719 DatePart::Year,
1720 DatePart::Month,
1721 DatePart::Week,
1722 DatePart::Day,
1723 DatePart::DayOfWeekSunday0,
1724 DatePart::DayOfWeekMonday0,
1725 DatePart::DayOfYear,
1726 ];
1727
1728 for part in invalid_parts {
1729 let err = date_part(array, part).unwrap_err();
1730 let expected = format!(
1731 "Compute error: {part} does not support: {}",
1732 array.data_type()
1733 );
1734 assert_eq!(expected, err.to_string());
1735 }
1736 }
1737
1738 ensure_returns_error(&Time32SecondArray::from(vec![0]));
1739 ensure_returns_error(&Time32MillisecondArray::from(vec![0]));
1740 ensure_returns_error(&Time64MicrosecondArray::from(vec![0]));
1741 ensure_returns_error(&Time64NanosecondArray::from(vec![0]));
1742 }
1743
1744 #[test]
1745 fn test_interval_year_month_array() {
1746 let input: IntervalYearMonthArray = vec![0, 5, 24].into();
1747
1748 let actual = date_part(&input, DatePart::Year).unwrap();
1749 let actual = actual.as_primitive::<Int32Type>();
1750 assert_eq!(0, actual.value(0));
1751 assert_eq!(0, actual.value(1));
1752 assert_eq!(2, actual.value(2));
1753
1754 let actual = date_part(&input, DatePart::Month).unwrap();
1755 let actual = actual.as_primitive::<Int32Type>();
1756 assert_eq!(0, actual.value(0));
1757 assert_eq!(5, actual.value(1));
1758 assert_eq!(0, actual.value(2));
1759
1760 assert!(date_part(&input, DatePart::Day).is_err());
1761 assert!(date_part(&input, DatePart::Week).is_err());
1762 }
1763
1764 #[test]
1767 fn test_interval_day_time_array() {
1768 let input: IntervalDayTimeArray = vec![
1769 IntervalDayTime::ZERO,
1770 IntervalDayTime::new(10, 42),
1771 IntervalDayTime::new(10, 1042),
1772 IntervalDayTime::new(10, MILLISECONDS_IN_DAY as i32 + 1),
1773 ]
1774 .into();
1775
1776 let actual = date_part(&input, DatePart::Day).unwrap();
1778 let actual = actual.as_primitive::<Int32Type>();
1779 assert_eq!(0, actual.value(0));
1780 assert_eq!(10, actual.value(1));
1781 assert_eq!(10, actual.value(2));
1782 assert_eq!(10, actual.value(3));
1783
1784 let actual = date_part(&input, DatePart::Week).unwrap();
1785 let actual = actual.as_primitive::<Int32Type>();
1786 assert_eq!(0, actual.value(0));
1787 assert_eq!(1, actual.value(1));
1788 assert_eq!(1, actual.value(2));
1789 assert_eq!(1, actual.value(3));
1790
1791 let actual = date_part(&input, DatePart::Nanosecond).unwrap();
1793 let actual = actual.as_primitive::<Int32Type>();
1794 assert_eq!(0, actual.value(0));
1795 assert_eq!(42_000_000, actual.value(1));
1796 assert_eq!(1_042_000_000, actual.value(2));
1797 assert_eq!(0, actual.value(3));
1799
1800 let actual = date_part(&input, DatePart::Microsecond).unwrap();
1801 let actual = actual.as_primitive::<Int32Type>();
1802 assert_eq!(0, actual.value(0));
1803 assert_eq!(42_000, actual.value(1));
1804 assert_eq!(1_042_000, actual.value(2));
1805 assert_eq!(0, actual.value(3));
1807
1808 let actual = date_part(&input, DatePart::Millisecond).unwrap();
1809 let actual = actual.as_primitive::<Int32Type>();
1810 assert_eq!(0, actual.value(0));
1811 assert_eq!(42, actual.value(1));
1812 assert_eq!(1042, actual.value(2));
1813 assert_eq!(MILLISECONDS_IN_DAY as i32 + 1, actual.value(3));
1814
1815 let actual = date_part(&input, DatePart::Second).unwrap();
1816 let actual = actual.as_primitive::<Int32Type>();
1817 assert_eq!(0, actual.value(0));
1818 assert_eq!(0, actual.value(1));
1819 assert_eq!(1, actual.value(2));
1820 assert_eq!(24 * 60 * 60, actual.value(3));
1821
1822 let actual = date_part(&input, DatePart::Minute).unwrap();
1823 let actual = actual.as_primitive::<Int32Type>();
1824 assert_eq!(0, actual.value(0));
1825 assert_eq!(0, actual.value(1));
1826 assert_eq!(0, actual.value(2));
1827 assert_eq!(24 * 60, actual.value(3));
1828
1829 let actual = date_part(&input, DatePart::Hour).unwrap();
1830 let actual = actual.as_primitive::<Int32Type>();
1831 assert_eq!(0, actual.value(0));
1832 assert_eq!(0, actual.value(1));
1833 assert_eq!(0, actual.value(2));
1834 assert_eq!(24, actual.value(3));
1835
1836 assert!(date_part(&input, DatePart::Month).is_err());
1838 assert!(date_part(&input, DatePart::Year).is_err());
1839 }
1840
1841 #[test]
1844 fn test_interval_month_day_nano_array() {
1845 let input: IntervalMonthDayNanoArray = vec![
1846 IntervalMonthDayNano::ZERO,
1847 IntervalMonthDayNano::new(5, 10, 42),
1848 IntervalMonthDayNano::new(16, 35, MILLISECONDS_IN_DAY * 1_000_000 + 1),
1849 ]
1850 .into();
1851
1852 let actual = date_part(&input, DatePart::Year).unwrap();
1854 let actual = actual.as_primitive::<Int32Type>();
1855 assert_eq!(0, actual.value(0));
1856 assert_eq!(0, actual.value(1));
1857 assert_eq!(1, actual.value(2));
1858
1859 let actual = date_part(&input, DatePart::Month).unwrap();
1860 let actual = actual.as_primitive::<Int32Type>();
1861 assert_eq!(0, actual.value(0));
1862 assert_eq!(5, actual.value(1));
1863 assert_eq!(16, actual.value(2));
1864
1865 let actual = date_part(&input, DatePart::Week).unwrap();
1867 let actual = actual.as_primitive::<Int32Type>();
1868 assert_eq!(0, actual.value(0));
1869 assert_eq!(1, actual.value(1));
1870 assert_eq!(5, actual.value(2));
1871
1872 let actual = date_part(&input, DatePart::Day).unwrap();
1873 let actual = actual.as_primitive::<Int32Type>();
1874 assert_eq!(0, actual.value(0));
1875 assert_eq!(10, actual.value(1));
1876 assert_eq!(35, actual.value(2));
1877
1878 let actual = date_part(&input, DatePart::Hour).unwrap();
1880 let actual = actual.as_primitive::<Int32Type>();
1881 assert_eq!(0, actual.value(0));
1882 assert_eq!(0, actual.value(1));
1883 assert_eq!(24, actual.value(2));
1884
1885 let actual = date_part(&input, DatePart::Minute).unwrap();
1886 let actual = actual.as_primitive::<Int32Type>();
1887 assert_eq!(0, actual.value(0));
1888 assert_eq!(0, actual.value(1));
1889 assert_eq!(24 * 60, actual.value(2));
1890
1891 let actual = date_part(&input, DatePart::Second).unwrap();
1892 let actual = actual.as_primitive::<Int32Type>();
1893 assert_eq!(0, actual.value(0));
1894 assert_eq!(0, actual.value(1));
1895 assert_eq!(24 * 60 * 60, actual.value(2));
1896
1897 let actual = date_part(&input, DatePart::Millisecond).unwrap();
1898 let actual = actual.as_primitive::<Int32Type>();
1899 assert_eq!(0, actual.value(0));
1900 assert_eq!(0, actual.value(1));
1901 assert_eq!(24 * 60 * 60 * 1_000, actual.value(2));
1902
1903 let actual = date_part(&input, DatePart::Microsecond).unwrap();
1904 let actual = actual.as_primitive::<Int32Type>();
1905 assert_eq!(0, actual.value(0));
1906 assert_eq!(0, actual.value(1));
1907 assert_eq!(0, actual.value(2));
1909
1910 let actual = date_part(&input, DatePart::Nanosecond).unwrap();
1911 let actual = actual.as_primitive::<Int32Type>();
1912 assert_eq!(0, actual.value(0));
1913 assert_eq!(42, actual.value(1));
1914 assert_eq!(0, actual.value(2));
1916 }
1917
1918 #[test]
1919 fn test_interval_array_invalid_parts() {
1920 fn ensure_returns_error(array: &dyn Array) {
1921 let invalid_parts = [
1922 DatePart::Quarter,
1923 DatePart::DayOfWeekSunday0,
1924 DatePart::DayOfWeekMonday0,
1925 DatePart::DayOfYear,
1926 ];
1927
1928 for part in invalid_parts {
1929 let err = date_part(array, part).unwrap_err();
1930 let expected = format!(
1931 "Compute error: {part} does not support: {}",
1932 array.data_type()
1933 );
1934 assert_eq!(expected, err.to_string());
1935 }
1936 }
1937
1938 ensure_returns_error(&IntervalYearMonthArray::from(vec![0]));
1939 ensure_returns_error(&IntervalDayTimeArray::from(vec![IntervalDayTime::ZERO]));
1940 ensure_returns_error(&IntervalMonthDayNanoArray::from(vec![
1941 IntervalMonthDayNano::ZERO,
1942 ]));
1943 }
1944
1945 #[test]
1946 fn test_duration_second() {
1947 let input: DurationSecondArray = vec![0, 42, 60 * 60 * 24 + 1].into();
1948
1949 let actual = date_part(&input, DatePart::Second).unwrap();
1950 let actual = actual.as_primitive::<Int32Type>();
1951 assert_eq!(0, actual.value(0));
1952 assert_eq!(42, actual.value(1));
1953 assert_eq!(60 * 60 * 24 + 1, actual.value(2));
1954
1955 let actual = date_part(&input, DatePart::Millisecond).unwrap();
1956 let actual = actual.as_primitive::<Int32Type>();
1957 assert_eq!(0, actual.value(0));
1958 assert_eq!(42_000, actual.value(1));
1959 assert_eq!((60 * 60 * 24 + 1) * 1_000, actual.value(2));
1960
1961 let actual = date_part(&input, DatePart::Microsecond).unwrap();
1962 let actual = actual.as_primitive::<Int32Type>();
1963 assert_eq!(0, actual.value(0));
1964 assert_eq!(42_000_000, actual.value(1));
1965 assert_eq!(0, actual.value(2));
1966
1967 let actual = date_part(&input, DatePart::Nanosecond).unwrap();
1968 let actual = actual.as_primitive::<Int32Type>();
1969 assert_eq!(0, actual.value(0));
1970 assert_eq!(0, actual.value(1));
1971 assert_eq!(0, actual.value(2));
1972 }
1973
1974 #[test]
1975 fn test_duration_millisecond() {
1976 let input: DurationMillisecondArray = vec![0, 42, 60 * 60 * 24 + 1].into();
1977
1978 let actual = date_part(&input, DatePart::Second).unwrap();
1979 let actual = actual.as_primitive::<Int32Type>();
1980 assert_eq!(0, actual.value(0));
1981 assert_eq!(0, actual.value(1));
1982 assert_eq!((60 * 60 * 24 + 1) / 1_000, actual.value(2));
1983
1984 let actual = date_part(&input, DatePart::Millisecond).unwrap();
1985 let actual = actual.as_primitive::<Int32Type>();
1986 assert_eq!(0, actual.value(0));
1987 assert_eq!(42, actual.value(1));
1988 assert_eq!(60 * 60 * 24 + 1, actual.value(2));
1989
1990 let actual = date_part(&input, DatePart::Microsecond).unwrap();
1991 let actual = actual.as_primitive::<Int32Type>();
1992 assert_eq!(0, actual.value(0));
1993 assert_eq!(42_000, actual.value(1));
1994 assert_eq!((60 * 60 * 24 + 1) * 1_000, actual.value(2));
1995
1996 let actual = date_part(&input, DatePart::Nanosecond).unwrap();
1997 let actual = actual.as_primitive::<Int32Type>();
1998 assert_eq!(0, actual.value(0));
1999 assert_eq!(42_000_000, actual.value(1));
2000 assert_eq!(0, actual.value(2));
2001 }
2002
2003 #[test]
2004 fn test_duration_microsecond() {
2005 let input: DurationMicrosecondArray = vec![0, 42, 60 * 60 * 24 + 1].into();
2006
2007 let actual = date_part(&input, DatePart::Second).unwrap();
2008 let actual = actual.as_primitive::<Int32Type>();
2009 assert_eq!(0, actual.value(0));
2010 assert_eq!(0, actual.value(1));
2011 assert_eq!(0, actual.value(2));
2012
2013 let actual = date_part(&input, DatePart::Millisecond).unwrap();
2014 let actual = actual.as_primitive::<Int32Type>();
2015 assert_eq!(0, actual.value(0));
2016 assert_eq!(0, actual.value(1));
2017 assert_eq!((60 * 60 * 24 + 1) / 1_000, actual.value(2));
2018
2019 let actual = date_part(&input, DatePart::Microsecond).unwrap();
2020 let actual = actual.as_primitive::<Int32Type>();
2021 assert_eq!(0, actual.value(0));
2022 assert_eq!(42, actual.value(1));
2023 assert_eq!(60 * 60 * 24 + 1, actual.value(2));
2024
2025 let actual = date_part(&input, DatePart::Nanosecond).unwrap();
2026 let actual = actual.as_primitive::<Int32Type>();
2027 assert_eq!(0, actual.value(0));
2028 assert_eq!(42_000, actual.value(1));
2029 assert_eq!((60 * 60 * 24 + 1) * 1_000, actual.value(2));
2030 }
2031
2032 #[test]
2033 fn test_duration_nanosecond() {
2034 let input: DurationNanosecondArray = vec![0, 42, 60 * 60 * 24 + 1].into();
2035
2036 let actual = date_part(&input, DatePart::Second).unwrap();
2037 let actual = actual.as_primitive::<Int32Type>();
2038 assert_eq!(0, actual.value(0));
2039 assert_eq!(0, actual.value(1));
2040 assert_eq!(0, actual.value(2));
2041
2042 let actual = date_part(&input, DatePart::Millisecond).unwrap();
2043 let actual = actual.as_primitive::<Int32Type>();
2044 assert_eq!(0, actual.value(0));
2045 assert_eq!(0, actual.value(1));
2046 assert_eq!(0, actual.value(2));
2047
2048 let actual = date_part(&input, DatePart::Microsecond).unwrap();
2049 let actual = actual.as_primitive::<Int32Type>();
2050 assert_eq!(0, actual.value(0));
2051 assert_eq!(0, actual.value(1));
2052 assert_eq!((60 * 60 * 24 + 1) / 1_000, actual.value(2));
2053
2054 let actual = date_part(&input, DatePart::Nanosecond).unwrap();
2055 let actual = actual.as_primitive::<Int32Type>();
2056 assert_eq!(0, actual.value(0));
2057 assert_eq!(42, actual.value(1));
2058 assert_eq!(60 * 60 * 24 + 1, actual.value(2));
2059 }
2060
2061 #[test]
2062 fn test_duration_invalid_parts() {
2063 fn ensure_returns_error(array: &dyn Array) {
2064 let invalid_parts = [
2065 DatePart::Year,
2066 DatePart::Quarter,
2067 DatePart::Month,
2068 DatePart::DayOfWeekSunday0,
2069 DatePart::DayOfWeekMonday0,
2070 DatePart::DayOfYear,
2071 ];
2072
2073 for part in invalid_parts {
2074 let err = date_part(array, part).unwrap_err();
2075 let expected = format!(
2076 "Compute error: {part} does not support: {}",
2077 array.data_type()
2078 );
2079 assert_eq!(expected, err.to_string());
2080 }
2081 }
2082
2083 ensure_returns_error(&DurationSecondArray::from(vec![0]));
2084 ensure_returns_error(&DurationMillisecondArray::from(vec![0]));
2085 ensure_returns_error(&DurationMicrosecondArray::from(vec![0]));
2086 ensure_returns_error(&DurationNanosecondArray::from(vec![0]));
2087 }
2088}