Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-time/src/chunkedarray/date.rs
6939 views
1
use arrow::temporal_conversions::{EPOCH_DAYS_FROM_CE, MILLISECONDS, SECONDS_IN_DAY};
2
use chrono::{Datelike, NaiveDate};
3
4
use super::*;
5
6
pub(crate) fn naive_date_to_date(nd: NaiveDate) -> i32 {
7
let nt = NaiveTime::from_hms_opt(0, 0, 0).unwrap();
8
let ndt = NaiveDateTime::new(nd, nt);
9
naive_datetime_to_date(ndt)
10
}
11
12
pub(crate) fn naive_datetime_to_date(v: NaiveDateTime) -> i32 {
13
(datetime_to_timestamp_ms(v) / (MILLISECONDS * SECONDS_IN_DAY)) as i32
14
}
15
16
pub trait DateMethods: AsDate {
17
/// Extract month from underlying NaiveDate representation.
18
/// Returns the year number in the calendar date.
19
fn year(&self) -> Int32Chunked {
20
let ca = self.as_date();
21
ca.physical().apply_kernel_cast::<Int32Type>(&date_to_year)
22
}
23
24
/// Extract year from underlying NaiveDate representation.
25
/// Returns whether the year is a leap year.
26
fn is_leap_year(&self) -> BooleanChunked {
27
let ca = self.as_date();
28
ca.physical()
29
.apply_kernel_cast::<BooleanType>(&date_to_is_leap_year)
30
}
31
32
/// This year number might not match the calendar year number.
33
fn iso_year(&self) -> Int32Chunked {
34
let ca = self.as_date();
35
ca.physical()
36
.apply_kernel_cast::<Int32Type>(&date_to_iso_year)
37
}
38
39
/// Extract month from underlying NaiveDateTime representation.
40
/// Quarters range from 1 to 4.
41
fn quarter(&self) -> Int8Chunked {
42
let months = self.month();
43
months_to_quarters(months)
44
}
45
46
/// Extract month from underlying NaiveDateTime representation.
47
/// Returns the month number starting from 1.
48
///
49
/// The return value ranges from 1 to 12.
50
fn month(&self) -> Int8Chunked {
51
let ca = self.as_date();
52
ca.physical().apply_kernel_cast::<Int8Type>(&date_to_month)
53
}
54
55
/// Returns the number of days in the month of the underlying NaiveDate
56
/// representation.
57
fn days_in_month(&self) -> Int8Chunked {
58
let ca = self.as_date();
59
ca.physical()
60
.apply_kernel_cast::<Int8Type>(&date_to_days_in_month)
61
}
62
63
/// Returns the ISO week number starting from 1.
64
/// The return value ranges from 1 to 53. (The last week of year differs by years.)
65
fn week(&self) -> Int8Chunked {
66
let ca = self.as_date();
67
ca.physical()
68
.apply_kernel_cast::<Int8Type>(&date_to_iso_week)
69
}
70
71
/// Extract day from underlying NaiveDate representation.
72
/// Returns the day of month starting from 1.
73
///
74
/// The return value ranges from 1 to 31. (The last day of month differs by months.)
75
fn day(&self) -> Int8Chunked {
76
let ca = self.as_date();
77
ca.physical().apply_kernel_cast::<Int8Type>(&date_to_day)
78
}
79
80
/// Returns the day of year starting from 1.
81
///
82
/// The return value ranges from 1 to 366. (The last day of year differs by years.)
83
fn ordinal(&self) -> Int16Chunked {
84
let ca = self.as_date();
85
ca.physical()
86
.apply_kernel_cast::<Int16Type>(&date_to_ordinal)
87
}
88
89
fn parse_from_str_slice(name: PlSmallStr, v: &[&str], fmt: &str) -> DateChunked;
90
91
/// Construct a date ChunkedArray from individual time components.
92
fn new_from_parts(
93
year: &Int32Chunked,
94
month: &Int8Chunked,
95
day: &Int8Chunked,
96
name: PlSmallStr,
97
) -> PolarsResult<DateChunked> {
98
let ca: Int32Chunked = year
99
.into_iter()
100
.zip(month)
101
.zip(day)
102
.map(|((y, m), d)| {
103
if let (Some(y), Some(m), Some(d)) = (y, m, d) {
104
NaiveDate::from_ymd_opt(y, m as u32, d as u32).map_or_else(
105
// We have an invalid date.
106
|| Err(polars_err!(ComputeError: format!("Invalid date components ({}, {}, {}) supplied", y, m, d))),
107
// We have a valid date.
108
|date| Ok(Some(date.num_days_from_ce() - EPOCH_DAYS_FROM_CE)),
109
)
110
} else {
111
Ok(None)
112
}
113
})
114
.try_collect_ca_with_dtype(name, DataType::Int32)?;
115
Ok(ca.into_date())
116
}
117
}
118
119
impl DateMethods for DateChunked {
120
fn parse_from_str_slice(name: PlSmallStr, v: &[&str], fmt: &str) -> DateChunked {
121
Int32Chunked::from_iter_options(
122
name,
123
v.iter().map(|s| {
124
NaiveDate::parse_from_str(s, fmt)
125
.ok()
126
.as_ref()
127
.map(|v| naive_date_to_date(*v))
128
}),
129
)
130
.into_date()
131
}
132
}
133
134
pub trait AsDate {
135
fn as_date(&self) -> &DateChunked;
136
}
137
138
impl AsDate for DateChunked {
139
fn as_date(&self) -> &DateChunked {
140
self
141
}
142
}
143
144