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;
233 char* str = NULL, *num = NULL;
241 if (duration->
years > 0) {
242 count = count + 1 + digits_in_number(duration->
years);
245 if (duration->
months > 0) {
246 count = count + 1 + digits_in_number(duration->
months);
249 if (duration->
weeks > 0) {
250 count = count + 1 + digits_in_number(duration->
weeks);
253 if (duration->
days > 0) {
254 count = count + 1 + digits_in_number(duration->
days);
257 if (duration->
hours > 0) {
258 count = count + 1 + digits_in_number(duration->
hours);
262 count = count + 1 + digits_in_number(duration->
minutes);
267 count = count + 1 + digits_in_number(duration->
seconds);
274 str = (
char*) calloc(count,
sizeof(
char));
278 if (duration->
years > 0) {
279 count = digits_in_number(duration->
years);
280 num = (
char*) calloc(count+2,
sizeof(
char));
281 snprintf(num, count+2,
"%uY", (uint32_t) duration->
years);
282 str = strncat(str, num, count+2);
285 if (duration->
months > 0) {
286 count = digits_in_number(duration->
months);
287 num = (
char*) calloc(count+2,
sizeof(
char));
288 snprintf(num, count+2,
"%uM", (uint32_t) duration->
months);
289 str = strncat(str, num, count+2);
292 if (duration->
weeks > 0) {
293 count = digits_in_number(duration->
weeks);
294 num = (
char*) calloc(count+2,
sizeof(
char));
295 snprintf(num, count+2,
"%uW", (uint32_t) duration->
weeks);
296 str = strncat(str, num, count+2);
299 if (duration->
days > 0) {
300 count = digits_in_number(duration->
days);
301 num = (
char*) calloc(count+2,
sizeof(
char));
302 snprintf(num, count+2,
"%uD", (uint32_t) duration->
days);
303 str = strncat(str, num, count+2);
307 str = strncat(str,
"T", 1);
309 if (duration->
hours > 0) {
310 count = digits_in_number(duration->
hours);
311 num = (
char*) calloc(count+2,
sizeof(
char));
312 snprintf(num, count+2,
"%uH", (uint32_t) duration->
hours);
313 str = strncat(str, num, count+2);
317 count = digits_in_number(duration->
minutes);
318 num = (
char*) calloc(count+2,
sizeof(
char));
319 snprintf(num, count+2,
"%uM", (uint32_t) duration->
minutes);
320 str = strncat(str, num, count+2);
325 count = digits_in_number(duration->
seconds);
326 num = (
char*) calloc(count+2,
sizeof(
char));
327 snprintf(num, count+2,
"%uS", (uint32_t) duration->
seconds);
328 str = strncat(str, num, count+2);
347 period += (duration->
minutes)*60;
348 period += (duration->
hours)*3600;
349 period += (duration->
days)*86400;
350 period += (duration->
weeks)*86400*7;
351 period += (duration->
months)*86400*31;
352 period += (duration->
years)*86400*365;
358 duration_str, dstr?dstr:
"(null)");
372 return (a < b ? a : b);
382 return (a > b ? a : b);
393 #ifdef HAVE_ARC4RANDOM_UNIFORM
394 return (time_t) (arc4random_uniform((uint32_t) mod+1));
395 #elif HAVE_ARC4RANDOM
396 return (time_t) (arc4random() % (unsigned) mod+1);
398 return (time_t) (random() % (unsigned) mod+1);
404 static const int mdays[] = {
405 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
410 is_leap_year(
int year)
412 return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
417 leap_days(
int y1,
int y2)
421 return (y2/4 - y1/4) - (y2/100 - y1/100) + (y2/400 - y1/400);
430 mktime_from_utc(
const struct tm *tm)
432 int year = 1900 + tm->tm_year;
433 time_t days = 365 * (year - 1970) + leap_days(1970, year);
439 for (i = 0; i < tm->tm_mon; ++i) {
442 if (tm->tm_mon > 1 && is_leap_year(year)) {
445 days += tm->tm_mday - 1;
447 hours = days * 24 + tm->tm_hour;
448 minutes = hours * 60 + tm->tm_min;
449 seconds = minutes * 60 + tm->tm_sec;
460 timeshift2time(
const char *time)
464 time_t timeshift = 0;
467 if (strptime(time,
"%Y%m%d%H%M%S", &tm)) {
468 timeshift = mktime_from_utc(&tm);
481 #ifdef ENFORCER_TIMESHIFT
482 const char* env = getenv(
"ENFORCER_TIMESHIFT");
484 return timeshift2time(env);
512 ods_log_error(
"[%s] time_datestamp: localtime() failed", duration_str);
516 if (strftime(outstr,
sizeof(outstr), format, tmp) == 0) {
517 ods_log_error(
"[%s] time_datestamp: strftime() failed", duration_str);
521 ut = (uint32_t) strtoul(outstr, NULL, 10);
523 *str = strdup(outstr);
529 time_itoa_reverse(
char* s)
534 for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
553 s[i++] = n % 10 +
'0';
554 }
while ((n /= 10) > 0);
556 time_itoa_reverse(s);
uint32_t time_datestamp(time_t tt, const char *format, char **str)
void * allocator_alloc(allocator_type *allocator, size_t size)
duration_type * duration_create(void)
void ods_log_error(const char *format,...)
void duration_cleanup(duration_type *duration)
time_t time_maximum(time_t a, time_t b)
allocator_type * allocator_create(void *(*allocator)(size_t size), void(*deallocator)(void *))
char * duration2string(duration_type *duration)
time_t duration2time(duration_type *duration)
int duration_compare(duration_type *d1, duration_type *d2)
void allocator_cleanup(allocator_type *allocator)
void time_itoa(time_t n, char *s)
void allocator_deallocate(allocator_type *allocator, void *data)
allocator_type * allocator
duration_type * duration_create_from_string(const char *str)
time_t ods_rand(time_t mod)
time_t time_minimum(time_t a, time_t b)
void ods_log_warning(const char *format,...)