frclib_core/units/
time.rs1use std::{ops::Neg, time::Duration};
2
3use crate::{unit, unit_conversion, unit_family};
4
5unit!(Hour: float);
6unit!(Minute: float);
7unit!(Second: float);
8unit!(Millisecond: float);
9unit!(Microsecond: uint);
10
11unit_conversion!(Second(float) <-> Millisecond(float) ~ second_to_millisecond);
12unit_conversion!(Second(float) <-> Microsecond(uint) ~ second_to_microsecond);
13unit_conversion!(Millisecond(float) <-> Microsecond(uint) ~ millisecond_to_microsecond);
14unit_conversion!(Hour(float) <-> Second(float) ~ hour_to_second);
15unit_conversion!(Minute(float) <-> Second(float) ~ minute_to_second);
16unit_conversion!(Hour(float) <-> Minute(float) ~ hour_to_minute);
17unit_conversion!(Minute(float) <-> Millisecond(float) ~ minute_to_millisecond);
18unit_conversion!(Minute(float) <-> Microsecond(uint) ~ minute_to_microsecond);
19unit_conversion!(Hour(float) <-> Millisecond(float) ~ hour_to_millisecond);
20unit_conversion!(Hour(float) <-> Microsecond(uint) ~ hour_to_microsecond);
21
22impl Neg for Microsecond {
24 type Output = Millisecond;
25 #[allow(clippy::cast_precision_loss)]
26 fn neg(self) -> Self::Output {
27 Millisecond::new(-(self.value() as f64))
28 }
29}
30
31unit_family!(Time(Second): Hour, Minute, Millisecond, Microsecond);
32
33fn second_to_millisecond(second: f64) -> f64 {
34 second * 1000.0
35}
36
37#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
38fn second_to_microsecond(second: f64) -> u64 {
39 if second.is_sign_negative() {
40 0
41 } else {
42 (second * 1_000_000.0) as u64
43 }
44}
45
46#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
47fn millisecond_to_microsecond(millisecond: f64) -> u64 {
48 if millisecond.is_sign_negative() {
49 0
50 } else {
51 (millisecond * 1000.0) as u64
52 }
53}
54
55fn hour_to_second(hour: f64) -> f64 {
56 hour * 3600.0
57}
58
59fn minute_to_second(minute: f64) -> f64 {
60 minute * 60.0
61}
62
63fn hour_to_minute(hour: f64) -> f64 {
64 hour * 60.0
65}
66
67fn minute_to_millisecond(minute: f64) -> f64 {
68 minute * 60000.0
69}
70
71#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
72fn minute_to_microsecond(minute: f64) -> u64 {
73 if minute.is_sign_negative() {
74 0
75 } else {
76 (minute * 60_000_000.0) as u64
77 }
78}
79
80fn hour_to_millisecond(hour: f64) -> f64 {
81 second_to_millisecond(hour_to_second(hour))
82}
83
84fn hour_to_microsecond(hour: f64) -> u64 {
85 second_to_microsecond(hour_to_second(hour))
86}
87
88impl From<Duration> for Hour {
89 fn from(duration: Duration) -> Self {
90 Self::new(duration.as_secs_f64() / 3600.0)
91 }
92}
93
94impl From<Duration> for Minute {
95 fn from(duration: Duration) -> Self {
96 Self::new(duration.as_secs_f64() / 60.0)
97 }
98}
99
100impl From<Duration> for Second {
101 fn from(duration: Duration) -> Self {
102 Self::new(duration.as_secs_f64())
103 }
104}
105
106impl From<Duration> for Millisecond {
107 fn from(duration: Duration) -> Self {
108 Self::new(duration.as_secs_f64() * 1000.0)
109 }
110}
111
112impl From<Duration> for Microsecond {
113 fn from(duration: Duration) -> Self {
114 Self::new(u64::try_from(duration.as_micros()).unwrap_or(u64::MAX))
115 }
116}
117
118impl From<Hour> for Duration {
119 fn from(hour: Hour) -> Self {
120 Self::from_secs_f64(hour.value() * 3600.0)
121 }
122}
123
124impl From<Minute> for Duration {
125 fn from(minute: Minute) -> Self {
126 Self::from_secs_f64(minute.value() * 60.0)
127 }
128}
129
130impl From<Second> for Duration {
131 fn from(second: Second) -> Self {
132 Self::from_secs_f64(second.value())
133 }
134}
135
136impl From<Millisecond> for Duration {
137 fn from(millisecond: Millisecond) -> Self {
138 Self::from_secs_f64(millisecond.value() / 1000.0)
139 }
140}
141
142impl From<Microsecond> for Duration {
143 fn from(microsecond: Microsecond) -> Self {
144 Self::from_micros(microsecond.value())
145 }
146}