/*#io docCopyright("Steve Dekorte", 2002) docLicense("BSD revised") */ #define DURATION_C #include "Duration.h" #undef DURATION_C #include #include #include #include typedef struct { double years; double days; double hours; double minutes; double seconds; } DurationComponents; Duration *Duration_new(void) { Duration *self = (Duration *)calloc(1, sizeof(Duration)); return self; } Duration *Duration_newWithSeconds_(double s) { Duration *self = Duration_new(); self->seconds = s; return self; } void Duration_copy_(Duration *self, Duration *other) { memcpy(self, other, sizeof(Duration)); } void Duration_free(Duration *self) { free(self); } int Duration_compare(Duration *self, Duration *other) { if (self->seconds == other->seconds) { return 0; } return self->seconds > other->seconds ? 1 : -1; } /* --- Components -------------------------------------------------------- */ #define SECONDS_IN_YEAR (60 * 60 * 24 * 365) #define SECONDS_IN_DAY (60 * 60 * 24) #define SECONDS_IN_HOUR (60 * 60) #define SECONDS_IN_MINUTE (60) DurationComponents Duration_asComponents(Duration *self) { DurationComponents c; double t = self->seconds; c.years = (int)(t / SECONDS_IN_YEAR); t -= (int)(c.years * SECONDS_IN_YEAR); c.days = (int)(t / SECONDS_IN_DAY); t -= (int)(c.days * SECONDS_IN_DAY); c.hours = (int)(t / SECONDS_IN_HOUR); t -= (int)(c.hours * SECONDS_IN_HOUR); c.minutes = (int)(t / SECONDS_IN_MINUTE); t -= (int)(c.minutes * SECONDS_IN_MINUTE); c.seconds = (t); return c; } void Duration_fromComponents_(Duration *self, DurationComponents c) { double t = c.years * SECONDS_IN_YEAR; t += c.days * SECONDS_IN_DAY; t += c.hours * SECONDS_IN_HOUR; t += c.minutes * SECONDS_IN_MINUTE; t += c.seconds; self->seconds = t; } // years -------------------------------------------------------- int Duration_years(Duration *self) { return (int)Duration_asComponents(self).years; } void Duration_setYears_(Duration *self, double y) { DurationComponents c = Duration_asComponents(self); c.years = y; Duration_fromComponents_(self, c); } // days -------------------------------------------------------- int Duration_days(Duration *self) { return (int)Duration_asComponents(self).days; } void Duration_setDays_(Duration *self, double d) { DurationComponents c = Duration_asComponents(self); c.days = d; Duration_fromComponents_(self, c); } // hours -------------------------------------------------------- int Duration_hours(Duration *self) { return (int)Duration_asComponents(self).hours; } void Duration_setHours_(Duration *self, double m) { DurationComponents c = Duration_asComponents(self); c.hours = m; Duration_fromComponents_(self, c); } // minutes -------------------------------------------------------- int Duration_minutes(Duration *self) { return (int)Duration_asComponents(self).minutes; } void Duration_setMinutes_(Duration *self, double m) { DurationComponents c = Duration_asComponents(self); c.minutes = m; Duration_fromComponents_(self, c); } // seconds -------------------------------------------------------- double Duration_seconds(Duration *self) { return Duration_asComponents(self).seconds; } void Duration_setSeconds_(Duration *self, double s) { DurationComponents c = Duration_asComponents(self); c.seconds = s; Duration_fromComponents_(self, c); } // total seconds -------------------------------------------------------- double Duration_asSeconds(Duration *self) { return self->seconds; } void Duration_fromSeconds_(Duration *self, double s) { self->seconds = s; } // strings -------------------------------------------------------- ByteArray *Duration_asByteArrayWithFormat_(Duration *self, const char *format) { DurationComponents c = Duration_asComponents(self); char s[128]; ByteArray *ba = ByteArray_newWithCString_(format?format:"%Y years %d days %H:%M:%S"); snprintf(s, 128, "%i", (int)c.years); ByteArray_replaceCString_withCString_(ba, "%Y", s); snprintf(s, 128, "%04i", (int)c.years); ByteArray_replaceCString_withCString_(ba, "%y", s); snprintf(s, 128, "%02i", (int)c.days); ByteArray_replaceCString_withCString_(ba, "%d", s); snprintf(s, 128, "%02i", (int)c.hours); ByteArray_replaceCString_withCString_(ba, "%H", s); snprintf(s, 128, "%02i", (int)c.minutes); ByteArray_replaceCString_withCString_(ba, "%M", s); snprintf(s, 128, "%02f", c.seconds); ByteArray_replaceCString_withCString_(ba, "%S", s); return ba; } void Duration_print(Duration *self) { ByteArray *ba = Duration_asByteArrayWithFormat_(self, NULL); ByteArray_print(ba); ByteArray_free(ba); } // math -------------------------------------------------------- void Duration_add_(Duration *self, Duration *other) { self->seconds += other->seconds; } void Duration_subtract_(Duration *self, Duration *other) { self->seconds -= other->seconds; }