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