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