1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
use super::*;
use polars_arrow::export::arrow::temporal_conversions::{
    MICROSECONDS, MILLISECONDS, MILLISECONDS_IN_DAY, NANOSECONDS, SECONDS_IN_DAY,
};

const NANOSECONDS_IN_MILLISECOND: i64 = 1_000_000;
const SECONDS_IN_HOUR: i64 = 3600;

pub trait DurationMethods {
    /// Extract the hours from a `Duration`
    fn hours(&self) -> Int64Chunked;

    /// Extract the days from a `Duration`
    fn days(&self) -> Int64Chunked;

    /// Extract the milliseconds from a `Duration`
    fn milliseconds(&self) -> Int64Chunked;

    /// Extract the nanoseconds from a `Duration`
    fn nanoseconds(&self) -> Int64Chunked;

    /// Extract the seconds from a `Duration`
    fn seconds(&self) -> Int64Chunked;
}

impl DurationMethods for DurationChunked {
    /// Extract the hours from a `Duration`
    fn hours(&self) -> Int64Chunked {
        match self.time_unit() {
            TimeUnit::Milliseconds => &self.0 / (MILLISECONDS * SECONDS_IN_HOUR),
            TimeUnit::Microseconds => &self.0 / (MICROSECONDS * SECONDS_IN_HOUR),
            TimeUnit::Nanoseconds => &self.0 / (NANOSECONDS * SECONDS_IN_HOUR),
        }
    }

    /// Extract the days from a `Duration`
    fn days(&self) -> Int64Chunked {
        match self.time_unit() {
            TimeUnit::Milliseconds => &self.0 / MILLISECONDS_IN_DAY,
            TimeUnit::Microseconds => &self.0 / (MICROSECONDS * SECONDS_IN_DAY),
            TimeUnit::Nanoseconds => &self.0 / (NANOSECONDS * SECONDS_IN_DAY),
        }
    }

    /// Extract the milliseconds from a `Duration`
    fn milliseconds(&self) -> Int64Chunked {
        match self.time_unit() {
            TimeUnit::Milliseconds => self.0.clone(),
            TimeUnit::Microseconds => self.0.clone() / 1000,
            TimeUnit::Nanoseconds => &self.0 / 1_000_000,
        }
    }

    /// Extract the nanoseconds from a `Duration`
    fn nanoseconds(&self) -> Int64Chunked {
        match self.time_unit() {
            TimeUnit::Milliseconds => &self.0 * NANOSECONDS_IN_MILLISECOND,
            TimeUnit::Microseconds => &self.0 * 1000,
            TimeUnit::Nanoseconds => self.0.clone(),
        }
    }

    /// Extract the seconds from a `Duration`
    fn seconds(&self) -> Int64Chunked {
        match self.time_unit() {
            TimeUnit::Milliseconds => &self.0 / MILLISECONDS,
            TimeUnit::Microseconds => &self.0 / MICROSECONDS,
            TimeUnit::Nanoseconds => &self.0 / NANOSECONDS,
        }
    }
}