1use crate::{Dt, DtErr, DtErrKind, Scale, an_err};
2use jiff::{SignedDuration, Span, Timestamp};
3
4impl Dt {
5 pub fn to_jiff_timestamp(&self, current: Scale) -> Timestamp {
7 let nanos = self.to(current, Scale::UTC).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::clamp_i128_to_i64(total_nanos.div_euclid(1_000_000_000));
25 let nanoseconds = Dt::clamp_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) -> Self {
58 Dt::from_dt(Dt::from_ns(ts.as_nanosecond(), Scale::TAI), Scale::UTC)
59 }
60
61 #[inline]
65 pub fn from_jiff_signed_duration(dur: SignedDuration) -> Self {
66 Self::from_ns(dur.as_nanos(), Scale::TAI)
67 }
68
69 #[inline]
73 pub fn from_jiff_span(span: Span) -> Result<Self, DtErr> {
74 let dur = SignedDuration::try_from(span)
75 .map_err(|e| an_err!(DtErrKind::InvalidInput, "{:?}: {}", span, e))?;
76 Ok(Self::from_jiff_signed_duration(dur))
77 }
78}