Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_datime/src/time/duration.rs

3.4 KiB, 30 runs

created by r1870400018:6387, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1//! [Written with AI entirely](https://need2know.ai/entirely-ai/code)\
2//! Anthropic Claude
3
4use crate::core::Duration;
5use oxedyne_fe2o3_core::prelude::*;
6
7#[derive(Clone, Debug, PartialEq)]
8pub struct CalClockDuration {
9 days: i32,
10 nanos: i64,
11}
12
13impl CalClockDuration {
14 pub fn new(days: i32, nanos: i64) -> Self {
15 Self { days, nanos }
16 }
17
18 pub fn from_days(days: i32) -> Self {
19 Self { days, nanos: 0 }
20 }
21
22 pub fn from_nanos(nanos: i64) -> Self {
23 Self { days: 0, nanos }
24 }
25
26 pub fn days(&self) -> i32 {
27 self.days
28 }
29
30 pub fn nanoseconds(&self) -> i64 {
31 self.nanos
32 }
33
34 pub fn from_millis(millis: i64) -> Outcome<Self> {
35 let nanos = millis * 1_000_000;
36 Ok(Self::from_nanos(nanos))
37 }
38
39 pub fn from_seconds(seconds: i64) -> Self {
40 let nanos = seconds * 1_000_000_000;
41 Self::from_nanos(nanos)
42 }
43
44 pub fn from_minutes(minutes: i64) -> Self {
45 let nanos = minutes * 60 * 1_000_000_000;
46 Self::from_nanos(nanos)
47 }
48
49 pub fn from_hours(hours: i64) -> Self {
50 let nanos = hours * 60 * 60 * 1_000_000_000;
51 Self::from_nanos(nanos)
52 }
53
54 /// Includes the nanosecond part, not just the days field.
55 pub fn total_days(&self) -> i64 {
56 const NANOS_PER_DAY: i64 = 24 * 60 * 60 * 1_000_000_000;
57
58 let day_nanos = self.days as i64 * NANOS_PER_DAY;
59 let total_nanos = day_nanos + self.nanos;
60
61 total_nanos / NANOS_PER_DAY
62 }
63
64 pub fn to_hours(&self) -> Outcome<i64> {
65 const NANOS_PER_HOUR: i64 = 60 * 60 * 1_000_000_000;
66 let total_nanos = res!(self.to_nanos());
67 Ok(total_nanos / NANOS_PER_HOUR)
68 }
69
70 pub fn to_minutes(&self) -> Outcome<i64> {
71 const NANOS_PER_MINUTE: i64 = 60 * 1_000_000_000;
72 let total_nanos = res!(self.to_nanos());
73 Ok(total_nanos / NANOS_PER_MINUTE)
74 }
75
76 pub fn add(&self, other: &Self) -> Outcome<Self> {
77 Ok(Self {
78 days: self.days + other.days,
79 nanos: self.nanos + other.nanos,
80 })
81 }
82
83 pub fn subtract(&self, other: &Self) -> Outcome<Self> {
84 Ok(Self {
85 days: self.days - other.days,
86 nanos: self.nanos - other.nanos,
87 })
88 }
89
90 pub fn time_component(&self) -> crate::clock::ClockDuration {
91 crate::clock::ClockDuration::from_nanos(self.nanos)
92 }
93
94 pub fn negate(&self) -> Self {
95 Self {
96 days: -self.days,
97 nanos: -self.nanos,
98 }
99 }
100
101 pub fn total_seconds(&self) -> i64 {
102 self.to_seconds().unwrap_or(0)
103 }
104
105 pub fn divide_by(&self, factor: i32) -> Outcome<Self> {
106 if factor == 0 {
107 return Err(err!("Cannot divide duration by zero"; Invalid, Input));
108 }
109
110 let total_nanos = self.days as i64 * 24 * 60 * 60 * 1_000_000_000 + self.nanos;
111 let divided_nanos = total_nanos / factor as i64;
112
113 let new_days = (divided_nanos / (24 * 60 * 60 * 1_000_000_000)) as i32;
114 let remaining_nanos = divided_nanos % (24 * 60 * 60 * 1_000_000_000);
115
116 Ok(Self {
117 days: new_days,
118 nanos: remaining_nanos,
119 })
120 }
121}
122
123impl Duration for CalClockDuration {
124 fn to_nanos(&self) -> Outcome<i64> {
125 let day_nanos = self.days as i64 * 24 * 60 * 60 * 1_000_000_000;
126 Ok(day_nanos + self.nanos)
127 }
128
129 fn to_seconds(&self) -> Outcome<i64> {
130 let total_nanos = res!(self.to_nanos());
131 Ok(total_nanos / 1_000_000_000)
132 }
133
134 fn to_days(&self) -> Outcome<i32> {
135 Ok(self.days)
136 }
137
138 fn is_negative(&self) -> bool {
139 self.days < 0 || (self.days == 0 && self.nanos < 0)
140 }
141}
142
143impl std::fmt::Display for CalClockDuration {
144 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
145 if self.days != 0 {
146 write!(f, "{}d {}ns", self.days, self.nanos)
147 } else {
148 write!(f, "{}ns", self.nanos)
149 }
150 }
151}