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