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