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};
385 /// use deep_time::macros::from_sec;
386 ///
387 /// assert_eq!(Dt::ZERO.to_mins_f(), 0.0);
388 ///
389 /// let dt = from_sec!(90);
390 /// assert_eq!(dt.to_mins_f(), 1.5);
391 ///
392 /// let dt = from_sec!(-90);
393 /// assert_eq!(dt.to_mins_f(), -1.5);
394 /// ```
395 pub const fn to_mins_f(&self) -> Real {
396 if self.attos == 0 {
397 return 0.0;
398 }
399 let mins = self.attos.div_euclid(ATTOS_PER_MIN);
400 let rem = self.attos.rem_euclid(ATTOS_PER_MIN);
401
402 if mins < 0 && rem > ATTOS_PER_MIN / 2 {
403 let small = ATTOS_PER_MIN - rem;
404 let small_f = f!(small as u128) / f!(ATTOS_PER_MIN);
405 f!(mins) + 1.0 - small_f
406 } else {
407 f!(mins) + f!(rem as u128) / f!(ATTOS_PER_MIN)
408 }
409 }
410
411 /// Converts this [`Dt`] into whole hours and a fractional part within one hour.
412 ///
413 /// - Returns `(whole, frac_attos)` where `frac_attos` is always non-negative.
414 /// - For negative values this does **not** split at the decimal point — see
415 /// [`to_sec64_floor`](../struct.Dt.html#method.to_sec64_floor) and
416 /// [`to_sec_ufrac`](../struct.Dt.html#method.to_sec_ufrac).
417 #[inline(always)]
418 pub const fn to_hours_floor(&self) -> (i128, i128) {
419 (
420 self.attos.div_euclid(ATTOS_PER_HOUR),
421 self.attos.rem_euclid(ATTOS_PER_HOUR),
422 )
423 }
424
425 /// Converts this [`Dt`] to a float number of hours.
426 ///
427 /// ## Examples
428 ///
429 /// ```rust
430 /// use deep_time::{Dt, dt, consts::ATTOS_PER_SEC_I128};
431 ///
432 /// assert_eq!(Dt::ZERO.to_hours_f(), 0.0);
433 ///
434 /// let dt = Dt::from_str_iso("2000-01-01 10:30:00 TAI").unwrap();
435 /// assert_eq!(dt.to_hours_f(), -1.5);
436 /// ```
437 pub const fn to_hours_f(&self) -> Real {
438 if self.attos == 0 {
439 return 0.0;
440 }
441 let hours = self.attos.div_euclid(ATTOS_PER_HOUR);
442 let rem = self.attos.rem_euclid(ATTOS_PER_HOUR);
443
444 if hours < 0 && rem > ATTOS_PER_HOUR / 2 {
445 let small = ATTOS_PER_HOUR - rem;
446 let small_f = f!(small as u128) / f!(ATTOS_PER_HOUR);
447 f!(hours) + 1.0 - small_f
448 } else {
449 f!(hours) + f!(rem as u128) / f!(ATTOS_PER_HOUR)
450 }
451 }
452
453 /// Converts this [`Dt`] into whole days and a fractional part within one day,
454 /// truncating toward zero.
455 ///
456 /// Returns `(whole, frac_attos)`. When the value is negative and has a fractional
457 /// part, `frac_attos` is negative too — e.g. `-1.25` days is
458 /// `(-1, -ATTOS_PER_DAY / 4)`.
459 ///
460 /// For a non-negative fractional part, use [`to_days_floor`](#method.to_days_floor).
461 ///
462 /// ## Examples
463 ///
464 /// ```rust
465 /// use deep_time::{Dt, Scale, consts::ATTOS_PER_DAY};
466 ///
467 /// let dt = Dt::from_days_f(1.25, Scale::TAI, Scale::TAI);
468 /// assert_eq!(dt.to_days(), (1, ATTOS_PER_DAY / 4));
469 ///
470 /// let dt = Dt::from_days_f(-1.25, Scale::TAI, Scale::TAI);
471 /// assert_eq!(dt.to_days(), (-1, -ATTOS_PER_DAY / 4));
472 /// ```
473 ///
474 /// ## See also
475 ///
476 /// - [`Dt::to_days_floor`](#method.to_days_floor)
477 /// - [`Dt::from_days`](../struct.Dt.html#method.from_days)
478 #[inline(always)]
479 pub const fn to_days(&self) -> (i128, i128) {
480 (self.attos / ATTOS_PER_DAY, self.attos % ATTOS_PER_DAY)
481 }
482
483 /// Converts this [`Dt`] into whole days and a fractional part within one day.
484 ///
485 /// - Returns `(whole, frac_attos)` where `frac_attos` is always non-negative.
486 /// - For negative values this does **not** split at the decimal point — see
487 /// [`to_sec64_floor`](../struct.Dt.html#method.to_sec64_floor) and
488 /// [`to_sec_ufrac`](../struct.Dt.html#method.to_sec_ufrac).
489 ///
490 /// ## Examples
491 ///
492 /// ```rust
493 /// use deep_time::{Dt, Scale, dt};
494 /// use deep_time::consts::ATTOS_PER_HALF_DAY;
495 ///
496 /// // library epoch is 2000-01-01 12:00:00 TAI
497 /// // so result will be negative 2 + half a day
498 /// // effectively -1.5 days
499 /// let dt = Dt::from_ymd(1999, 12, 31, Scale::TAI, 0, 0, 0, 0);
500 /// let (days, attos) = dt.to_days_floor();
501 /// assert_eq!(days, -2);
502 /// assert_eq!(attos, ATTOS_PER_HALF_DAY);
503 /// ```
504 ///
505 /// ## See also
506 ///
507 /// - [`Dt::to_days`](#method.to_days)
508 #[inline(always)]
509 pub const fn to_days_floor(&self) -> (i128, i128) {
510 (
511 self.attos.div_euclid(ATTOS_PER_DAY),
512 self.attos.rem_euclid(ATTOS_PER_DAY),
513 )
514 }
515
516 /// Converts this [`Dt`] to a float number of days.
517 ///
518 /// ## Examples
519 ///
520 /// ```rust
521 /// use deep_time::{Dt, Scale, consts::ATTOS_PER_HALF_DAY_U128};
522 ///
523 /// assert_eq!(Dt::ZERO.to_days_f(), 0.0);
524 ///
525 /// // library epoch is 2000-01-01 12:00:00 TAI
526 /// // so -1.5 days
527 /// let dt = Dt::from_ymd(1999, 12, 31, Scale::TAI, 0, 0, 0, 0);
528 /// assert_eq!(dt.to_days_f(), -1.5);
529 /// ```
530 ///
531 /// ## See also
532 ///
533 /// - [`Dt::from_days_f`](../struct.Dt.html#method.from_days_f)
534 pub const fn to_days_f(&self) -> Real {
535 if self.attos == 0 {
536 return 0.0;
537 }
538 let days = self.attos.div_euclid(ATTOS_PER_DAY);
539 let rem = self.attos.rem_euclid(ATTOS_PER_DAY);
540
541 if days < 0 && rem > ATTOS_PER_DAY / 2 {
542 let small = ATTOS_PER_DAY - rem;
543 let small_f = f!(small as u128) / f!(ATTOS_PER_DAY);
544 f!(days) + 1.0 - small_f
545 } else {
546 f!(days) + f!(rem as u128) / f!(ATTOS_PER_DAY)
547 }
548 }
549
550 /// Converts this [`Dt`] into whole milliseconds and a fractional part within one millisecond,
551 /// truncating toward zero.
552 ///
553 /// Returns `(whole, frac_attos)`. `frac_attos` will be negative when `whole` is negative and
554 /// there is a non-zero fraction. See
555 /// [`to_sec`](../struct.Dt.html#method.to_sec)
556 /// for the same rule in seconds.
557 #[inline(always)]
558 pub const fn to_ms(&self) -> (i128, i128) {
559 (
560 self.attos / ATTOS_PER_MS_I128,
561 self.attos % ATTOS_PER_MS_I128,
562 )
563 }
564
565 /// Converts this [`Dt`] into whole microseconds and a fractional part within one microsecond,
566 /// truncating toward zero.
567 ///
568 /// Returns `(whole, frac_attos)`. `frac_attos` will be negative when `whole` is negative and
569 /// there is a non-zero fraction. See
570 /// [`to_sec`](../struct.Dt.html#method.to_sec)
571 /// for the same rule in seconds.
572 #[inline(always)]
573 pub const fn to_us(&self) -> (i128, i128) {
574 (
575 self.attos / ATTOS_PER_US_I128,
576 self.attos % ATTOS_PER_US_I128,
577 )
578 }
579
580 /// Converts this [`Dt`] into whole nanoseconds and a fractional part within one nanosecond,
581 /// truncating toward zero.
582 ///
583 /// Returns `(whole, frac_attos)`. `frac_attos` will be negative when `whole` is negative and
584 /// there is a non-zero fraction. See
585 /// [`to_sec`](../struct.Dt.html#method.to_sec)
586 /// for the same rule in seconds.
587 #[inline(always)]
588 pub const fn to_ns(&self) -> (i128, i128) {
589 (
590 self.attos / ATTOS_PER_NS_I128,
591 self.attos % ATTOS_PER_NS_I128,
592 )
593 }
594
595 /// Converts this [`Dt`] into whole picoseconds and a fractional part within one picosecond,
596 /// truncating toward zero.
597 ///
598 /// Returns `(whole, frac_attos)`. `frac_attos` will be negative when `whole` is negative and
599 /// there is a non-zero fraction. See
600 /// [`to_sec`](../struct.Dt.html#method.to_sec)
601 /// for the same rule in seconds.
602 #[inline(always)]
603 pub const fn to_ps(&self) -> (i128, i128) {
604 (
605 self.attos / ATTOS_PER_PS_I128,
606 self.attos % ATTOS_PER_PS_I128,
607 )
608 }
609
610 /// Converts this [`Dt`] into whole femtoseconds and a fractional part within one femtosecond,
611 /// truncating toward zero.
612 ///
613 /// Returns `(whole, frac_attos)`. `frac_attos` will be negative when `whole` is negative and
614 /// there is a non-zero fraction. See
615 /// [`to_sec`](../struct.Dt.html#method.to_sec)
616 /// for the same rule in seconds.
617 #[inline(always)]
618 pub const fn to_fs(&self) -> (i128, i128) {
619 (
620 self.attos / ATTOS_PER_FS_I128,
621 self.attos % ATTOS_PER_FS_I128,
622 )
623 }
624}