deep_time/dt/to.rs
1use crate::{
2 ATTOS_PER_DAY, ATTOS_PER_FS_I128, ATTOS_PER_HOUR, ATTOS_PER_MIN, ATTOS_PER_MS_I128,
3 ATTOS_PER_NS_I128, ATTOS_PER_PS_I128, ATTOS_PER_SEC_I128, ATTOS_PER_SECF, ATTOS_PER_US_I128,
4 Dt, Real, dt,
5};
6
7impl Dt {
8 /// Returns the whole seconds portion of this [`Dt`] using truncation towards zero
9 /// (i.e., the integer part obtained via truncating division, without rounding).
10 ///
11 /// This is equivalent to `self.attos / ATTOS_PER_SEC_I128`.
12 ///
13 /// Unlike
14 /// [`to_sec_floor`](../struct.Dt.html#method.to_sec_floor)
15 /// (which uses Euclidean division, flooring towards
16 /// negative infinity for negative values to keep the fractional part non-negative),
17 /// this version truncates towards zero.
18 ///
19 /// Consequently, for values in `(-1, 0)` seconds (e.g. -0.3 s or -0.8 s),
20 /// both return `0`.
21 ///
22 /// ## Examples
23 ///
24 /// ```rust
25 /// use deep_time::{Dt, dt};
26 ///
27 /// // -0.3 seconds → truncates to 0
28 /// let dt = dt!(-300_000_000_000_000_000);
29 /// assert_eq!(dt.to_sec(), 0);
30 ///
31 /// // -0.8 seconds → truncates to 0
32 /// let dt = dt!(-800_000_000_000_000_000);
33 /// assert_eq!(dt.to_sec(), 0);
34 ///
35 /// // -1.3 seconds → truncates to -1 (while to_sec_floor gives -2)
36 /// let dt = dt!(-1_300_000_000_000_000_000);
37 /// assert_eq!(dt.to_sec(), -1);
38 /// assert_eq!(dt.to_sec_floor(), -2);
39 ///
40 /// // Positive values behave the same as `to_sec_floor`
41 /// let dt = dt!(1_300_000_000_000_000_000);
42 /// assert_eq!(dt.to_sec(), 1);
43 /// assert_eq!(dt.to_sec_floor(), 1);
44 /// ```
45 #[inline(always)]
46 pub const fn to_sec(&self) -> i128 {
47 self.attos / ATTOS_PER_SEC_I128
48 }
49
50 /// Returns the whole seconds portion of this [`Dt`] using truncation towards zero,
51 /// then clamped to an [`i64`].
52 ///
53 /// If the truncated seconds value lies outside the `i64` range, the result
54 /// saturates to [`i64::MAX`] or [`i64::MIN`].
55 ///
56 /// See
57 /// [`to_sec`](../struct.Dt.html#method.to_sec)
58 /// for the truncation semantics
59 /// (towards zero, no rounding).
60 ///
61 /// ## Examples
62 ///
63 /// ```rust
64 /// use deep_time::{Dt, dt};
65 ///
66 /// let dt = dt!(-1_300_000_000_000_000_000);
67 /// assert_eq!(dt.to_sec64(), -1);
68 ///
69 /// let dt = dt!(1_300_000_000_000_000_000);
70 /// assert_eq!(dt.to_sec64_floor(), 1);
71 /// ```
72 #[inline(always)]
73 pub const fn to_sec64(&self) -> i64 {
74 Self::to_i64(self.attos / ATTOS_PER_SEC_I128)
75 }
76
77 /// If this time were turned into [`i128`] seconds and [`u64`] (always
78 /// pushing to the positive) fractional attoseconds, this returns the
79 /// whole seconds part.
80 ///
81 /// To just get seconds rounded to the nearest second use
82 /// [`Dt::to_sec_round`](../struct.Dt.html#method.to_sec_round)
83 /// instead.
84 ///
85 /// ## Examples
86 ///
87 /// ```rust
88 /// use deep_time::{Dt, Scale, dt};
89 ///
90 /// // negative 1.3 seconds
91 /// let dt = dt!(-1_300_000_000_000_000_000);
92 ///
93 /// // becomes positive 700ms
94 /// let frac = dt.to_sec_ufrac();
95 /// assert_eq!(frac, 700_000_000_000_000_000);
96 ///
97 /// // becomes negative 2 seconds
98 /// let sec = dt.to_sec_floor();
99 /// assert_eq!(sec, -2);
100 ///
101 /// let dt = dt!(1_300_000_000_000_000_000);
102 ///
103 /// assert_eq!(dt.to_sec_floor(), 1);
104 /// assert_eq!(dt.to_sec_ufrac(), 300_000_000_000_000_000);
105 ///
106 /// // if you just want rounded seconds
107 /// // use to_sec_round() instead
108 /// let dt = dt!(-1_300_000_000_000_000_000);
109 /// let sec = dt.to_sec_round();
110 /// assert_eq!(sec, -1);
111 /// ```
112 #[inline(always)]
113 pub const fn to_sec_floor(&self) -> i128 {
114 self.attos.div_euclid(ATTOS_PER_SEC_I128)
115 }
116
117 /// If this time were turned into [`i64`] seconds and [`u64`] (always
118 /// pushing to the positive) fractional attoseconds, this returns the
119 /// whole seconds part.
120 ///
121 /// To just get seconds rounded to the nearest second use
122 /// [`Dt::to_sec_round`](../struct.Dt.html#method.to_sec_round)
123 /// instead.
124 ///
125 /// ## Examples
126 ///
127 /// ```rust
128 /// use deep_time::{Dt, Scale, dt};
129 ///
130 /// // negative 1.3 seconds
131 /// let dt = dt!(-1_300_000_000_000_000_000);
132 ///
133 /// // becomes positive 700ms
134 /// let frac = dt.to_sec_ufrac();
135 /// assert_eq!(frac, 700_000_000_000_000_000);
136 ///
137 /// // becomes negative 2 seconds
138 /// let sec = dt.to_sec64_floor();
139 /// assert_eq!(sec, -2);
140 ///
141 /// let dt = dt!(1_300_000_000_000_000_000);
142 ///
143 /// assert_eq!(dt.to_sec64_floor(), 1);
144 /// assert_eq!(dt.to_sec_ufrac(), 300_000_000_000_000_000);
145 ///
146 /// // if you just want rounded seconds
147 /// // use to_sec_round() instead
148 /// let dt = dt!(-1_300_000_000_000_000_000);
149 /// let sec = dt.to_sec_round();
150 /// assert_eq!(sec, -1);
151 /// ```
152 #[inline(always)]
153 pub const fn to_sec64_floor(&self) -> i64 {
154 Self::to_i64(self.attos.div_euclid(ATTOS_PER_SEC_I128))
155 }
156
157 /// Returns this [`Dt`] rounded to the nearest whole second, then
158 /// converted to an [`i128`] number of seconds.
159 ///
160 /// - Exactly halfway cases (e.g. 0.5 s, -0.5 s) round as follows:
161 /// 0.5 becomes 1 and -0.5 becomes -1.
162 /// - Matches the behavior of [`Dt::round`].
163 ///
164 /// ## Examples
165 ///
166 /// ```rust
167 /// use deep_time::{Dt, dt};
168 ///
169 /// // 1.3 seconds → rounds to 1
170 /// assert_eq!(dt!(1_300_000_000_000_000_000).to_sec_round(), 1);
171 ///
172 /// // -1.3 seconds → rounds to -1
173 /// assert_eq!(dt!(-1_300_000_000_000_000_000).to_sec_round(), -1);
174 ///
175 /// // 1.6 seconds → rounds to 2
176 /// assert_eq!(dt!(1_600_000_000_000_000_000).to_sec_round(), 2);
177 ///
178 /// // Halfway cases
179 /// assert_eq!(dt!(500_000_000_000_000_000).to_sec_round(), 1);
180 /// assert_eq!(dt!(-500_000_000_000_000_000).to_sec_round(), -1);
181 /// ```
182 #[inline(always)]
183 pub const fn to_sec_round(&self) -> i128 {
184 self.round_to_sec().to_sec()
185 }
186
187 /// Returns this [`Dt`] rounded to the nearest whole second, then
188 /// converted to an [`i64`] number of seconds.
189 ///
190 /// - Exactly halfway cases round as follows: 0.5 becomes 1 and -0.5 becomes -1,
191 /// same as
192 /// [`to_sec_round`](../struct.Dt.html#method.to_sec_round).
193 /// - If the rounded value is outside the representable `i64` range,
194 /// it saturates to [`i64::MAX`] or [`i64::MIN`].
195 ///
196 /// ## Examples
197 ///
198 /// ```rust
199 /// use deep_time::{Dt, dt};
200 ///
201 /// let dt = dt!(1_300_000_000_000_000_000);
202 /// assert_eq!(dt.to_sec64_round(), 1);
203 ///
204 /// let dt = dt!(-1_300_000_000_000_000_000);
205 /// assert_eq!(dt.to_sec64_round(), -1);
206 /// ```
207 #[inline(always)]
208 pub const fn to_sec64_round(&self) -> i64 {
209 Self::to_i64(self.round_to_sec().to_sec())
210 }
211
212 /// Converts this [`Dt`] to an f64 number of seconds.
213 #[inline(always)]
214 pub const fn to_f64(&self) -> f64 {
215 self.to_sec_f()
216 }
217
218 /// Converts this [`Dt`] to a float number of seconds.
219 pub const fn to_sec_f(&self) -> Real {
220 if self.attos == 0 {
221 return 0.0;
222 }
223 let sec = self.attos.div_euclid(ATTOS_PER_SEC_I128);
224 let rem = self.attos.rem_euclid(ATTOS_PER_SEC_I128); // always in [0, aps)
225
226 if sec < 0 && rem > ATTOS_PER_SEC_I128 / 2 {
227 // original cancellation-avoidance path
228 let small = ATTOS_PER_SEC_I128 - rem;
229 let small_f = f!(small as u64) / ATTOS_PER_SECF;
230 f!(sec) + 1.0 - small_f
231 } else {
232 f!(sec) + f!(rem as u64) / ATTOS_PER_SECF
233 }
234 }
235
236 /// If this time were turned into seconds, this returns the signed fractional
237 /// attoseconds part — the amount left over after removing whole seconds, with the
238 /// same sign as the original value when non-zero.
239 ///
240 /// Pairs with [`from_sec_and_frac`](../struct.Dt.html#method.from_sec_and_frac).
241 #[inline(always)]
242 pub const fn to_sec_frac(&self) -> i64 {
243 (self.attos % ATTOS_PER_SEC_I128) as i64
244 }
245
246 /// If this time were turned into i64 seconds and u64 (always pushing to the positive)
247 /// fractional attoseconds, this returns the fractional attoseconds part.
248 ///
249 /// - Always returns a value in the range `0 ≤ x < ATTOS_PER_SEC`.
250 /// - For negative [`Dt`]s this is **not** simply the decimal part of the time in seconds.
251 ///
252 /// ## Examples
253 ///
254 /// ```rust
255 /// use deep_time::{Dt, Scale, dt};
256 ///
257 /// // negative 1.3 seconds
258 /// let dt = dt!(-1_300_000_000_000_000_000);
259 ///
260 /// // becomes positive 700ms
261 /// let frac = dt.to_sec_ufrac();
262 /// assert_eq!(frac, 700_000_000_000_000_000);
263 ///
264 /// // becomes -2 seconds
265 /// let sec = dt.to_sec64_floor();
266 /// assert_eq!(sec, -2);
267 ///
268 /// let dt = dt!(1_300_000_000_000_000_000);
269 ///
270 /// assert_eq!(dt.to_sec64_floor(), 1);
271 /// assert_eq!(dt.to_sec_ufrac(), 300_000_000_000_000_000);
272 /// ```
273 #[inline(always)]
274 pub const fn to_sec_ufrac(&self) -> u64 {
275 self.attos.rem_euclid(ATTOS_PER_SEC_I128) as u64
276 }
277
278 /// Returns a new [`Dt`] rounded to the nearest second.
279 #[inline(always)]
280 pub const fn round_to_sec(&self) -> Dt {
281 self.round(dt!(ATTOS_PER_SEC_I128))
282 }
283
284 /// Returns the total time in attoseconds.
285 #[inline(always)]
286 pub const fn to_attos(&self) -> i128 {
287 self.attos
288 }
289
290 /// Converts this [`Dt`] into whole femtoseconds and a fractional part within one femtosecond.
291 ///
292 /// - Returns `(whole, frac_attos)` where `frac_attos` is always non-negative.
293 /// - For negative values this does **not** split at the decimal point — see
294 /// [`to_sec64_floor`](../struct.Dt.html#method.to_sec64_floor) and
295 /// [`to_sec_ufrac`](../struct.Dt.html#method.to_sec_ufrac).
296 /// - For truncation toward zero, use [`to_fs`](../struct.Dt.html#method.to_fs).
297 #[inline(always)]
298 pub const fn to_fs_floor(&self) -> (i128, i128) {
299 (
300 self.attos.div_euclid(ATTOS_PER_FS_I128),
301 self.attos.rem_euclid(ATTOS_PER_FS_I128),
302 )
303 }
304
305 /// Converts this [`Dt`] into whole picoseconds and a fractional part within one picosecond.
306 ///
307 /// - Returns `(whole, frac_attos)` where `frac_attos` is always non-negative.
308 /// - For negative values this does **not** split at the decimal point — see
309 /// [`to_sec64_floor`](../struct.Dt.html#method.to_sec64_floor) and
310 /// [`to_sec_ufrac`](../struct.Dt.html#method.to_sec_ufrac).
311 /// - For truncation toward zero, use [`to_ps`](../struct.Dt.html#method.to_ps).
312 #[inline(always)]
313 pub const fn to_ps_floor(&self) -> (i128, i128) {
314 (
315 self.attos.div_euclid(ATTOS_PER_PS_I128),
316 self.attos.rem_euclid(ATTOS_PER_PS_I128),
317 )
318 }
319
320 /// Converts this [`Dt`] into whole nanoseconds and a fractional part within one nanosecond.
321 ///
322 /// - Returns `(whole, frac_attos)` where `frac_attos` is always non-negative.
323 /// - For negative values this does **not** split at the decimal point — see
324 /// [`to_sec64_floor`](../struct.Dt.html#method.to_sec64_floor) and
325 /// [`to_sec_ufrac`](../struct.Dt.html#method.to_sec_ufrac).
326 /// - For truncation toward zero, use [`to_ns`](../struct.Dt.html#method.to_ns).
327 #[inline(always)]
328 pub const fn to_ns_floor(&self) -> (i128, i128) {
329 (
330 self.attos.div_euclid(ATTOS_PER_NS_I128),
331 self.attos.rem_euclid(ATTOS_PER_NS_I128),
332 )
333 }
334
335 /// Converts this [`Dt`] into whole microseconds and a fractional part within one microsecond.
336 ///
337 /// - Returns `(whole, frac_attos)` where `frac_attos` is always non-negative.
338 /// - For negative values this does **not** split at the decimal point — see
339 /// [`to_sec64_floor`](../struct.Dt.html#method.to_sec64_floor) and
340 /// [`to_sec_ufrac`](../struct.Dt.html#method.to_sec_ufrac).
341 /// - For truncation toward zero, use [`to_us`](../struct.Dt.html#method.to_us).
342 #[inline(always)]
343 pub const fn to_us_floor(&self) -> (i128, i128) {
344 (
345 self.attos.div_euclid(ATTOS_PER_US_I128),
346 self.attos.rem_euclid(ATTOS_PER_US_I128),
347 )
348 }
349
350 /// Converts this [`Dt`] into whole milliseconds and a fractional part within one millisecond.
351 ///
352 /// - Returns `(whole, frac_attos)` where `frac_attos` is always non-negative.
353 /// - For negative values this does **not** split at the decimal point — see
354 /// [`to_sec64_floor`](../struct.Dt.html#method.to_sec64_floor) and
355 /// [`to_sec_ufrac`](../struct.Dt.html#method.to_sec_ufrac).
356 /// - For truncation toward zero, use [`to_ms`](../struct.Dt.html#method.to_ms).
357 #[inline(always)]
358 pub const fn to_ms_floor(&self) -> (i128, i128) {
359 (
360 self.attos.div_euclid(ATTOS_PER_MS_I128),
361 self.attos.rem_euclid(ATTOS_PER_MS_I128),
362 )
363 }
364
365 /// Converts this [`Dt`] into whole minutes and a fractional part within one minute.
366 ///
367 /// - Returns `(whole, frac_attos)` where `frac_attos` is always non-negative.
368 /// - For negative values this does **not** split at the decimal point — see
369 /// [`to_sec64_floor`](../struct.Dt.html#method.to_sec64_floor) and
370 /// [`to_sec_ufrac`](../struct.Dt.html#method.to_sec_ufrac).
371 #[inline(always)]
372 pub const fn to_mins_floor(&self) -> (i128, i128) {
373 (
374 self.attos.div_euclid(ATTOS_PER_MIN),
375 self.attos.rem_euclid(ATTOS_PER_MIN),
376 )
377 }
378
379 /// Converts this [`Dt`] to a float number of minutes.
380 ///
381 /// ## Examples
382 ///
383 /// ```rust
384 /// use deep_time::{Dt, from_sec};
385 ///
386 /// assert_eq!(Dt::ZERO.to_mins_f(), 0.0);
387 ///
388 /// let dt = from_sec!(90);
389 /// assert_eq!(dt.to_mins_f(), 1.5);
390 ///
391 /// let dt = from_sec!(-90);
392 /// assert_eq!(dt.to_mins_f(), -1.5);
393 /// ```
394 pub const fn to_mins_f(&self) -> Real {
395 if self.attos == 0 {
396 return 0.0;
397 }
398 let mins = self.attos.div_euclid(ATTOS_PER_MIN);
399 let rem = self.attos.rem_euclid(ATTOS_PER_MIN);
400
401 if mins < 0 && rem > ATTOS_PER_MIN / 2 {
402 let small = ATTOS_PER_MIN - rem;
403 let small_f = f!(small as u128) / f!(ATTOS_PER_MIN);
404 f!(mins) + 1.0 - small_f
405 } else {
406 f!(mins) + f!(rem as u128) / f!(ATTOS_PER_MIN)
407 }
408 }
409
410 /// Converts this [`Dt`] into whole hours and a fractional part within one hour.
411 ///
412 /// - Returns `(whole, frac_attos)` where `frac_attos` is always non-negative.
413 /// - For negative values this does **not** split at the decimal point — see
414 /// [`to_sec64_floor`](../struct.Dt.html#method.to_sec64_floor) and
415 /// [`to_sec_ufrac`](../struct.Dt.html#method.to_sec_ufrac).
416 #[inline(always)]
417 pub const fn to_hours_floor(&self) -> (i128, i128) {
418 (
419 self.attos.div_euclid(ATTOS_PER_HOUR),
420 self.attos.rem_euclid(ATTOS_PER_HOUR),
421 )
422 }
423
424 /// Converts this [`Dt`] to a float number of hours.
425 ///
426 /// ## Examples
427 ///
428 /// ```rust
429 /// use deep_time::{Dt, dt, consts::ATTOS_PER_SEC_I128};
430 ///
431 /// assert_eq!(Dt::ZERO.to_hours_f(), 0.0);
432 ///
433 /// let dt = Dt::from_str_iso("2000-01-01 10:30:00 TAI").unwrap();
434 /// assert_eq!(dt.to_hours_f(), -1.5);
435 /// ```
436 pub const fn to_hours_f(&self) -> Real {
437 if self.attos == 0 {
438 return 0.0;
439 }
440 let hours = self.attos.div_euclid(ATTOS_PER_HOUR);
441 let rem = self.attos.rem_euclid(ATTOS_PER_HOUR);
442
443 if hours < 0 && rem > ATTOS_PER_HOUR / 2 {
444 let small = ATTOS_PER_HOUR - rem;
445 let small_f = f!(small as u128) / f!(ATTOS_PER_HOUR);
446 f!(hours) + 1.0 - small_f
447 } else {
448 f!(hours) + f!(rem as u128) / f!(ATTOS_PER_HOUR)
449 }
450 }
451
452 /// Converts this [`Dt`] into whole days and a fractional part within one day,
453 /// truncating toward zero.
454 ///
455 /// Returns `(whole, frac_attos)`. When the value is negative and has a fractional
456 /// part, `frac_attos` is negative too — e.g. `-1.25` days is
457 /// `(-1, -ATTOS_PER_DAY / 4)`.
458 ///
459 /// For a non-negative fractional part, use [`to_days_floor`](#method.to_days_floor).
460 ///
461 /// ## Examples
462 ///
463 /// ```rust
464 /// use deep_time::{Dt, Scale, consts::ATTOS_PER_DAY};
465 ///
466 /// let dt = Dt::from_days_f(1.25, Scale::TAI, Scale::TAI);
467 /// assert_eq!(dt.to_days(), (1, ATTOS_PER_DAY / 4));
468 ///
469 /// let dt = Dt::from_days_f(-1.25, Scale::TAI, Scale::TAI);
470 /// assert_eq!(dt.to_days(), (-1, -ATTOS_PER_DAY / 4));
471 /// ```
472 ///
473 /// ## See also
474 ///
475 /// - [`Dt::to_days_floor`](#method.to_days_floor)
476 /// - [`Dt::from_days`](../struct.Dt.html#method.from_days)
477 #[inline(always)]
478 pub const fn to_days(&self) -> (i128, i128) {
479 (self.attos / ATTOS_PER_DAY, self.attos % ATTOS_PER_DAY)
480 }
481
482 /// Converts this [`Dt`] into whole days and a fractional part within one day.
483 ///
484 /// - Returns `(whole, frac_attos)` where `frac_attos` is always non-negative.
485 /// - For negative values this does **not** split at the decimal point — see
486 /// [`to_sec64_floor`](../struct.Dt.html#method.to_sec64_floor) and
487 /// [`to_sec_ufrac`](../struct.Dt.html#method.to_sec_ufrac).
488 ///
489 /// ## Examples
490 ///
491 /// ```rust
492 /// use deep_time::{Dt, Scale, dt};
493 /// use deep_time::consts::ATTOS_PER_HALF_DAY;
494 ///
495 /// // library epoch is 2000-01-01 12:00:00 TAI
496 /// // so result will be negative 2 + half a day
497 /// // effectively -1.5 days
498 /// let dt = Dt::from_ymd(1999, 12, 31, Scale::TAI, 0, 0, 0, 0);
499 /// let (days, attos) = dt.to_days_floor();
500 /// assert_eq!(days, -2);
501 /// assert_eq!(attos, ATTOS_PER_HALF_DAY);
502 /// ```
503 ///
504 /// ## See also
505 ///
506 /// - [`Dt::to_days`](#method.to_days)
507 #[inline(always)]
508 pub const fn to_days_floor(&self) -> (i128, i128) {
509 (
510 self.attos.div_euclid(ATTOS_PER_DAY),
511 self.attos.rem_euclid(ATTOS_PER_DAY),
512 )
513 }
514
515 /// Converts this [`Dt`] to a float number of days.
516 ///
517 /// ## Examples
518 ///
519 /// ```rust
520 /// use deep_time::{Dt, Scale, consts::ATTOS_PER_HALF_DAY_U128};
521 ///
522 /// assert_eq!(Dt::ZERO.to_days_f(), 0.0);
523 ///
524 /// // library epoch is 2000-01-01 12:00:00 TAI
525 /// // so -1.5 days
526 /// let dt = Dt::from_ymd(1999, 12, 31, Scale::TAI, 0, 0, 0, 0);
527 /// assert_eq!(dt.to_days_f(), -1.5);
528 /// ```
529 ///
530 /// ## See also
531 ///
532 /// - [`Dt::from_days_f`](../struct.Dt.html#method.from_days_f)
533 pub const fn to_days_f(&self) -> Real {
534 if self.attos == 0 {
535 return 0.0;
536 }
537 let days = self.attos.div_euclid(ATTOS_PER_DAY);
538 let rem = self.attos.rem_euclid(ATTOS_PER_DAY);
539
540 if days < 0 && rem > ATTOS_PER_DAY / 2 {
541 let small = ATTOS_PER_DAY - rem;
542 let small_f = f!(small as u128) / f!(ATTOS_PER_DAY);
543 f!(days) + 1.0 - small_f
544 } else {
545 f!(days) + f!(rem as u128) / f!(ATTOS_PER_DAY)
546 }
547 }
548
549 /// Converts this [`Dt`] into whole milliseconds and a fractional part within one millisecond,
550 /// truncating toward zero.
551 ///
552 /// Returns `(whole, frac_attos)`. `frac_attos` will be negative when `whole` is negative and
553 /// there is a non-zero fraction. See
554 /// [`to_sec`](../struct.Dt.html#method.to_sec)
555 /// for the same rule in seconds.
556 #[inline(always)]
557 pub const fn to_ms(&self) -> (i128, i128) {
558 (
559 self.attos / ATTOS_PER_MS_I128,
560 self.attos % ATTOS_PER_MS_I128,
561 )
562 }
563
564 /// Converts this [`Dt`] into whole microseconds and a fractional part within one microsecond,
565 /// truncating toward zero.
566 ///
567 /// Returns `(whole, frac_attos)`. `frac_attos` will be negative when `whole` is negative and
568 /// there is a non-zero fraction. See
569 /// [`to_sec`](../struct.Dt.html#method.to_sec)
570 /// for the same rule in seconds.
571 #[inline(always)]
572 pub const fn to_us(&self) -> (i128, i128) {
573 (
574 self.attos / ATTOS_PER_US_I128,
575 self.attos % ATTOS_PER_US_I128,
576 )
577 }
578
579 /// Converts this [`Dt`] into whole nanoseconds and a fractional part within one nanosecond,
580 /// truncating toward zero.
581 ///
582 /// Returns `(whole, frac_attos)`. `frac_attos` will be negative when `whole` is negative and
583 /// there is a non-zero fraction. See
584 /// [`to_sec`](../struct.Dt.html#method.to_sec)
585 /// for the same rule in seconds.
586 #[inline(always)]
587 pub const fn to_ns(&self) -> (i128, i128) {
588 (
589 self.attos / ATTOS_PER_NS_I128,
590 self.attos % ATTOS_PER_NS_I128,
591 )
592 }
593
594 /// Converts this [`Dt`] into whole picoseconds and a fractional part within one picosecond,
595 /// truncating toward zero.
596 ///
597 /// Returns `(whole, frac_attos)`. `frac_attos` will be negative when `whole` is negative and
598 /// there is a non-zero fraction. See
599 /// [`to_sec`](../struct.Dt.html#method.to_sec)
600 /// for the same rule in seconds.
601 #[inline(always)]
602 pub const fn to_ps(&self) -> (i128, i128) {
603 (
604 self.attos / ATTOS_PER_PS_I128,
605 self.attos % ATTOS_PER_PS_I128,
606 )
607 }
608
609 /// Converts this [`Dt`] into whole femtoseconds and a fractional part within one femtosecond,
610 /// truncating toward zero.
611 ///
612 /// Returns `(whole, frac_attos)`. `frac_attos` will be negative when `whole` is negative and
613 /// there is a non-zero fraction. See
614 /// [`to_sec`](../struct.Dt.html#method.to_sec)
615 /// for the same rule in seconds.
616 #[inline(always)]
617 pub const fn to_fs(&self) -> (i128, i128) {
618 (
619 self.attos / ATTOS_PER_FS_I128,
620 self.attos % ATTOS_PER_FS_I128,
621 )
622 }
623}