1919//! assert!(read_query.is_ok());
2020//! ```
2121
22+ #[ cfg( feature = "chrono_timestamps" ) ]
23+ extern crate chrono;
24+
25+ #[ cfg( feature = "chrono_timestamps" ) ]
26+ use chrono:: prelude:: { DateTime , TimeZone , Utc } ;
27+ #[ cfg( feature = "chrono_timestamps" ) ]
28+ use std:: convert:: TryInto ;
29+
30+ #[ cfg( feature = "chrono_timestamps" ) ]
31+ pub mod consts;
2232pub mod read_query;
2333pub mod write_query;
24-
2534use std:: fmt;
2635
2736use crate :: { Error , ReadQuery , WriteQuery } ;
2837
29- #[ derive( PartialEq ) ]
38+ #[ cfg( feature = "chrono_timestamps" ) ]
39+ use consts:: { MILLIS_PER_SECOND , MINUTES_PER_HOUR , NANOS_PER_MILLI , SECONDS_PER_MINUTE } ;
40+
41+ #[ derive( PartialEq , Debug , Copy , Clone ) ]
3042pub enum Timestamp {
3143 Now ,
3244 Nanoseconds ( usize ) ,
@@ -48,6 +60,47 @@ impl fmt::Display for Timestamp {
4860 }
4961}
5062
63+ #[ cfg( feature = "chrono_timestamps" ) ]
64+ impl Into < DateTime < Utc > > for Timestamp {
65+ fn into ( self ) -> DateTime < Utc > {
66+ match self {
67+ Timestamp :: Now => Utc :: now ( ) ,
68+ Timestamp :: Hours ( h) => {
69+ let nanos =
70+ h * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI ;
71+ Utc . timestamp_nanos ( nanos. try_into ( ) . unwrap ( ) )
72+ }
73+ Timestamp :: Minutes ( m) => {
74+ let nanos = m * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI ;
75+ Utc . timestamp_nanos ( nanos. try_into ( ) . unwrap ( ) )
76+ }
77+ Timestamp :: Seconds ( s) => {
78+ let nanos = s * MILLIS_PER_SECOND * NANOS_PER_MILLI ;
79+ Utc . timestamp_nanos ( nanos. try_into ( ) . unwrap ( ) )
80+ }
81+ Timestamp :: Milliseconds ( millis) => {
82+ let nanos = millis * NANOS_PER_MILLI ;
83+ Utc . timestamp_nanos ( nanos. try_into ( ) . unwrap ( ) )
84+ }
85+ Timestamp :: Nanoseconds ( nanos) => Utc . timestamp_nanos ( nanos. try_into ( ) . unwrap ( ) ) ,
86+ Timestamp :: Microseconds ( mis) => {
87+ let nanos = mis / 10000 ;
88+ Utc . timestamp_nanos ( nanos. try_into ( ) . unwrap ( ) )
89+ }
90+ }
91+ }
92+ }
93+
94+ #[ cfg( feature = "chrono_timestamps" ) ]
95+ impl < T > From < DateTime < T > > for Timestamp
96+ where
97+ T : TimeZone ,
98+ {
99+ fn from ( date_time : DateTime < T > ) -> Self {
100+ Timestamp :: Nanoseconds ( date_time. timestamp_nanos ( ) as usize )
101+ }
102+ }
103+
51104/// Internal enum used to represent either type of query.
52105pub enum QueryTypes < ' a > {
53106 Read ( & ' a ReadQuery ) ,
@@ -157,8 +210,17 @@ pub enum QueryType {
157210
158211#[ cfg( test) ]
159212mod tests {
213+ #[ cfg( feature = "chrono_timestamps" ) ]
214+ use std:: convert:: TryInto ;
215+ #[ cfg( feature = "chrono_timestamps" ) ]
216+ extern crate chrono;
217+ #[ cfg( feature = "chrono_timestamps" ) ]
218+ use super :: consts:: {
219+ MICROS_PER_NANO , MILLIS_PER_SECOND , MINUTES_PER_HOUR , NANOS_PER_MILLI , SECONDS_PER_MINUTE ,
220+ } ;
160221 use crate :: query:: { Timestamp , ValidQuery } ;
161-
222+ #[ cfg( feature = "chrono_timestamps" ) ]
223+ use chrono:: prelude:: { DateTime , TimeZone , Utc } ;
162224 #[ test]
163225 fn test_equality_str ( ) {
164226 assert_eq ! ( ValidQuery :: from( "hello" ) , "hello" ) ;
@@ -181,4 +243,85 @@ mod tests {
181243 fn test_format_for_timestamp_else ( ) {
182244 assert ! ( format!( "{}" , Timestamp :: Nanoseconds ( 100 ) ) == "100" ) ;
183245 }
246+
247+ #[ cfg( feature = "chrono_timestamps" ) ]
248+ #[ test]
249+ fn test_chrono_datetime_from_timestamp_now ( ) {
250+ let datetime_from_timestamp: DateTime < Utc > = Timestamp :: Now . into ( ) ;
251+ assert_eq ! ( Utc :: now( ) . date( ) , datetime_from_timestamp. date( ) )
252+ }
253+ #[ cfg( feature = "chrono_timestamps" ) ]
254+ #[ test]
255+ fn test_chrono_datetime_from_timestamp_hours ( ) {
256+ let datetime_from_timestamp: DateTime < Utc > = Timestamp :: Hours ( 2 ) . into ( ) ;
257+ assert_eq ! (
258+ Utc . timestamp_nanos(
259+ ( 2 * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI )
260+ . try_into( )
261+ . unwrap( )
262+ ) ,
263+ datetime_from_timestamp
264+ )
265+ }
266+ #[ cfg( feature = "chrono_timestamps" ) ]
267+ #[ test]
268+ fn test_chrono_datetime_from_timestamp_minutes ( ) {
269+ let datetime_from_timestamp: DateTime < Utc > = Timestamp :: Minutes ( 2 ) . into ( ) ;
270+ assert_eq ! (
271+ Utc . timestamp_nanos(
272+ ( 2 * SECONDS_PER_MINUTE * MILLIS_PER_SECOND * NANOS_PER_MILLI )
273+ . try_into( )
274+ . unwrap( )
275+ ) ,
276+ datetime_from_timestamp
277+ )
278+ }
279+ #[ cfg( feature = "chrono_timestamps" ) ]
280+ #[ test]
281+ fn test_chrono_datetime_from_timestamp_seconds ( ) {
282+ let datetime_from_timestamp: DateTime < Utc > = Timestamp :: Seconds ( 2 ) . into ( ) ;
283+ assert_eq ! (
284+ Utc . timestamp_nanos(
285+ ( 2 * MILLIS_PER_SECOND * NANOS_PER_MILLI )
286+ . try_into( )
287+ . unwrap( )
288+ ) ,
289+ datetime_from_timestamp
290+ )
291+ }
292+ #[ cfg( feature = "chrono_timestamps" ) ]
293+ #[ test]
294+ fn test_chrono_datetime_from_timestamp_millis ( ) {
295+ let datetime_from_timestamp: DateTime < Utc > = Timestamp :: Milliseconds ( 2 ) . into ( ) ;
296+ assert_eq ! (
297+ Utc . timestamp_nanos( ( 2 * NANOS_PER_MILLI ) . try_into( ) . unwrap( ) ) ,
298+ datetime_from_timestamp
299+ )
300+ }
301+
302+ #[ cfg( feature = "chrono_timestamps" ) ]
303+ #[ test]
304+ fn test_chrono_datetime_from_timestamp_nanos ( ) {
305+ let datetime_from_timestamp: DateTime < Utc > = Timestamp :: Nanoseconds ( 1 ) . into ( ) ;
306+ assert_eq ! ( Utc . timestamp_nanos( 1 ) , datetime_from_timestamp)
307+ }
308+ #[ cfg( feature = "chrono_timestamps" ) ]
309+ #[ test]
310+ fn test_chrono_datetime_from_timestamp_micros ( ) {
311+ let datetime_from_timestamp: DateTime < Utc > = Timestamp :: Microseconds ( 1 ) . into ( ) ;
312+ assert_eq ! (
313+ Utc . timestamp_nanos( ( 1 / MICROS_PER_NANO ) . try_into( ) . unwrap( ) ) ,
314+ datetime_from_timestamp
315+ )
316+ }
317+
318+ #[ cfg( feature = "chrono_timestamps" ) ]
319+ #[ test]
320+ fn test_timestamp_from_chrono_date ( ) {
321+ let timestamp_from_datetime: Timestamp = Utc . ymd ( 1970 , 1 , 1 ) . and_hms ( 0 , 0 , 1 ) . into ( ) ;
322+ assert_eq ! (
323+ Timestamp :: Nanoseconds ( MILLIS_PER_SECOND * NANOS_PER_MILLI ) ,
324+ timestamp_from_datetime
325+ )
326+ }
184327}
0 commit comments