19
19
//! assert!(read_query.is_ok());
20
20
//! ```
21
21
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;
22
32
pub mod read_query;
23
33
pub mod write_query;
24
-
25
34
use std:: fmt;
26
35
27
36
use crate :: { Error , ReadQuery , WriteQuery } ;
28
37
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 ) ]
30
42
pub enum Timestamp {
31
43
Now ,
32
44
Nanoseconds ( usize ) ,
@@ -48,6 +60,47 @@ impl fmt::Display for Timestamp {
48
60
}
49
61
}
50
62
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
+
51
104
/// Internal enum used to represent either type of query.
52
105
pub enum QueryTypes < ' a > {
53
106
Read ( & ' a ReadQuery ) ,
@@ -157,8 +210,17 @@ pub enum QueryType {
157
210
158
211
#[ cfg( test) ]
159
212
mod 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
+ } ;
160
221
use crate :: query:: { Timestamp , ValidQuery } ;
161
-
222
+ #[ cfg( feature = "chrono_timestamps" ) ]
223
+ use chrono:: prelude:: { DateTime , TimeZone , Utc } ;
162
224
#[ test]
163
225
fn test_equality_str ( ) {
164
226
assert_eq ! ( ValidQuery :: from( "hello" ) , "hello" ) ;
@@ -181,4 +243,85 @@ mod tests {
181
243
fn test_format_for_timestamp_else ( ) {
182
244
assert ! ( format!( "{}" , Timestamp :: Nanoseconds ( 100 ) ) == "100" ) ;
183
245
}
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
+ }
184
327
}
0 commit comments