sqldatetime/
lib.rs

1//! This crate provides SQL date/time types.
2//!
3//! # Feature Flags
4//!
5//!- `serde`: Enable `serde`-based serialization and deserialization. Not enabled by default.
6//!- `oracle`: Enable Oracle oriented datetime type: `OracleDate`. Not enabled by default.
7
8#![cfg_attr(docsrs, feature(doc_cfg))]
9
10#[macro_use]
11mod util;
12
13mod common;
14mod date;
15mod error;
16mod format;
17mod interval;
18mod time;
19mod timestamp;
20
21mod local;
22#[cfg(feature = "oracle")]
23mod oracle;
24#[cfg(feature = "serde")]
25mod serialize;
26
27pub use crate::date::{Date, Month, WeekDay};
28pub use crate::error::Error;
29pub use crate::format::Formatter;
30pub use crate::interval::{IntervalDT, IntervalYM, Sign};
31pub use crate::time::Time;
32pub use crate::timestamp::Timestamp;
33
34#[cfg(feature = "oracle")]
35pub use crate::oracle::Date as OracleDate;
36
37/// General trait for all date time types.
38pub trait DateTime {
39    /// Extracts year from date time.
40    fn year(&self) -> Option<i32>;
41    /// Extracts month from date time.
42    fn month(&self) -> Option<i32>;
43    /// Extracts day from date time.
44    fn day(&self) -> Option<i32>;
45    /// Extracts hour from date time.
46    fn hour(&self) -> Option<i32>;
47    /// Extracts minute from date time.
48    fn minute(&self) -> Option<i32>;
49    /// Extracts second from date time.
50    fn second(&self) -> Option<f64>;
51    /// Extracts second from date time.
52    fn date(&self) -> Option<Date>;
53}
54
55/// Trunc trait for Timestamp/Date/OracleDate
56pub trait Trunc: Sized {
57    /// Truncates to the first day of the century.
58    ///
59    /// ## Example
60    ///
61    /// ```
62    /// use sqldatetime::{Timestamp, Date, Time, Trunc};
63    ///
64    /// let timestamp = Date::try_from_ymd(2021, 10, 1).unwrap().and_time(Time::ZERO);
65    /// let result = Date::try_from_ymd(2001, 1, 1).unwrap().and_time(Time::ZERO);
66    /// assert_eq!(timestamp.trunc_century().unwrap(), result);
67    /// ```
68    fn trunc_century(self) -> Result<Self, Error>;
69
70    /// Truncates to the first day of the year.
71    ///
72    /// ## Example
73    ///
74    /// ```
75    /// use sqldatetime::{Timestamp, Date, Time, Trunc};
76    ///
77    /// let timestamp = Date::try_from_ymd(2021, 10, 1).unwrap().and_time(Time::ZERO);
78    /// let result = Date::try_from_ymd(2021, 1, 1).unwrap().and_time(Time::ZERO);
79    /// assert_eq!(timestamp.trunc_year().unwrap(), result);
80    /// ```
81    fn trunc_year(self) -> Result<Self, Error>;
82
83    /// Truncates to the first day of the first week in the year.
84    ///
85    /// ## Example
86    ///
87    /// ```
88    /// use sqldatetime::{Timestamp, Date, Time, Trunc};
89    ///
90    /// let timestamp = Date::try_from_ymd(2021, 10, 1).unwrap().and_time(Time::ZERO);
91    /// let result = Date::try_from_ymd(2021, 1, 4).unwrap().and_time(Time::ZERO);
92    /// assert_eq!(timestamp.trunc_iso_year().unwrap(), result);
93    /// ```
94    fn trunc_iso_year(self) -> Result<Self, Error>;
95
96    /// Truncates to the first day of the quarter.
97    ///
98    /// ## Example
99    ///
100    /// ```
101    /// use sqldatetime::{Timestamp, Date, Time, Trunc};
102    ///
103    /// let timestamp = Date::try_from_ymd(2021, 11, 1).unwrap().and_time(Time::ZERO);
104    /// let result = Date::try_from_ymd(2021, 10, 1).unwrap().and_time(Time::ZERO);
105    /// assert_eq!(timestamp.trunc_quarter().unwrap(), result);
106    /// ```
107    fn trunc_quarter(self) -> Result<Self, Error>;
108
109    /// Truncates to the first day of the month.
110    ///
111    /// ## Example
112    ///
113    /// ```
114    /// use sqldatetime::{Timestamp, Date, Time, Trunc};
115    ///
116    /// let timestamp = Date::try_from_ymd(2021, 10, 24).unwrap().and_time(Time::ZERO);
117    /// let result = Date::try_from_ymd(2021, 10, 1).unwrap().and_time(Time::ZERO);
118    /// assert_eq!(timestamp.trunc_month().unwrap(), result);
119    /// ```
120    fn trunc_month(self) -> Result<Self, Error>;
121
122    /// Truncates to the same day of the week as the first day of the year.
123    ///
124    /// ## Example
125    ///
126    /// ```
127    /// use sqldatetime::{Timestamp, Date, Time, Trunc};
128    ///
129    /// let timestamp = Date::try_from_ymd(2021, 1, 7).unwrap().and_time(Time::ZERO);
130    /// let result = Date::try_from_ymd(2021, 1, 1).unwrap().and_time(Time::ZERO);
131    /// assert_eq!(timestamp.trunc_week().unwrap(), result);
132    /// ```
133    fn trunc_week(self) -> Result<Self, Error>;
134
135    /// Truncates to the monday of the week.
136    ///
137    /// ## Example
138    ///
139    /// ```
140    /// use sqldatetime::{Timestamp, Date, Time, Trunc};
141    ///
142    /// let timestamp = Date::try_from_ymd(2021, 1, 7).unwrap().and_time(Time::ZERO);
143    /// let result = Date::try_from_ymd(2021, 1, 4).unwrap().and_time(Time::ZERO);
144    /// assert_eq!(timestamp.trunc_iso_week().unwrap(), result);
145    /// ```
146    fn trunc_iso_week(self) -> Result<Self, Error>;
147
148    /// Truncates to the same day of the week as the first day of the month.
149    ///
150    /// ## Example
151    ///
152    /// ```
153    /// use sqldatetime::{Timestamp, Date, Time, Trunc};
154    ///
155    /// let timestamp = Date::try_from_ymd(2021, 10, 7).unwrap().and_time(Time::ZERO);
156    /// let result = Date::try_from_ymd(2021, 10, 1).unwrap().and_time(Time::ZERO);
157    /// assert_eq!(timestamp.trunc_month_start_week().unwrap(), result);
158    /// ```
159    fn trunc_month_start_week(self) -> Result<Self, Error>;
160
161    /// Truncates to the day.
162    ///
163    /// ## Example
164    ///
165    /// ```
166    /// use sqldatetime::{Timestamp, Date, Time, Trunc};
167    ///
168    /// let timestamp = Date::try_from_ymd(2021, 10, 1).unwrap().and_time(Time::MAX);
169    /// let result = Date::try_from_ymd(2021, 10, 1).unwrap().and_time(Time::ZERO);
170    /// assert_eq!(timestamp.trunc_day().unwrap(), result);
171    /// ```
172    fn trunc_day(self) -> Result<Self, Error>;
173
174    /// Truncates to the sunday of the week.
175    ///
176    /// ## Example
177    ///
178    /// ```
179    /// use sqldatetime::{Timestamp, Date, Time, Trunc};
180    ///
181    /// let timestamp = Date::try_from_ymd(2021, 1, 7).unwrap().and_time(Time::ZERO);
182    /// let result = Date::try_from_ymd(2021, 1, 3).unwrap().and_time(Time::ZERO);
183    /// assert_eq!(timestamp.trunc_sunday_start_week().unwrap(), result);
184    /// ```
185    fn trunc_sunday_start_week(self) -> Result<Self, Error>;
186
187    /// Truncates to the hour.
188    ///
189    /// ## Example
190    ///
191    /// ```
192    /// use sqldatetime::{Timestamp, Date, Time, Trunc};
193    ///
194    /// let timestamp = Timestamp::new( Date::try_from_ymd(2021, 1, 1).unwrap(), Time::try_from_hms(9, 59, 59, 59).unwrap());
195    /// let result = Timestamp::new( Date::try_from_ymd(2021, 1, 1).unwrap(), Time::try_from_hms(9, 0, 0, 0).unwrap());
196    /// assert_eq!(timestamp.trunc_hour().unwrap(), result);
197    /// ```
198    fn trunc_hour(self) -> Result<Self, Error>;
199
200    /// Truncates to the minute.
201    ///
202    /// ## Example
203    ///
204    /// ```
205    /// use sqldatetime::{Timestamp, Date, Time, Trunc};
206    ///
207    /// let timestamp = Timestamp::new( Date::try_from_ymd(2021, 1, 1).unwrap(), Time::try_from_hms(9, 30, 59, 59).unwrap());
208    /// let result = Timestamp::new( Date::try_from_ymd(2021, 1, 1).unwrap(), Time::try_from_hms(9, 30, 0, 0).unwrap());
209    /// assert_eq!(timestamp.trunc_minute().unwrap(), result);
210    /// ```
211    fn trunc_minute(self) -> Result<Self, Error>;
212}
213
214/// Round trait for Timestamp/Date/OracleDate
215pub trait Round: Sized {
216    /// If year is more than half of century, rounds to the first day of next century, else truncates.
217    ///
218    /// ## Example
219    ///
220    /// ```
221    /// use sqldatetime::{Timestamp, Date, Time, Round};
222    ///
223    /// let timestamp = Date::try_from_ymd(2051, 1, 1).unwrap().and_time(Time::ZERO);
224    /// let result = Date::try_from_ymd(2101, 1, 1).unwrap().and_time(Time::ZERO);
225    /// assert_eq!(timestamp.round_century().unwrap(), result);
226    /// ```
227    fn round_century(self) -> Result<Self, Error>;
228
229    /// If month is bigger than June, rounds to the first day of next year, else truncates.
230    ///
231    /// ## Example
232    ///
233    /// ```
234    /// use sqldatetime::{Timestamp, Date, Time, Round};
235    ///
236    /// let timestamp = Date::try_from_ymd(2021, 7, 1).unwrap().and_time(Time::ZERO);
237    /// let result = Date::try_from_ymd(2022, 1, 1).unwrap().and_time(Time::ZERO);
238    /// assert_eq!(timestamp.round_year().unwrap(), result);
239    /// ```
240    fn round_year(self) -> Result<Self, Error>;
241
242    /// If month is bigger than June, rounds to the first day of week in next year, else truncates.
243    ///
244    /// ## Example
245    ///
246    /// ```
247    /// use sqldatetime::{Timestamp, Date, Time, Round};
248    ///
249    /// let timestamp = Date::try_from_ymd(2000, 12, 31).unwrap().and_time(Time::ZERO);
250    /// let result = Date::try_from_ymd(2001, 1, 1).unwrap().and_time(Time::ZERO);
251    /// assert_eq!(timestamp.round_iso_year().unwrap(), result);
252    /// ```
253    fn round_iso_year(self) -> Result<Self, Error>;
254
255    /// Rounds up on the sixteenth day of the second month of the quarter, else truncates.
256    ///
257    /// ## Example
258    ///
259    /// ```
260    /// use sqldatetime::{Timestamp, Date, Time, Round};
261    ///
262    /// let timestamp = Date::try_from_ymd(2021, 11, 16).unwrap().and_time(Time::ZERO);
263    /// let result = Date::try_from_ymd(2022, 1, 1).unwrap().and_time(Time::ZERO);
264    /// assert_eq!(timestamp.round_quarter().unwrap(), result);
265    /// ```
266    fn round_quarter(self) -> Result<Self, Error>;
267
268    /// Rounds up on the sixteenth day of each month, else truncates.
269    ///
270    /// ## Example
271    ///
272    /// ```
273    /// use sqldatetime::{Timestamp, Date, Time, Round};
274    ///
275    /// let timestamp = Date::try_from_ymd(2021, 12, 16).unwrap().and_time(Time::ZERO);
276    /// let result = Date::try_from_ymd(2022, 1, 1).unwrap().and_time(Time::ZERO);
277    /// assert_eq!(timestamp.round_month().unwrap(), result);
278    /// ```
279    fn round_month(self) -> Result<Self, Error>;
280
281    /// Rounds up on the fifth day of each week, the same day of the week as the first day of the year, else truncates.
282    ///
283    /// ## Example
284    ///
285    /// ```
286    /// use sqldatetime::{Timestamp, Date, Time, Round};
287    ///
288    /// let timestamp = Date::try_from_ymd(2021, 1, 5).unwrap().and_time(Time::ZERO);
289    /// let result = Date::try_from_ymd(2021, 1, 8).unwrap().and_time(Time::ZERO);
290    /// assert_eq!(timestamp.round_week().unwrap(), result);
291    /// ```
292    fn round_week(self) -> Result<Self, Error>;
293
294    /// Rounds up on the fifth day of each week, Monday be the first day of week, else truncates.
295    ///
296    /// ## Example
297    ///
298    /// ```
299    /// use sqldatetime::{Timestamp, Date, Time, Round};
300    ///
301    /// let timestamp = Date::try_from_ymd(2021, 1, 8).unwrap().and_time(Time::ZERO);
302    /// let result = Date::try_from_ymd(2021, 1, 11).unwrap().and_time(Time::ZERO);
303    /// assert_eq!(timestamp.round_iso_week().unwrap(), result);
304    /// ```
305    fn round_iso_week(self) -> Result<Self, Error>;
306
307    /// Rounds up on the fifth day of each week, the same day of the week as the first day of the month, else truncates.
308    ///
309    /// ## Example
310    ///
311    /// ```
312    /// use sqldatetime::{Timestamp, Date, Time, Round};
313    ///
314    /// let timestamp = Date::try_from_ymd(2021, 1, 5).unwrap().and_time(Time::ZERO);
315    /// let result = Date::try_from_ymd(2021, 1, 8).unwrap().and_time(Time::ZERO);
316    /// assert_eq!(timestamp.round_month_start_week().unwrap(), result);
317    /// ```
318    fn round_month_start_week(self) -> Result<Self, Error>;
319
320    /// Rounds up at 12:00 of each day, else truncates.
321    ///
322    /// ## Example
323    ///
324    /// ```
325    /// use sqldatetime::{Timestamp, Date, Time, Round};
326    ///
327    /// let timestamp = Timestamp::new( Date::try_from_ymd(2021, 12, 31).unwrap(), Time::try_from_hms(12, 0, 0, 0).unwrap());
328    /// let result = Date::try_from_ymd(2022, 1, 1).unwrap().and_time(Time::ZERO);
329    /// assert_eq!(timestamp.round_day().unwrap(), result);
330    /// ```
331    fn round_day(self) -> Result<Self, Error>;
332
333    /// Rounds up on the fifth day of each week, Sunday be the first day of week, else truncates.
334    ///
335    /// ## Example
336    ///
337    /// ```
338    /// use sqldatetime::{Timestamp, Date, Time, Round};
339    ///
340    /// let timestamp = Date::try_from_ymd(2021, 1, 8).unwrap().and_time(Time::ZERO);
341    /// let result = Date::try_from_ymd(2021, 1, 10).unwrap().and_time(Time::ZERO);
342    /// assert_eq!(timestamp.round_sunday_start_week().unwrap(), result);
343    /// ```
344    fn round_sunday_start_week(self) -> Result<Self, Error>;
345
346    /// Rounds up at half of each hour, else truncates.
347    ///
348    /// ## Example
349    ///
350    /// ```
351    /// use sqldatetime::{Timestamp, Date, Time, Round};
352    ///
353    /// let timestamp = Timestamp::new( Date::try_from_ymd(2021, 12, 31).unwrap(), Time::try_from_hms(23, 30, 0, 0).unwrap());
354    /// let result = Date::try_from_ymd(2022, 1, 1).unwrap().and_time(Time::ZERO);
355    /// assert_eq!(timestamp.round_hour().unwrap(), result);
356    /// ```
357    fn round_hour(self) -> Result<Self, Error>;
358
359    /// Rounds up at half of each minute, else truncates.
360    ///
361    /// ## Example
362    ///
363    /// ```
364    /// use sqldatetime::{Timestamp, Date, Time, Round};
365    ///
366    /// let timestamp = Timestamp::new( Date::try_from_ymd(2021, 12, 31).unwrap(), Time::try_from_hms(23, 59, 30, 0).unwrap());
367    /// let result = Date::try_from_ymd(2022, 1, 1).unwrap().and_time(Time::ZERO);
368    /// assert_eq!(timestamp.round_minute().unwrap(), result);
369    /// ```
370    fn round_minute(self) -> Result<Self, Error>;
371}