43 static const char* duration_str =
"duration";
64 ods_log_error(
"[%s] cannot create: allocator failed", duration_str);
132 ods_log_error(
"[%s] cannot create from string %s: create failed",
140 P = strchr(str,
'P');
142 ods_log_error(
"[%s] cannot create from string %s: P not found",
148 T = strchr(str,
'T');
149 X = strchr(str,
'Y');
151 duration->
years = atoi(str+1);
155 X = strchr(str,
'M');
156 if (X && (!T || (
size_t) (X-P) < (
size_t) (T-P))) {
157 duration->
months = atoi(str+1);
161 X = strchr(str,
'D');
163 duration->
days = atoi(str+1);
171 X = strchr(str,
'H');
173 duration->
hours = atoi(str+1);
177 X = strrchr(str,
'M');
178 if (X && T && (
size_t) (X-P) > (
size_t) (T-P)) {
179 duration->
minutes = atoi(str+1);
183 X = strchr(str,
'S');
185 duration->
seconds = atoi(str+1);
190 W = strchr(str,
'W');
198 duration->
weeks = atoi(str+1);
211 digits_in_number(time_t duration)
213 uint32_t period = (uint32_t) duration;
231 char* str = NULL, *num = NULL;
239 if (duration->
years > 0) {
240 count = count + 1 + digits_in_number(duration->
years);
242 if (duration->
months > 0) {
243 count = count + 1 + digits_in_number(duration->
months);
245 if (duration->
weeks > 0) {
246 count = count + 1 + digits_in_number(duration->
weeks);
248 if (duration->
days > 0) {
249 count = count + 1 + digits_in_number(duration->
days);
251 if (duration->
hours > 0) {
252 count = count + 1 + digits_in_number(duration->
hours);
256 count = count + 1 + digits_in_number(duration->
minutes);
260 count = count + 1 + digits_in_number(duration->
seconds);
267 str = (
char*) calloc(count,
sizeof(
char));
271 if (duration->
years > 0) {
272 count = digits_in_number(duration->
years);
273 num = (
char*) calloc(count+2,
sizeof(
char));
275 snprintf(num, count+2,
"%uY", (uint32_t) duration->
years);
276 str = strncat(str, num, count+2);
279 goto duration2string_num_calloc_failed;
282 if (duration->
months > 0) {
283 count = digits_in_number(duration->
months);
284 num = (
char*) calloc(count+2,
sizeof(
char));
286 snprintf(num, count+2,
"%uM", (uint32_t) duration->
months);
287 str = strncat(str, num, count+2);
290 goto duration2string_num_calloc_failed;
293 if (duration->
weeks > 0) {
294 count = digits_in_number(duration->
weeks);
295 num = (
char*) calloc(count+2,
sizeof(
char));
297 snprintf(num, count+2,
"%uW", (uint32_t) duration->
weeks);
298 str = strncat(str, num, count+2);
301 goto duration2string_num_calloc_failed;
304 if (duration->
days > 0) {
305 count = digits_in_number(duration->
days);
306 num = (
char*) calloc(count+2,
sizeof(
char));
308 snprintf(num, count+2,
"%uD", (uint32_t) duration->
days);
309 str = strncat(str, num, count+2);
312 goto duration2string_num_calloc_failed;
316 str = strncat(str,
"T", 1);
318 if (duration->
hours > 0) {
319 count = digits_in_number(duration->
hours);
320 num = (
char*) calloc(count+2,
sizeof(
char));
322 snprintf(num, count+2,
"%uH", (uint32_t) duration->
hours);
323 str = strncat(str, num, count+2);
326 goto duration2string_num_calloc_failed;
330 count = digits_in_number(duration->
minutes);
331 num = (
char*) calloc(count+2,
sizeof(
char));
333 snprintf(num, count+2,
"%uM", (uint32_t) duration->
minutes);
334 str = strncat(str, num, count+2);
337 goto duration2string_num_calloc_failed;
341 count = digits_in_number(duration->
seconds);
342 num = (
char*) calloc(count+2,
sizeof(
char));
344 snprintf(num, count+2,
"%uS", (uint32_t) duration->
seconds);
345 str = strncat(str, num, count+2);
348 goto duration2string_num_calloc_failed;
353 duration2string_num_calloc_failed:
354 ods_log_error(
"[%s] cannot create string: malloc error", duration_str);
372 period += (duration->
minutes)*60;
373 period += (duration->
hours)*3600;
374 period += (duration->
days)*86400;
375 period += (duration->
weeks)*86400*7;
376 period += (duration->
months)*86400*31;
377 period += (duration->
years)*86400*365;
383 duration_str, dstr?dstr:
"(null)");
397 return (a < b ? a : b);
407 return (a > b ? a : b);
418 #ifdef HAVE_ARC4RANDOM_UNIFORM
419 return (time_t) (arc4random_uniform((uint32_t) mod+1));
420 #elif HAVE_ARC4RANDOM
421 return (time_t) (arc4random() % (unsigned) mod+1);
423 return (time_t) (random() % (unsigned) mod+1);
429 static const int mdays[] = {
430 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
435 is_leap_year(
int year)
437 return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
442 leap_days(
int y1,
int y2)
446 return (y2/4 - y1/4) - (y2/100 - y1/100) + (y2/400 - y1/400);
450 #ifdef ENFORCER_TIMESHIFT
456 mktime_from_utc(
const struct tm *tm)
458 int year = 1900 + tm->tm_year;
459 time_t days = 365 * ((time_t) (year - 1970)) +
460 ((time_t) leap_days(1970, year));
466 for (i = 0; i < tm->tm_mon; ++i) {
469 if (tm->tm_mon > 1 && is_leap_year(year)) {
472 days += tm->tm_mday - 1;
474 hours = days * 24 + tm->tm_hour;
475 minutes = hours * 60 + tm->tm_min;
476 seconds = minutes * 60 + tm->tm_sec;
487 timeshift2time(
const char *time)
491 time_t timeshift = 0;
494 if (strptime(time,
"%Y%m%d%H%M%S", &tm)) {
495 timeshift = mktime_from_utc(&tm);
509 #ifdef ENFORCER_TIMESHIFT
510 const char* env = getenv(
"ENFORCER_TIMESHIFT");
512 return timeshift2time(env);
540 ods_log_error(
"[%s] time_datestamp: localtime() failed", duration_str);
544 if (strftime(outstr,
sizeof(outstr), format, tmp) == 0) {
545 ods_log_error(
"[%s] time_datestamp: strftime() failed", duration_str);
549 ut = (uint32_t) strtoul(outstr, NULL, 10);
551 *str = strdup(outstr);
557 time_itoa_reverse(
char* s)
562 for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
581 s[i++] = n % 10 +
'0';
582 }
while ((n /= 10) > 0);
584 time_itoa_reverse(s);