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