@@ -13,6 +13,8 @@ use hex::{self, FromHexError};
13
13
14
14
use rand:: { thread_rng, Rng } ;
15
15
16
+ use chrono:: Utc ;
17
+
16
18
const TIMESTAMP_SIZE : usize = 4 ;
17
19
const PROCESS_ID_SIZE : usize = 5 ;
18
20
const COUNTER_SIZE : usize = 3 ;
@@ -114,6 +116,14 @@ impl ObjectId {
114
116
}
115
117
}
116
118
119
+ /// Retrieves the timestamp (chrono::DateTime) from an ObjectId.
120
+ pub fn timestamp ( & self ) -> chrono:: DateTime < Utc > {
121
+ let seconds_since_epoch = BigEndian :: read_u32 ( & self . id ) ;
122
+ let naive_datetime = chrono:: NaiveDateTime :: from_timestamp ( seconds_since_epoch as i64 , 0 ) ;
123
+ let timestamp: chrono:: DateTime < Utc > = chrono:: DateTime :: from_utc ( naive_datetime, Utc ) ;
124
+ timestamp
125
+ }
126
+
117
127
/// Returns the raw byte representation of an ObjectId.
118
128
pub fn bytes ( & self ) -> [ u8 ; 12 ] {
119
129
self . id
@@ -204,16 +214,40 @@ fn count_generated_is_big_endian() {
204
214
assert_eq ! ( 0x33u8 , oid. bytes( ) [ COUNTER_OFFSET + 2 ] ) ;
205
215
}
206
216
207
- #[ test]
208
- fn test_display ( ) {
209
- let id = ObjectId :: with_string ( "53e37d08776f724e42000000" ) . unwrap ( ) ;
217
+ #[ cfg ( test) ]
218
+ mod test {
219
+ use chrono :: { offset :: TimeZone , Utc } ;
210
220
211
- assert_eq ! ( format!( "{}" , id) , "53e37d08776f724e42000000" )
212
- }
221
+ #[ test]
222
+ fn test_display ( ) {
223
+ let id = super :: ObjectId :: with_string ( "53e37d08776f724e42000000" ) . unwrap ( ) ;
213
224
214
- #[ test]
215
- fn test_debug ( ) {
216
- let id = ObjectId :: with_string ( "53e37d08776f724e42000000" ) . unwrap ( ) ;
225
+ assert_eq ! ( format!( "{}" , id) , "53e37d08776f724e42000000" )
226
+ }
217
227
218
- assert_eq ! ( format!( "{:?}" , id) , "ObjectId(53e37d08776f724e42000000)" )
228
+ #[ test]
229
+ fn test_debug ( ) {
230
+ let id = super :: ObjectId :: with_string ( "53e37d08776f724e42000000" ) . unwrap ( ) ;
231
+
232
+ assert_eq ! ( format!( "{:?}" , id) , "ObjectId(53e37d08776f724e42000000)" )
233
+ }
234
+
235
+ #[ test]
236
+ fn test_timestamp ( ) {
237
+ let id = super :: ObjectId :: with_string ( "000000000000000000000000" ) . unwrap ( ) ;
238
+ // "Jan 1st, 1970 00:00:00 UTC"
239
+ assert_eq ! ( Utc . ymd( 1970 , 1 , 1 ) . and_hms( 0 , 0 , 0 ) , id. timestamp( ) ) ;
240
+
241
+ let id = super :: ObjectId :: with_string ( "7FFFFFFF0000000000000000" ) . unwrap ( ) ;
242
+ // "Jan 19th, 2038 03:14:07 UTC"
243
+ assert_eq ! ( Utc . ymd( 2038 , 1 , 19 ) . and_hms( 3 , 14 , 7 ) , id. timestamp( ) ) ;
244
+
245
+ let id = super :: ObjectId :: with_string ( "800000000000000000000000" ) . unwrap ( ) ;
246
+ // "Jan 19th, 2038 03:14:08 UTC"
247
+ assert_eq ! ( Utc . ymd( 2038 , 1 , 19 ) . and_hms( 3 , 14 , 8 ) , id. timestamp( ) ) ;
248
+
249
+ let id = super :: ObjectId :: with_string ( "FFFFFFFF0000000000000000" ) . unwrap ( ) ;
250
+ // "Feb 7th, 2106 06:28:15 UTC"
251
+ assert_eq ! ( Utc . ymd( 2106 , 2 , 7 ) . and_hms( 6 , 28 , 15 ) , id. timestamp( ) ) ;
252
+ }
219
253
}
0 commit comments