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.target(Scale::UTC).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 #[inline]
25 pub fn from_jiff_timestamp(ts: Timestamp) -> Dt {
26 Dt::from_diff_and_scale(
27 Dt::from_ns(ts.as_nanosecond(), Scale::UTC),
28 Self::UNIX_EPOCH,
29 false,
30 )
31 }
32
33 pub fn to_jiff_span(&self) -> Span {
35 let total_nanos = self.to_ns();
36 let seconds = Dt::i128_to_i64(total_nanos.div_euclid(1_000_000_000));
37 let nanoseconds = Dt::i128_to_i64(total_nanos.rem_euclid(1_000_000_000));
38
39 if let Ok(base) = Span::new().try_seconds(seconds)
40 && let Ok(span) = base.try_nanoseconds(nanoseconds)
41 {
42 return span;
43 }
44 if total_nanos >= 0 {
46 Span::new()
47 .seconds(631_107_417_600i64)
48 .nanoseconds(999_999_999i64)
49 } else {
50 Span::new()
51 .seconds(-631_107_417_600i64)
52 .nanoseconds(-999_999_999i64)
53 }
54 }
55
56 #[inline]
61 pub fn to_jiff_signed_duration(&self) -> SignedDuration {
62 SignedDuration::from_nanos_i128(self.to_ns())
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}