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