1use crate::{Dt, DtErr, DtErrKind, Scale, an_err};
2use jiff::{SignedDuration, Span, Timestamp};
3
4impl Dt {
5 pub fn to_jiff_timestamp(&self) -> Timestamp {
7 let nanos = self.to_unix().to_ns();
8
9 match Timestamp::from_nanosecond(nanos) {
10 Ok(ts) => ts,
11 Err(_) => {
12 if nanos >= 0 {
13 Timestamp::MAX
14 } else {
15 Timestamp::MIN
16 }
17 }
18 }
19 }
20
21 pub fn to_jiff_span(&self) -> Span {
23 let total_nanos = self.to_ns();
24 let seconds = Dt::i128_to_i64(total_nanos.div_euclid(1_000_000_000));
25 let nanoseconds = Dt::i128_to_i64(total_nanos.rem_euclid(1_000_000_000));
26
27 if let Ok(base) = Span::new().try_seconds(seconds)
28 && let Ok(span) = base.try_nanoseconds(nanoseconds)
29 {
30 return span;
31 }
32 if total_nanos >= 0 {
34 Span::new()
35 .seconds(631_107_417_600i64)
36 .nanoseconds(999_999_999i64)
37 } else {
38 Span::new()
39 .seconds(-631_107_417_600i64)
40 .nanoseconds(-999_999_999i64)
41 }
42 }
43
44 #[inline]
49 pub fn to_jiff_signed_duration(&self) -> SignedDuration {
50 SignedDuration::from_nanos_i128(self.to_ns())
51 }
52
53 #[inline]
57 pub fn from_jiff_timestamp(ts: Timestamp) -> Dt {
58 Dt::from_diff_and_scale(
59 Dt::from_ns(ts.as_nanosecond(), Scale::UTC),
60 Self::UNIX_EPOCH,
61 false,
62 )
63 }
64
65 #[inline]
69 pub fn from_jiff_signed_duration(dur: SignedDuration) -> Dt {
70 Self::from_ns(dur.as_nanos(), Scale::TAI)
71 }
72
73 #[inline]
77 pub fn from_jiff_span(span: Span) -> Result<Self, DtErr> {
78 let dur = SignedDuration::try_from(span)
79 .map_err(|e| an_err!(DtErrKind::InvalidInput, "{:?}: {}", span, e))?;
80 Ok(Self::from_jiff_signed_duration(dur))
81 }
82}