use crate::datatypes::TimeUnit;
use chrono::{NaiveDate, NaiveDateTime, NaiveTime};
pub const SECONDS_IN_DAY: i64 = 86_400;
pub const MILLISECONDS: i64 = 1_000;
pub const MICROSECONDS: i64 = 1_000_000;
pub const NANOSECONDS: i64 = 1_000_000_000;
pub const MILLISECONDS_IN_DAY: i64 = SECONDS_IN_DAY * MILLISECONDS;
pub const EPOCH_DAYS_FROM_CE: i32 = 719_163;
#[inline]
pub fn date32_to_datetime(v: i32) -> NaiveDateTime {
NaiveDateTime::from_timestamp(v as i64 * SECONDS_IN_DAY, 0)
}
#[inline]
pub fn date32_to_date(days: i32) -> NaiveDate {
NaiveDate::from_num_days_from_ce(EPOCH_DAYS_FROM_CE + days)
}
#[inline]
pub fn date64_to_datetime(v: i64) -> NaiveDateTime {
NaiveDateTime::from_timestamp(
v / MILLISECONDS,
(v % MILLISECONDS * MICROSECONDS) as u32,
)
}
#[inline]
pub fn date64_to_date(milliseconds: i64) -> NaiveDate {
date64_to_datetime(milliseconds).date()
}
#[inline]
pub fn time32s_to_time(v: i32) -> NaiveTime {
NaiveTime::from_num_seconds_from_midnight(v as u32, 0)
}
#[inline]
pub fn time32ms_to_time(v: i32) -> NaiveTime {
let v = v as i64;
NaiveTime::from_num_seconds_from_midnight(
(v / MILLISECONDS) as u32,
(v % MILLISECONDS * MICROSECONDS) as u32,
)
}
#[inline]
pub fn time64us_to_time(v: i64) -> NaiveTime {
NaiveTime::from_num_seconds_from_midnight(
(v / MICROSECONDS) as u32,
(v % MICROSECONDS * MILLISECONDS) as u32,
)
}
#[inline]
pub fn time64ns_to_time(v: i64) -> NaiveTime {
NaiveTime::from_num_seconds_from_midnight(
(v / NANOSECONDS) as u32,
(v % NANOSECONDS) as u32,
)
}
#[inline]
pub fn timestamp_s_to_datetime(v: i64) -> NaiveDateTime {
NaiveDateTime::from_timestamp(v, 0)
}
#[inline]
pub fn timestamp_ms_to_datetime(v: i64) -> NaiveDateTime {
NaiveDateTime::from_timestamp(
v / MILLISECONDS,
(v % MILLISECONDS * MICROSECONDS) as u32,
)
}
#[inline]
pub fn timestamp_us_to_datetime(v: i64) -> NaiveDateTime {
NaiveDateTime::from_timestamp(
v / MICROSECONDS,
(v % MICROSECONDS * MILLISECONDS) as u32,
)
}
#[inline]
pub fn timestamp_ns_to_datetime(v: i64) -> NaiveDateTime {
NaiveDateTime::from_timestamp(
v / NANOSECONDS,
(v % NANOSECONDS) as u32,
)
}
pub fn timeunit_scale(a: &TimeUnit, b: &TimeUnit) -> f64 {
match (a, b) {
(TimeUnit::Second, TimeUnit::Second) => 1.0,
(TimeUnit::Second, TimeUnit::Millisecond) => 0.001,
(TimeUnit::Second, TimeUnit::Microsecond) => 0.000_001,
(TimeUnit::Second, TimeUnit::Nanosecond) => 0.000_000_001,
(TimeUnit::Millisecond, TimeUnit::Second) => 1_000.0,
(TimeUnit::Millisecond, TimeUnit::Millisecond) => 1.0,
(TimeUnit::Millisecond, TimeUnit::Microsecond) => 0.001,
(TimeUnit::Millisecond, TimeUnit::Nanosecond) => 0.000_001,
(TimeUnit::Microsecond, TimeUnit::Second) => 1_000_000.0,
(TimeUnit::Microsecond, TimeUnit::Millisecond) => 1_000.0,
(TimeUnit::Microsecond, TimeUnit::Microsecond) => 1.0,
(TimeUnit::Microsecond, TimeUnit::Nanosecond) => 0.001,
(TimeUnit::Nanosecond, TimeUnit::Second) => 1_000_000_000.0,
(TimeUnit::Nanosecond, TimeUnit::Millisecond) => 1_000_000.0,
(TimeUnit::Nanosecond, TimeUnit::Microsecond) => 1_000.0,
(TimeUnit::Nanosecond, TimeUnit::Nanosecond) => 1.0,
}
}