polars_core/chunked_array/temporal/
conversion.rs

1use arrow::temporal_conversions::*;
2use chrono::*;
3
4use crate::prelude::*;
5
6pub(crate) const NS_IN_DAY: i64 = 86_400_000_000_000;
7pub(crate) const US_IN_DAY: i64 = 86_400_000_000;
8pub(crate) const MS_IN_DAY: i64 = 86_400_000;
9pub(crate) const SECONDS_IN_DAY: i64 = 86_400;
10
11impl From<&AnyValue<'_>> for NaiveDateTime {
12    fn from(v: &AnyValue) -> Self {
13        match v {
14            #[cfg(feature = "dtype-date")]
15            AnyValue::Date(v) => date32_to_datetime(*v),
16            #[cfg(feature = "dtype-datetime")]
17            AnyValue::Datetime(v, tu, _) => match tu {
18                TimeUnit::Nanoseconds => timestamp_ns_to_datetime(*v),
19                TimeUnit::Microseconds => timestamp_us_to_datetime(*v),
20                TimeUnit::Milliseconds => timestamp_ms_to_datetime(*v),
21            },
22            _ => panic!("can only convert date/datetime to NaiveDateTime"),
23        }
24    }
25}
26
27impl From<&AnyValue<'_>> for NaiveTime {
28    fn from(v: &AnyValue) -> Self {
29        match v {
30            #[cfg(feature = "dtype-time")]
31            AnyValue::Time(v) => time64ns_to_time(*v),
32            _ => panic!("can only convert date/datetime to NaiveTime"),
33        }
34    }
35}
36
37// Used by lazy for literal conversion
38pub fn datetime_to_timestamp_ns(v: NaiveDateTime) -> i64 {
39    let us = v.and_utc().timestamp() * 1_000_000_000; //nanos
40    us + v.and_utc().timestamp_subsec_nanos() as i64
41}
42
43pub fn datetime_to_timestamp_ms(v: NaiveDateTime) -> i64 {
44    v.and_utc().timestamp_millis()
45}
46
47pub fn datetime_to_timestamp_us(v: NaiveDateTime) -> i64 {
48    let us = v.and_utc().timestamp() * 1_000_000;
49    us + v.and_utc().timestamp_subsec_micros() as i64
50}
51
52pub(crate) fn naive_datetime_to_date(v: NaiveDateTime) -> i32 {
53    (datetime_to_timestamp_ms(v) / (MILLISECONDS * SECONDS_IN_DAY)) as i32
54}
55
56pub fn get_strftime_format(fmt: &str, dtype: &DataType) -> PolarsResult<String> {
57    if fmt == "polars" && !matches!(dtype, DataType::Duration(_)) {
58        polars_bail!(InvalidOperation: "'polars' is not a valid `to_string` format for {} dtype expressions", dtype);
59    } else {
60        let format_string = if fmt != "iso" && fmt != "iso:strict" {
61            fmt.to_string()
62        } else {
63            let sep = if fmt == "iso" { " " } else { "T" };
64            #[allow(unreachable_code)]
65            match dtype {
66                #[cfg(feature = "dtype-datetime")]
67                DataType::Datetime(tu, tz) => match (tu, tz.is_some()) {
68                    (TimeUnit::Milliseconds, true) => format!("%F{}%T%.3f%:z", sep),
69                    (TimeUnit::Milliseconds, false) => format!("%F{}%T%.3f", sep),
70                    (TimeUnit::Microseconds, true) => format!("%F{}%T%.6f%:z", sep),
71                    (TimeUnit::Microseconds, false) => format!("%F{}%T%.6f", sep),
72                    (TimeUnit::Nanoseconds, true) => format!("%F{}%T%.9f%:z", sep),
73                    (TimeUnit::Nanoseconds, false) => format!("%F{}%T%.9f", sep),
74                },
75                #[cfg(feature = "dtype-date")]
76                DataType::Date => "%F".to_string(),
77                #[cfg(feature = "dtype-time")]
78                DataType::Time => "%T%.f".to_string(),
79                _ => {
80                    let err = format!(
81                        "invalid call to `get_strftime_format`; fmt={:?}, dtype={}",
82                        fmt, dtype
83                    );
84                    unimplemented!("{}", err)
85                },
86            }
87        };
88        Ok(format_string)
89    }
90}