polars_time/
utils.rs

1#[cfg(feature = "timezones")]
2use arrow::legacy::kernels::{Ambiguous, NonExistent, convert_to_naive_local};
3#[cfg(feature = "timezones")]
4use arrow::legacy::time_zone::Tz;
5#[cfg(feature = "timezones")]
6use chrono::NaiveDateTime;
7#[cfg(feature = "timezones")]
8use chrono::TimeZone;
9#[cfg(feature = "timezones")]
10use chrono_tz::TZ_VARIANTS;
11#[cfg(feature = "timezones")]
12use polars_core::prelude::PolarsResult;
13
14/// Localize datetime according to given time zone.
15///
16/// e.g. '2021-01-01 03:00' -> '2021-01-01 03:00CDT'
17///
18/// Note: this may only return `Ok(None)` if ambiguous is Ambiguous::Null
19/// or if non_existent is NonExistent::Null.
20/// Otherwise, it will either return `Ok(Some(NaiveDateTime))` or `PolarsError`.
21///
22/// Therefore, calling `try_localize_datetime(..., Ambiguous::Raise, NonExistent::Raise)?.unwrap()`
23/// is safe, and will never panic.
24#[cfg(feature = "timezones")]
25pub(crate) fn try_localize_datetime(
26    ndt: NaiveDateTime,
27    tz: &Tz,
28    ambiguous: Ambiguous,
29    non_existent: NonExistent,
30) -> PolarsResult<Option<NaiveDateTime>> {
31    convert_to_naive_local(&chrono_tz::UTC, tz, ndt, ambiguous, non_existent)
32}
33
34#[cfg(feature = "timezones")]
35pub(crate) fn unlocalize_datetime(ndt: NaiveDateTime, tz: &Tz) -> NaiveDateTime {
36    // e.g. '2021-01-01 03:00CDT' -> '2021-01-01 03:00'
37    tz.from_utc_datetime(&ndt).naive_local()
38}
39
40#[cfg(feature = "timezones")]
41pub fn known_timezones() -> [&'static str; TZ_VARIANTS.len()] {
42    core::array::from_fn(|i| TZ_VARIANTS[i].name())
43}