tantivy_common/
datetime.rs1use std::fmt;
2use std::io::{Read, Write};
3
4use serde::{Deserialize, Serialize};
5use time::format_description::well_known::Rfc3339;
6use time::{OffsetDateTime, PrimitiveDateTime, UtcOffset};
7
8use crate::BinarySerializable;
9
10#[derive(
13 Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Default,
14)]
15#[serde(rename_all = "lowercase")]
16pub enum DateTimePrecision {
17 #[default]
19 Seconds,
20 Milliseconds,
22 Microseconds,
24 Nanoseconds,
26}
27
28#[derive(Clone, Default, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
39pub struct DateTime {
40 pub(crate) timestamp_nanos: i64,
42}
43
44impl DateTime {
45 pub const MIN: DateTime = DateTime {
47 timestamp_nanos: i64::MIN,
48 };
49
50 pub const MAX: DateTime = DateTime {
52 timestamp_nanos: i64::MAX,
53 };
54
55 pub const fn from_timestamp_secs(seconds: i64) -> Self {
57 Self {
58 timestamp_nanos: seconds * 1_000_000_000,
59 }
60 }
61
62 pub const fn from_timestamp_millis(milliseconds: i64) -> Self {
64 Self {
65 timestamp_nanos: milliseconds * 1_000_000,
66 }
67 }
68
69 pub const fn from_timestamp_micros(microseconds: i64) -> Self {
71 Self {
72 timestamp_nanos: microseconds * 1_000,
73 }
74 }
75
76 pub const fn from_timestamp_nanos(nanoseconds: i64) -> Self {
78 Self {
79 timestamp_nanos: nanoseconds,
80 }
81 }
82
83 pub fn from_utc(dt: OffsetDateTime) -> Self {
88 let timestamp_nanos = dt.unix_timestamp_nanos() as i64;
89 Self { timestamp_nanos }
90 }
91
92 pub fn from_primitive(dt: PrimitiveDateTime) -> Self {
98 Self::from_utc(dt.assume_utc())
99 }
100
101 pub const fn into_timestamp_secs(self) -> i64 {
103 self.timestamp_nanos / 1_000_000_000
104 }
105
106 pub const fn into_timestamp_millis(self) -> i64 {
108 self.timestamp_nanos / 1_000_000
109 }
110
111 pub const fn into_timestamp_micros(self) -> i64 {
113 self.timestamp_nanos / 1_000
114 }
115
116 pub const fn into_timestamp_nanos(self) -> i64 {
118 self.timestamp_nanos
119 }
120
121 pub fn into_utc(self) -> OffsetDateTime {
123 let utc_datetime = OffsetDateTime::from_unix_timestamp_nanos(self.timestamp_nanos as i128)
124 .expect("valid UNIX timestamp");
125 debug_assert_eq!(UtcOffset::UTC, utc_datetime.offset());
126 utc_datetime
127 }
128
129 pub fn into_offset(self, offset: UtcOffset) -> OffsetDateTime {
131 self.into_utc().to_offset(offset)
132 }
133
134 pub fn into_primitive(self) -> PrimitiveDateTime {
139 let utc_datetime = self.into_utc();
140 debug_assert_eq!(UtcOffset::UTC, utc_datetime.offset());
142 PrimitiveDateTime::new(utc_datetime.date(), utc_datetime.time())
143 }
144
145 pub fn truncate(self, precision: DateTimePrecision) -> Self {
147 let truncated_timestamp_micros = match precision {
148 DateTimePrecision::Seconds => (self.timestamp_nanos / 1_000_000_000) * 1_000_000_000,
149 DateTimePrecision::Milliseconds => (self.timestamp_nanos / 1_000_000) * 1_000_000,
150 DateTimePrecision::Microseconds => (self.timestamp_nanos / 1_000) * 1_000,
151 DateTimePrecision::Nanoseconds => self.timestamp_nanos,
152 };
153 Self {
154 timestamp_nanos: truncated_timestamp_micros,
155 }
156 }
157}
158
159impl fmt::Debug for DateTime {
160 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
161 let utc_rfc3339 = self.into_utc().format(&Rfc3339).map_err(|_| fmt::Error)?;
162 f.write_str(&utc_rfc3339)
163 }
164}
165
166impl BinarySerializable for DateTime {
167 fn serialize<W: Write + ?Sized>(&self, writer: &mut W) -> std::io::Result<()> {
168 let timestamp_micros = self.into_timestamp_micros();
169 <i64 as BinarySerializable>::serialize(×tamp_micros, writer)
170 }
171
172 fn deserialize<R: Read>(reader: &mut R) -> std::io::Result<Self> {
173 let timestamp_micros = <i64 as BinarySerializable>::deserialize(reader)?;
174 Ok(Self::from_timestamp_micros(timestamp_micros))
175 }
176}