@@ -12,7 +12,7 @@ use std::{
1212use chrono:: { LocalResult , TimeZone , Utc } ;
1313#[ cfg( all(
1414 feature = "serde_with-3" ,
15- any( feature = "chrono-0_4" , feature = "time-0_3" )
15+ any( feature = "chrono-0_4" , feature = "time-0_3" , feature = "jiff-0_2" )
1616) ) ]
1717use serde:: { Deserialize , Deserializer , Serialize } ;
1818use time:: format_description:: well_known:: Rfc3339 ;
@@ -215,6 +215,13 @@ impl crate::DateTime {
215215 Self :: from_millis ( dt. timestamp_millis ( ) )
216216 }
217217
218+ /// Convert the given [`jiff::Timestamp`] into a [`bson::DateTime`](DateTime), truncating it to
219+ /// millisecond precision.
220+ #[ cfg( feature = "jiff-0_2" ) ]
221+ pub fn from_jiff ( ts : jiff:: Timestamp ) -> Self {
222+ Self :: from_millis ( ts. as_millisecond ( ) )
223+ }
224+
218225 /// Returns a builder used to construct a [`DateTime`] from a given year, month,
219226 /// day, and optionally, an hour, minute, second and millisecond, which default to
220227 /// 0 if not explicitly set.
@@ -253,6 +260,32 @@ impl crate::DateTime {
253260 }
254261 }
255262
263+ /// Convert this [`DateTime`] to a [`jiff::Timestamp`].
264+ ///
265+ /// Note: Not every BSON datetime can be represented as a [`jiff::Timestamp`]. For such dates,
266+ /// [`jiff::Timestamp::MIN`] or [`jiff::Timestamp::MAX`] will be returned, whichever
267+ /// is closer.
268+ ///
269+ /// ```
270+ /// let bson_dt = bson::DateTime::now();
271+ /// let jiff_ts = bson_dt.to_jiff();
272+ /// assert_eq!(bson_dt.timestamp_millis(), jiff_ts.as_millisecond());
273+ ///
274+ /// let big = bson::DateTime::from_millis(i64::MAX);
275+ /// let jiff_big = big.to_jiff();
276+ /// assert_eq!(jiff_big, jiff::Timestamp::MAX)
277+ /// ```
278+ #[ cfg( feature = "jiff-0_2" ) ]
279+ pub fn to_jiff ( self ) -> jiff:: Timestamp {
280+ jiff:: Timestamp :: from_millisecond ( self . 0 ) . unwrap_or ( {
281+ if self . 0 < 0 {
282+ jiff:: Timestamp :: MIN
283+ } else {
284+ jiff:: Timestamp :: MAX
285+ }
286+ } )
287+ }
288+
256289 fn from_time_private ( dt : time:: OffsetDateTime ) -> Self {
257290 let millis = dt. unix_timestamp_nanos ( ) / 1_000_000 ;
258291 match millis. try_into ( ) {
@@ -488,6 +521,45 @@ impl serde_with::SerializeAs<chrono::DateTime<Utc>> for crate::DateTime {
488521 }
489522}
490523
524+ #[ cfg( feature = "jiff-0_2" ) ]
525+ impl From < crate :: DateTime > for jiff:: Timestamp {
526+ fn from ( bson_dt : DateTime ) -> Self {
527+ bson_dt. to_jiff ( )
528+ }
529+ }
530+
531+ #[ cfg( feature = "jiff-0_2" ) ]
532+ impl From < jiff:: Timestamp > for crate :: DateTime {
533+ fn from ( x : jiff:: Timestamp ) -> Self {
534+ Self :: from_jiff ( x)
535+ }
536+ }
537+
538+ #[ cfg( all( feature = "jiff-0_2" , feature = "serde_with-3" ) ) ]
539+ impl < ' de > serde_with:: DeserializeAs < ' de , jiff:: Timestamp > for crate :: DateTime {
540+ fn deserialize_as < D > ( deserializer : D ) -> std:: result:: Result < jiff:: Timestamp , D :: Error >
541+ where
542+ D : Deserializer < ' de > ,
543+ {
544+ let dt = DateTime :: deserialize ( deserializer) ?;
545+ Ok ( dt. to_jiff ( ) )
546+ }
547+ }
548+
549+ #[ cfg( all( feature = "jiff-0_2" , feature = "serde_with-3" ) ) ]
550+ impl serde_with:: SerializeAs < jiff:: Timestamp > for crate :: DateTime {
551+ fn serialize_as < S > (
552+ source : & jiff:: Timestamp ,
553+ serializer : S ,
554+ ) -> std:: result:: Result < S :: Ok , S :: Error >
555+ where
556+ S : serde:: Serializer ,
557+ {
558+ let dt = DateTime :: from_jiff ( * source) ;
559+ dt. serialize ( serializer)
560+ }
561+ }
562+
491563#[ cfg( feature = "time-0_3" ) ]
492564impl From < crate :: DateTime > for time:: OffsetDateTime {
493565 fn from ( bson_dt : DateTime ) -> Self {
0 commit comments