1 //metadoc Duration copyright Steve Dekorte 2002
2 //metadoc Duration license BSD revised
3
4 #define DURATION_C
5 #include "Duration.h"
6 #undef DURATION_C
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <math.h>
11
12 typedef struct
13 {
14 double years;
15 double days;
16 double hours;
17 double minutes;
18 double seconds;
19 } DurationComponents;
20
Duration_new(void)21 Duration *Duration_new(void)
22 {
23 Duration *self = (Duration *)io_calloc(1, sizeof(Duration));
24 return self;
25 }
26
Duration_newWithSeconds_(double s)27 Duration *Duration_newWithSeconds_(double s)
28 {
29 Duration *self = Duration_new();
30 self->seconds = s;
31 return self;
32 }
33
Duration_copy_(Duration * self,const Duration * other)34 void Duration_copy_(Duration *self, const Duration *other)
35 {
36 memcpy(self, other, sizeof(Duration));
37 }
38
Duration_free(Duration * self)39 void Duration_free(Duration *self)
40 {
41 io_free(self);
42 }
43
Duration_compare(const Duration * self,const Duration * other)44 int Duration_compare(const Duration *self, const Duration *other)
45 {
46 if (self->seconds == other->seconds)
47 {
48 return 0;
49 }
50
51 return self->seconds > other->seconds ? 1 : -1;
52 }
53
54 // components --------------------------------------------------------
55
56 #define SECONDS_IN_YEAR (60 * 60 * 24 * 365)
57 #define SECONDS_IN_DAY (60 * 60 * 24)
58 #define SECONDS_IN_HOUR (60 * 60)
59 #define SECONDS_IN_MINUTE (60)
60
Duration_asComponents(const Duration * self)61 DurationComponents Duration_asComponents(const Duration *self)
62 {
63 DurationComponents c;
64 double t = self->seconds;
65 c.years = (int)(t / SECONDS_IN_YEAR); t -= (int)(c.years * SECONDS_IN_YEAR);
66 c.days = (int)(t / SECONDS_IN_DAY); t -= (int)(c.days * SECONDS_IN_DAY);
67 c.hours = (int)(t / SECONDS_IN_HOUR); t -= (int)(c.hours * SECONDS_IN_HOUR);
68 c.minutes = (int)(t / SECONDS_IN_MINUTE); t -= (int)(c.minutes * SECONDS_IN_MINUTE);
69 c.seconds = (t);
70 return c;
71 }
72
Duration_fromComponents_(Duration * self,DurationComponents c)73 void Duration_fromComponents_(Duration *self, DurationComponents c)
74 {
75 double t = c.years * SECONDS_IN_YEAR;
76 t += c.days * SECONDS_IN_DAY;
77 t += c.hours * SECONDS_IN_HOUR;
78 t += c.minutes * SECONDS_IN_MINUTE;
79 t += c.seconds;
80 self->seconds = t;
81 }
82
83 // years --------------------------------------------------------
84
Duration_years(const Duration * self)85 int Duration_years(const Duration *self)
86 {
87 return (int)Duration_asComponents(self).years;
88 }
89
Duration_setYears_(Duration * self,double y)90 void Duration_setYears_(Duration *self, double y)
91 {
92 DurationComponents c = Duration_asComponents(self);
93 c.years = y;
94 Duration_fromComponents_(self, c);
95 }
96
97 // days --------------------------------------------------------
98
Duration_days(const Duration * self)99 int Duration_days(const Duration *self)
100 {
101 return (int)Duration_asComponents(self).days;
102 }
103
Duration_setDays_(Duration * self,double d)104 void Duration_setDays_(Duration *self, double d)
105 {
106 DurationComponents c = Duration_asComponents(self);
107 c.days = d;
108 Duration_fromComponents_(self, c);
109 }
110
111 // hours --------------------------------------------------------
112
Duration_hours(const Duration * self)113 int Duration_hours(const Duration *self)
114 {
115 return (int)Duration_asComponents(self).hours;
116 }
117
Duration_setHours_(Duration * self,double m)118 void Duration_setHours_(Duration *self, double m)
119 {
120 DurationComponents c = Duration_asComponents(self);
121 c.hours = m;
122 Duration_fromComponents_(self, c);
123 }
124
125 // minutes --------------------------------------------------------
126
Duration_minutes(const Duration * self)127 int Duration_minutes(const Duration *self)
128 {
129 return (int)Duration_asComponents(self).minutes;
130 }
131
Duration_setMinutes_(Duration * self,double m)132 void Duration_setMinutes_(Duration *self, double m)
133 {
134 DurationComponents c = Duration_asComponents(self);
135 c.minutes = m;
136 Duration_fromComponents_(self, c);
137 }
138
139 // seconds --------------------------------------------------------
140
Duration_seconds(const Duration * self)141 double Duration_seconds(const Duration *self)
142 {
143 return Duration_asComponents(self).seconds;
144 }
145
Duration_setSeconds_(Duration * self,double s)146 void Duration_setSeconds_(Duration *self, double s)
147 {
148 DurationComponents c = Duration_asComponents(self);
149 c.seconds = s;
150 Duration_fromComponents_(self, c);
151 }
152
153 // total seconds --------------------------------------------------------
154
Duration_asSeconds(const Duration * self)155 double Duration_asSeconds(const Duration *self)
156 {
157 return self->seconds;
158 }
159
Duration_fromSeconds_(Duration * self,double s)160 void Duration_fromSeconds_(Duration *self, double s)
161 {
162 self->seconds = s;
163 }
164
165 // strings --------------------------------------------------------
166
Duration_asUArrayWithFormat_(const Duration * self,const char * format)167 UArray *Duration_asUArrayWithFormat_(const Duration *self, const char *format)
168 {
169 DurationComponents c = Duration_asComponents(self);
170 char s[128];
171 UArray *ba = UArray_newWithCString_(format?format:"%Y years %d days %H:%M:%S");
172
173 snprintf(s, 128, "%i", (int)c.years);
174 UArray_replaceCString_withCString_(ba, "%Y", s);
175
176 snprintf(s, 128, "%04i", (int)c.years);
177 UArray_replaceCString_withCString_(ba, "%y", s);
178
179 snprintf(s, 128, "%02i", (int)c.days);
180 UArray_replaceCString_withCString_(ba, "%d", s);
181
182 snprintf(s, 128, "%02i", (int)c.hours);
183 UArray_replaceCString_withCString_(ba, "%H", s);
184
185 snprintf(s, 128, "%02i", (int)c.minutes);
186 UArray_replaceCString_withCString_(ba, "%M", s);
187
188 snprintf(s, 128, "%02f", c.seconds);
189 UArray_replaceCString_withCString_(ba, "%S", s);
190
191 return ba;
192 }
193
Duration_print(const Duration * self)194 void Duration_print(const Duration *self)
195 {
196 UArray *ba = Duration_asUArrayWithFormat_(self, NULL);
197 UArray_print(ba);
198 UArray_free(ba);
199 }
200
201 // math --------------------------------------------------------
202
Duration_add_(Duration * self,const Duration * other)203 void Duration_add_(Duration *self, const Duration *other)
204 {
205 self->seconds += other->seconds;
206 }
207
Duration_subtract_(Duration * self,const Duration * other)208 void Duration_subtract_(Duration *self, const Duration *other)
209 {
210 self->seconds -= other->seconds;
211 }
212
213