implement second/minute helpers for temporal (#493) (#498)
* implement second/minute helpers for temporal
* Update arrow/src/compute/kernels/temporal.rs
Co-authored-by: Daniël Heres <danielheres@gmail.com>
* Update arrow/src/compute/kernels/temporal.rs
Co-authored-by: Daniël Heres <danielheres@gmail.com>
Co-authored-by: Daniël Heres <danielheres@gmail.com>
Co-authored-by: Dmitry Patsura <zaets28rus@gmail.com>
Co-authored-by: Daniël Heres <danielheres@gmail.com>
diff --git a/arrow/src/compute/kernels/temporal.rs b/arrow/src/compute/kernels/temporal.rs
index 18a267f..5db0dfb 100644
--- a/arrow/src/compute/kernels/temporal.rs
+++ b/arrow/src/compute/kernels/temporal.rs
@@ -100,6 +100,72 @@
Ok(b.finish())
}
+/// Extracts the minutes of a given temporal array as an array of integers
+pub fn minute<T>(array: &PrimitiveArray<T>) -> Result<Int32Array>
+where
+ T: ArrowTemporalType + ArrowNumericType,
+ i64: std::convert::From<T::Native>,
+{
+ let mut b = Int32Builder::new(array.len());
+ match array.data_type() {
+ &DataType::Date64 | &DataType::Timestamp(_, _) => {
+ for i in 0..array.len() {
+ if array.is_null(i) {
+ b.append_null()?;
+ } else {
+ match array.value_as_datetime(i) {
+ Some(dt) => b.append_value(dt.minute() as i32)?,
+ None => b.append_null()?,
+ }
+ }
+ }
+ }
+ dt => {
+ return {
+ Err(ArrowError::ComputeError(format!(
+ "minute does not support type {:?}",
+ dt
+ )))
+ }
+ }
+ }
+
+ Ok(b.finish())
+}
+
+/// Extracts the seconds of a given temporal array as an array of integers
+pub fn second<T>(array: &PrimitiveArray<T>) -> Result<Int32Array>
+where
+ T: ArrowTemporalType + ArrowNumericType,
+ i64: std::convert::From<T::Native>,
+{
+ let mut b = Int32Builder::new(array.len());
+ match array.data_type() {
+ &DataType::Date64 | &DataType::Timestamp(_, _) => {
+ for i in 0..array.len() {
+ if array.is_null(i) {
+ b.append_null()?;
+ } else {
+ match array.value_as_datetime(i) {
+ Some(dt) => b.append_value(dt.second() as i32)?,
+ None => b.append_null()?,
+ }
+ }
+ }
+ }
+ dt => {
+ return {
+ Err(ArrowError::ComputeError(format!(
+ "second does not support type {:?}",
+ dt
+ )))
+ }
+ }
+ }
+
+ Ok(b.finish())
+}
+
#[cfg(test)]
mod tests {
use super::*;
@@ -184,4 +250,48 @@
assert!(!b.is_valid(1));
assert_eq!(2024, b.value(2));
}
+
+ #[test]
+ fn test_temporal_array_date64_minute() {
+ let a: PrimitiveArray<Date64Type> =
+ vec![Some(1514764800000), None, Some(1550636625000)].into();
+
+ let b = minute(&a).unwrap();
+ assert_eq!(0, b.value(0));
+ assert!(!b.is_valid(1));
+ assert_eq!(23, b.value(2));
+ }
+
+ #[test]
+ fn test_temporal_array_timestamp_micro_minute() {
+ let a: TimestampMicrosecondArray =
+ vec![Some(1612025847000000), None, Some(1722015847000000)].into();
+
+ let b = minute(&a).unwrap();
+ assert_eq!(57, b.value(0));
+ assert!(!b.is_valid(1));
+ assert_eq!(44, b.value(2));
+ }
+
+ #[test]
+ fn test_temporal_array_date64_second() {
+ let a: PrimitiveArray<Date64Type> =
+ vec![Some(1514764800000), None, Some(1550636625000)].into();
+
+ let b = second(&a).unwrap();
+ assert_eq!(0, b.value(0));
+ assert!(!b.is_valid(1));
+ assert_eq!(45, b.value(2));
+ }
+
+ #[test]
+ fn test_temporal_array_timestamp_micro_second() {
+ let a: TimestampMicrosecondArray =
+ vec![Some(1612025847000000), None, Some(1722015847000000)].into();
+
+ let b = second(&a).unwrap();
+ assert_eq!(27, b.value(0));
+ assert!(!b.is_valid(1));
+ assert_eq!(7, b.value(2));
+ }
}