neo4j/value/
time.rs

1// Copyright Rouven Bauer
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//    https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Temporal types based on the [`chrono`] crate.
16
17use duplicate::duplicate_item;
18
19pub type Tz = chrono_tz::Tz;
20pub type FixedOffset = chrono::FixedOffset;
21
22pub type LocalTime = chrono::NaiveTime;
23#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
24pub struct Time {
25    pub time: chrono::NaiveTime,
26    pub offset: FixedOffset,
27}
28pub type Date = chrono::NaiveDate;
29pub type LocalDateTime = chrono::NaiveDateTime;
30pub type DateTime = chrono::DateTime<Tz>;
31pub type DateTimeFixed = chrono::DateTime<FixedOffset>;
32
33const AVERAGE_SECONDS_IN_MONTH: i64 = 2629746;
34const AVERAGE_SECONDS_IN_DAY: i64 = 86400;
35
36// TODO: implement Ord, Neg, Add, Sub, from, into, etc.
37#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
38pub struct Duration {
39    pub(crate) months: i64,
40    pub(crate) days: i64,
41    pub(crate) seconds: i64,
42    pub(crate) nanoseconds: i32,
43}
44
45impl Duration {
46    pub fn new(months: i64, days: i64, seconds: i64, nanoseconds: i32) -> Option<Self> {
47        let seconds = seconds.checked_add(i64::from(nanoseconds) / 1_000_000_000)?;
48        let nanoseconds = nanoseconds % 1_000_000_000;
49        let months_seconds = months.checked_mul(AVERAGE_SECONDS_IN_MONTH)?;
50        let days_seconds = days.checked_mul(AVERAGE_SECONDS_IN_DAY)?;
51        seconds
52            .checked_add(months_seconds)?
53            .checked_add(days_seconds)?;
54        Some(Self {
55            months,
56            days,
57            seconds,
58            nanoseconds,
59        })
60    }
61
62    #[duplicate_item(
63        name            type_;
64        [ months ]      [ i64 ];
65        [ days ]        [ i64 ];
66        [ seconds ]     [ i64 ];
67        [ nanoseconds ] [ i32 ];
68    )]
69    pub fn name(&self) -> type_ {
70        self.name
71    }
72}
73
74pub(crate) fn local_date_time_from_timestamp(secs: i64, nsecs: u32) -> Option<LocalDateTime> {
75    chrono::DateTime::from_timestamp(secs, nsecs).map(|dt| dt.naive_utc())
76}