| 245 | } |
| 246 | |
| 247 | void |
| 248 | clock_ts_to_ct(const struct timespec *ts, struct clocktime *ct) |
| 249 | { |
| 250 | time_t i, year, days; |
| 251 | time_t rsec; /* remainder seconds */ |
| 252 | time_t secs; |
| 253 | |
| 254 | secs = ts->tv_sec; |
| 255 | days = secs / SECDAY; |
| 256 | rsec = secs % SECDAY; |
| 257 | |
| 258 | ct->dow = day_of_week(days); |
| 259 | |
| 260 | /* Subtract out whole years. */ |
| 261 | if (days >= recent_base_days) { |
| 262 | year = recent_base_year; |
| 263 | days -= recent_base_days; |
| 264 | } else { |
| 265 | year = POSIX_BASE_YEAR; |
| 266 | } |
| 267 | for (; days >= days_in_year(year); year++) |
| 268 | days -= days_in_year(year); |
| 269 | ct->year = year; |
| 270 | |
| 271 | /* Subtract out whole months, counting them in i. */ |
| 272 | for (i = 1; days >= days_in_month(year, i); i++) |
| 273 | days -= days_in_month(year, i); |
| 274 | ct->mon = i; |
| 275 | |
| 276 | /* Days are what is left over (+1) from all that. */ |
| 277 | ct->day = days + 1; |
| 278 | |
| 279 | /* Hours, minutes, seconds are easy */ |
| 280 | ct->hour = rsec / 3600; |
| 281 | rsec = rsec % 3600; |
| 282 | ct->min = rsec / 60; |
| 283 | rsec = rsec % 60; |
| 284 | ct->sec = rsec; |
| 285 | ct->nsec = ts->tv_nsec; |
| 286 | if (ct_debug) { |
| 287 | printf("ts_to_ct(%jd.%09ld) = [", |
| 288 | (intmax_t)ts->tv_sec, ts->tv_nsec); |
| 289 | clock_print_ct(ct, 9); |
| 290 | printf("]\n"); |
| 291 | } |
| 292 | |
| 293 | KASSERT(ct->year >= 0 && ct->year < 10000, |
| 294 | ("year %d isn't a 4 digit year", ct->year)); |
| 295 | KASSERT(ct->mon >= 1 && ct->mon <= 12, |
| 296 | ("month %d not in 1-12", ct->mon)); |
| 297 | KASSERT(ct->day >= 1 && ct->day <= 31, |
| 298 | ("day %d not in 1-31", ct->day)); |
| 299 | KASSERT(ct->hour >= 0 && ct->hour <= 23, |
| 300 | ("hour %d not in 0-23", ct->hour)); |
| 301 | KASSERT(ct->min >= 0 && ct->min <= 59, |
| 302 | ("minute %d not in 0-59", ct->min)); |
| 303 | /* Not sure if this interface needs to handle leapseconds or not. */ |
| 304 | KASSERT(ct->sec >= 0 && ct->sec <= 60, |
no test coverage detected