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