Path: blob/main/crates/polars-time/src/chunkedarray/date.rs
6939 views
use arrow::temporal_conversions::{EPOCH_DAYS_FROM_CE, MILLISECONDS, SECONDS_IN_DAY};1use chrono::{Datelike, NaiveDate};23use super::*;45pub(crate) fn naive_date_to_date(nd: NaiveDate) -> i32 {6let nt = NaiveTime::from_hms_opt(0, 0, 0).unwrap();7let ndt = NaiveDateTime::new(nd, nt);8naive_datetime_to_date(ndt)9}1011pub(crate) fn naive_datetime_to_date(v: NaiveDateTime) -> i32 {12(datetime_to_timestamp_ms(v) / (MILLISECONDS * SECONDS_IN_DAY)) as i3213}1415pub trait DateMethods: AsDate {16/// Extract month from underlying NaiveDate representation.17/// Returns the year number in the calendar date.18fn year(&self) -> Int32Chunked {19let ca = self.as_date();20ca.physical().apply_kernel_cast::<Int32Type>(&date_to_year)21}2223/// Extract year from underlying NaiveDate representation.24/// Returns whether the year is a leap year.25fn is_leap_year(&self) -> BooleanChunked {26let ca = self.as_date();27ca.physical()28.apply_kernel_cast::<BooleanType>(&date_to_is_leap_year)29}3031/// This year number might not match the calendar year number.32fn iso_year(&self) -> Int32Chunked {33let ca = self.as_date();34ca.physical()35.apply_kernel_cast::<Int32Type>(&date_to_iso_year)36}3738/// Extract month from underlying NaiveDateTime representation.39/// Quarters range from 1 to 4.40fn quarter(&self) -> Int8Chunked {41let months = self.month();42months_to_quarters(months)43}4445/// Extract month from underlying NaiveDateTime representation.46/// Returns the month number starting from 1.47///48/// The return value ranges from 1 to 12.49fn month(&self) -> Int8Chunked {50let ca = self.as_date();51ca.physical().apply_kernel_cast::<Int8Type>(&date_to_month)52}5354/// Returns the number of days in the month of the underlying NaiveDate55/// representation.56fn days_in_month(&self) -> Int8Chunked {57let ca = self.as_date();58ca.physical()59.apply_kernel_cast::<Int8Type>(&date_to_days_in_month)60}6162/// Returns the ISO week number starting from 1.63/// The return value ranges from 1 to 53. (The last week of year differs by years.)64fn week(&self) -> Int8Chunked {65let ca = self.as_date();66ca.physical()67.apply_kernel_cast::<Int8Type>(&date_to_iso_week)68}6970/// Extract day from underlying NaiveDate representation.71/// Returns the day of month starting from 1.72///73/// The return value ranges from 1 to 31. (The last day of month differs by months.)74fn day(&self) -> Int8Chunked {75let ca = self.as_date();76ca.physical().apply_kernel_cast::<Int8Type>(&date_to_day)77}7879/// Returns the day of year starting from 1.80///81/// The return value ranges from 1 to 366. (The last day of year differs by years.)82fn ordinal(&self) -> Int16Chunked {83let ca = self.as_date();84ca.physical()85.apply_kernel_cast::<Int16Type>(&date_to_ordinal)86}8788fn parse_from_str_slice(name: PlSmallStr, v: &[&str], fmt: &str) -> DateChunked;8990/// Construct a date ChunkedArray from individual time components.91fn new_from_parts(92year: &Int32Chunked,93month: &Int8Chunked,94day: &Int8Chunked,95name: PlSmallStr,96) -> PolarsResult<DateChunked> {97let ca: Int32Chunked = year98.into_iter()99.zip(month)100.zip(day)101.map(|((y, m), d)| {102if let (Some(y), Some(m), Some(d)) = (y, m, d) {103NaiveDate::from_ymd_opt(y, m as u32, d as u32).map_or_else(104// We have an invalid date.105|| Err(polars_err!(ComputeError: format!("Invalid date components ({}, {}, {}) supplied", y, m, d))),106// We have a valid date.107|date| Ok(Some(date.num_days_from_ce() - EPOCH_DAYS_FROM_CE)),108)109} else {110Ok(None)111}112})113.try_collect_ca_with_dtype(name, DataType::Int32)?;114Ok(ca.into_date())115}116}117118impl DateMethods for DateChunked {119fn parse_from_str_slice(name: PlSmallStr, v: &[&str], fmt: &str) -> DateChunked {120Int32Chunked::from_iter_options(121name,122v.iter().map(|s| {123NaiveDate::parse_from_str(s, fmt)124.ok()125.as_ref()126.map(|v| naive_date_to_date(*v))127}),128)129.into_date()130}131}132133pub trait AsDate {134fn as_date(&self) -> &DateChunked;135}136137impl AsDate for DateChunked {138fn as_date(&self) -> &DateChunked {139self140}141}142143144