polars_core/series/implementations/
datetime.rs

1use super::*;
2#[cfg(feature = "algorithm_group_by")]
3use crate::frame::group_by::*;
4use crate::prelude::*;
5
6unsafe impl IntoSeries for DatetimeChunked {
7    fn into_series(self) -> Series {
8        Series(Arc::new(SeriesWrap(self)))
9    }
10}
11
12impl private::PrivateSeriesNumeric for SeriesWrap<DatetimeChunked> {
13    fn bit_repr(&self) -> Option<BitRepr> {
14        Some(self.0.to_bit_repr())
15    }
16}
17
18impl private::PrivateSeries for SeriesWrap<DatetimeChunked> {
19    fn compute_len(&mut self) {
20        self.0.compute_len()
21    }
22    fn _field(&self) -> Cow<Field> {
23        Cow::Owned(self.0.field())
24    }
25    fn _dtype(&self) -> &DataType {
26        self.0.dtype()
27    }
28    fn _get_flags(&self) -> StatisticsFlags {
29        self.0.get_flags()
30    }
31    fn _set_flags(&mut self, flags: StatisticsFlags) {
32        self.0.set_flags(flags)
33    }
34
35    #[cfg(feature = "zip_with")]
36    fn zip_with_same_type(&self, mask: &BooleanChunked, other: &Series) -> PolarsResult<Series> {
37        let other = other.to_physical_repr().into_owned();
38        self.0.zip_with(mask, other.as_ref().as_ref()).map(|ca| {
39            ca.into_datetime(self.0.time_unit(), self.0.time_zone().clone())
40                .into_series()
41        })
42    }
43
44    fn into_total_eq_inner<'a>(&'a self) -> Box<dyn TotalEqInner + 'a> {
45        self.0.physical().into_total_eq_inner()
46    }
47    fn into_total_ord_inner<'a>(&'a self) -> Box<dyn TotalOrdInner + 'a> {
48        self.0.physical().into_total_ord_inner()
49    }
50
51    fn vec_hash(&self, random_state: PlRandomState, buf: &mut Vec<u64>) -> PolarsResult<()> {
52        self.0.vec_hash(random_state, buf)?;
53        Ok(())
54    }
55
56    fn vec_hash_combine(
57        &self,
58        build_hasher: PlRandomState,
59        hashes: &mut [u64],
60    ) -> PolarsResult<()> {
61        self.0.vec_hash_combine(build_hasher, hashes)?;
62        Ok(())
63    }
64
65    #[cfg(feature = "algorithm_group_by")]
66    unsafe fn agg_min(&self, groups: &GroupsType) -> Series {
67        self.0
68            .agg_min(groups)
69            .into_datetime(self.0.time_unit(), self.0.time_zone().clone())
70            .into_series()
71    }
72
73    #[cfg(feature = "algorithm_group_by")]
74    unsafe fn agg_max(&self, groups: &GroupsType) -> Series {
75        self.0
76            .agg_max(groups)
77            .into_datetime(self.0.time_unit(), self.0.time_zone().clone())
78            .into_series()
79    }
80    #[cfg(feature = "algorithm_group_by")]
81    unsafe fn agg_list(&self, groups: &GroupsType) -> Series {
82        // we cannot cast and dispatch as the inner type of the list would be incorrect
83        self.0
84            .agg_list(groups)
85            .cast(&DataType::List(Box::new(self.dtype().clone())))
86            .unwrap()
87    }
88
89    fn subtract(&self, rhs: &Series) -> PolarsResult<Series> {
90        match (self.dtype(), rhs.dtype()) {
91            (DataType::Datetime(tu, tz), DataType::Datetime(tur, tzr)) => {
92                assert_eq!(tu, tur);
93                assert_eq!(tz, tzr);
94                let lhs = self.cast(&DataType::Int64, CastOptions::NonStrict).unwrap();
95                let rhs = rhs.cast(&DataType::Int64).unwrap();
96                Ok(lhs.subtract(&rhs)?.into_duration(*tu).into_series())
97            },
98            (DataType::Datetime(tu, tz), DataType::Duration(tur)) => {
99                assert_eq!(tu, tur);
100                let lhs = self.cast(&DataType::Int64, CastOptions::NonStrict).unwrap();
101                let rhs = rhs.cast(&DataType::Int64).unwrap();
102                Ok(lhs
103                    .subtract(&rhs)?
104                    .into_datetime(*tu, tz.clone())
105                    .into_series())
106            },
107            (dtl, dtr) => polars_bail!(opq = sub, dtl, dtr),
108        }
109    }
110    fn add_to(&self, rhs: &Series) -> PolarsResult<Series> {
111        match (self.dtype(), rhs.dtype()) {
112            (DataType::Datetime(tu, tz), DataType::Duration(tur)) => {
113                assert_eq!(tu, tur);
114                let lhs = self.cast(&DataType::Int64, CastOptions::NonStrict).unwrap();
115                let rhs = rhs.cast(&DataType::Int64).unwrap();
116                Ok(lhs
117                    .add_to(&rhs)?
118                    .into_datetime(*tu, tz.clone())
119                    .into_series())
120            },
121            (dtl, dtr) => polars_bail!(opq = add, dtl, dtr),
122        }
123    }
124    fn multiply(&self, rhs: &Series) -> PolarsResult<Series> {
125        polars_bail!(opq = mul, self.dtype(), rhs.dtype());
126    }
127    fn divide(&self, rhs: &Series) -> PolarsResult<Series> {
128        polars_bail!(opq = div, self.dtype(), rhs.dtype());
129    }
130    fn remainder(&self, rhs: &Series) -> PolarsResult<Series> {
131        polars_bail!(opq = rem, self.dtype(), rhs.dtype());
132    }
133    #[cfg(feature = "algorithm_group_by")]
134    fn group_tuples(&self, multithreaded: bool, sorted: bool) -> PolarsResult<GroupsType> {
135        self.0.group_tuples(multithreaded, sorted)
136    }
137
138    fn arg_sort_multiple(
139        &self,
140        by: &[Column],
141        options: &SortMultipleOptions,
142    ) -> PolarsResult<IdxCa> {
143        self.0.deref().arg_sort_multiple(by, options)
144    }
145}
146
147impl SeriesTrait for SeriesWrap<DatetimeChunked> {
148    fn rename(&mut self, name: PlSmallStr) {
149        self.0.rename(name);
150    }
151
152    fn chunk_lengths(&self) -> ChunkLenIter {
153        self.0.chunk_lengths()
154    }
155    fn name(&self) -> &PlSmallStr {
156        self.0.name()
157    }
158
159    fn chunks(&self) -> &Vec<ArrayRef> {
160        self.0.chunks()
161    }
162    unsafe fn chunks_mut(&mut self) -> &mut Vec<ArrayRef> {
163        self.0.chunks_mut()
164    }
165
166    fn shrink_to_fit(&mut self) {
167        self.0.shrink_to_fit()
168    }
169
170    fn slice(&self, offset: i64, length: usize) -> Series {
171        self.0
172            .slice(offset, length)
173            .into_datetime(self.0.time_unit(), self.0.time_zone().clone())
174            .into_series()
175    }
176    fn split_at(&self, offset: i64) -> (Series, Series) {
177        let (a, b) = self.0.split_at(offset);
178        (
179            a.into_datetime(self.0.time_unit(), self.0.time_zone().clone())
180                .into_series(),
181            b.into_datetime(self.0.time_unit(), self.0.time_zone().clone())
182                .into_series(),
183        )
184    }
185
186    fn _sum_as_f64(&self) -> f64 {
187        self.0._sum_as_f64()
188    }
189
190    fn mean(&self) -> Option<f64> {
191        self.0.mean()
192    }
193
194    fn median(&self) -> Option<f64> {
195        self.0.median()
196    }
197
198    fn append(&mut self, other: &Series) -> PolarsResult<()> {
199        polars_ensure!(self.0.dtype() == other.dtype(), append);
200        let mut other = other.to_physical_repr().into_owned();
201        self.0
202            .append_owned(std::mem::take(other._get_inner_mut().as_mut()))
203    }
204    fn append_owned(&mut self, mut other: Series) -> PolarsResult<()> {
205        polars_ensure!(self.0.dtype() == other.dtype(), append);
206        self.0.append_owned(std::mem::take(
207            &mut other
208                ._get_inner_mut()
209                .as_any_mut()
210                .downcast_mut::<DatetimeChunked>()
211                .unwrap()
212                .0,
213        ))
214    }
215
216    fn extend(&mut self, other: &Series) -> PolarsResult<()> {
217        polars_ensure!(self.0.dtype() == other.dtype(), extend);
218        let other = other.to_physical_repr();
219        self.0.extend(other.as_ref().as_ref().as_ref())?;
220        Ok(())
221    }
222
223    fn filter(&self, filter: &BooleanChunked) -> PolarsResult<Series> {
224        self.0.filter(filter).map(|ca| {
225            ca.into_datetime(self.0.time_unit(), self.0.time_zone().clone())
226                .into_series()
227        })
228    }
229
230    fn take(&self, indices: &IdxCa) -> PolarsResult<Series> {
231        let ca = self.0.take(indices)?;
232        Ok(ca
233            .into_datetime(self.0.time_unit(), self.0.time_zone().clone())
234            .into_series())
235    }
236
237    unsafe fn take_unchecked(&self, indices: &IdxCa) -> Series {
238        let ca = self.0.take_unchecked(indices);
239        ca.into_datetime(self.0.time_unit(), self.0.time_zone().clone())
240            .into_series()
241    }
242
243    fn take_slice(&self, indices: &[IdxSize]) -> PolarsResult<Series> {
244        let ca = self.0.take(indices)?;
245        Ok(ca
246            .into_datetime(self.0.time_unit(), self.0.time_zone().clone())
247            .into_series())
248    }
249
250    unsafe fn take_slice_unchecked(&self, indices: &[IdxSize]) -> Series {
251        let ca = self.0.take_unchecked(indices);
252        ca.into_datetime(self.0.time_unit(), self.0.time_zone().clone())
253            .into_series()
254    }
255
256    fn len(&self) -> usize {
257        self.0.len()
258    }
259
260    fn rechunk(&self) -> Series {
261        self.0
262            .rechunk()
263            .into_datetime(self.0.time_unit(), self.0.time_zone().clone())
264            .into_series()
265    }
266
267    fn new_from_index(&self, index: usize, length: usize) -> Series {
268        self.0
269            .new_from_index(index, length)
270            .into_datetime(self.0.time_unit(), self.0.time_zone().clone())
271            .into_series()
272    }
273
274    fn cast(&self, dtype: &DataType, cast_options: CastOptions) -> PolarsResult<Series> {
275        match dtype {
276            DataType::String => Ok(self.0.to_string("iso")?.into_series()),
277            _ => self.0.cast_with_options(dtype, cast_options),
278        }
279    }
280
281    #[inline]
282    unsafe fn get_unchecked(&self, index: usize) -> AnyValue {
283        self.0.get_any_value_unchecked(index)
284    }
285
286    fn sort_with(&self, options: SortOptions) -> PolarsResult<Series> {
287        Ok(self
288            .0
289            .sort_with(options)
290            .into_datetime(self.0.time_unit(), self.0.time_zone().clone())
291            .into_series())
292    }
293
294    fn arg_sort(&self, options: SortOptions) -> IdxCa {
295        self.0.arg_sort(options)
296    }
297
298    fn null_count(&self) -> usize {
299        self.0.null_count()
300    }
301
302    fn has_nulls(&self) -> bool {
303        self.0.has_nulls()
304    }
305
306    #[cfg(feature = "algorithm_group_by")]
307    fn unique(&self) -> PolarsResult<Series> {
308        self.0.unique().map(|ca| {
309            ca.into_datetime(self.0.time_unit(), self.0.time_zone().clone())
310                .into_series()
311        })
312    }
313
314    #[cfg(feature = "algorithm_group_by")]
315    fn n_unique(&self) -> PolarsResult<usize> {
316        self.0.n_unique()
317    }
318
319    #[cfg(feature = "algorithm_group_by")]
320    fn arg_unique(&self) -> PolarsResult<IdxCa> {
321        self.0.arg_unique()
322    }
323
324    fn is_null(&self) -> BooleanChunked {
325        self.0.is_null()
326    }
327
328    fn is_not_null(&self) -> BooleanChunked {
329        self.0.is_not_null()
330    }
331
332    fn reverse(&self) -> Series {
333        self.0
334            .reverse()
335            .into_datetime(self.0.time_unit(), self.0.time_zone().clone())
336            .into_series()
337    }
338
339    fn as_single_ptr(&mut self) -> PolarsResult<usize> {
340        self.0.as_single_ptr()
341    }
342
343    fn shift(&self, periods: i64) -> Series {
344        self.0
345            .shift(periods)
346            .into_datetime(self.0.time_unit(), self.0.time_zone().clone())
347            .into_series()
348    }
349
350    fn max_reduce(&self) -> PolarsResult<Scalar> {
351        let sc = self.0.max_reduce();
352
353        Ok(Scalar::new(self.dtype().clone(), sc.value().clone()))
354    }
355
356    fn min_reduce(&self) -> PolarsResult<Scalar> {
357        let sc = self.0.min_reduce();
358
359        Ok(Scalar::new(self.dtype().clone(), sc.value().clone()))
360    }
361
362    fn median_reduce(&self) -> PolarsResult<Scalar> {
363        let av: AnyValue = self.median().map(|v| v as i64).into();
364        Ok(Scalar::new(self.dtype().clone(), av))
365    }
366
367    fn quantile_reduce(&self, _quantile: f64, _method: QuantileMethod) -> PolarsResult<Scalar> {
368        Ok(Scalar::new(self.dtype().clone(), AnyValue::Null))
369    }
370
371    fn clone_inner(&self) -> Arc<dyn SeriesTrait> {
372        Arc::new(SeriesWrap(Clone::clone(&self.0)))
373    }
374
375    fn as_any(&self) -> &dyn Any {
376        &self.0
377    }
378
379    fn as_any_mut(&mut self) -> &mut dyn Any {
380        &mut self.0
381    }
382
383    fn as_arc_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {
384        self as _
385    }
386}