56 #ifndef _POSIX_C_SOURCE
57 #define _POSIX_C_SOURCE 200809L
71 static struct timeval current_time = { 0, 0 };
75 static bool live_time_tracking =
true;
77 struct tm *
SCLocalTime(time_t timep,
struct tm *result);
78 struct tm *
SCUtcTime(time_t timep,
struct tm *result);
95 if (live_time_tracking)
102 live_time_tracking =
true;
108 live_time_tracking =
false;
114 return live_time_tracking;
119 if (live_time_tracking)
128 if (live_time_tracking)
134 SCLogDebug(
"time set to %" PRIuMAX
" sec, %" PRIuMAX
" usec",
135 (uintmax_t)current_time.tv_sec, (uintmax_t)current_time.tv_usec);
144 memset(&
tv, 0x00,
sizeof(
tv));
146 gettimeofday(&
tv, NULL);
155 struct timeval
tv = { 0 };
156 if (live_time_tracking) {
157 gettimeofday(&
tv, NULL);
162 tv.tv_sec = current_time.tv_sec;
163 tv.tv_usec = current_time.tv_usec;
173 SCLogDebug(
"time we got is %" PRIuMAX
" sec, %" PRIuMAX
" usec", (uintmax_t)
tv.tv_sec,
174 (uintmax_t)
tv.tv_usec);
196 static inline void WinStrftime(
const SCTime_t ts,
const struct tm *t,
char *
str,
size_t size)
198 char time_fmt[64] = { 0 };
200 const long int tzdiff = -_timezone;
201 const int h = abs(_timezone) / 3600 + _daylight;
202 const int m = (abs(_timezone) % 3600) / 60;
203 snprintf(tz,
sizeof(tz),
"%c%02d%02d", tzdiff < 0 ?
'-' :
'+', h,
m);
204 strftime(time_fmt,
sizeof(time_fmt),
"%Y-%m-%dT%H:%M:%S.%%06u", t);
214 memset(&local_tm, 0,
sizeof(local_tm));
215 struct tm *t = (
struct tm*)
SCLocalTime(time, &local_tm);
219 WinStrftime(
ts, t,
str, size);
221 char time_fmt[64] = { 0 };
223 strftime(time_fmt,
sizeof(time_fmt),
"%Y-%m-%dT%H:%M:%S.%%06" PRIi64
"%z", t);
224 snprintf(
str, size, time_fmt, usec);
227 snprintf(
str, size,
"ts-error");
235 memset(&local_tm, 0,
sizeof(local_tm));
236 struct tm *t = (
struct tm*)
SCUtcTime(time, &local_tm);
239 char time_fmt[64] = { 0 };
240 strftime(time_fmt,
sizeof(time_fmt),
"%Y-%m-%dT%H:%M:%S", t);
243 snprintf(
str, size,
"ts-error");
250 strftime(
str, size, fmt, t);
252 snprintf(
str, size,
"ts-error");
258 return gmtime_r(&timep, result);
270 return localtime_r(&timep, result);
277 struct tm *t = (
struct tm*)
SCLocalTime(time, &local_tm);
280 snprintf(
str, size,
"%02d/%02d/%02d-%02d:%02d:%02d.%06u", t->tm_mon + 1, t->tm_mday,
281 t->tm_year + 1900, t->tm_hour, t->tm_min, t->tm_sec, (uint32_t)
SCTIME_USECS(
ts));
283 snprintf(
str, size,
"ts-error");
295 #define MAX_LOCAL_TIME_STRING 32
297 static thread_local
int mru_time_slot;
298 static thread_local time_t last_local_time[2];
299 static thread_local
short int cached_local_time_len[2];
300 static thread_local
char cached_local_time[2][MAX_LOCAL_TIME_STRING];
304 static thread_local
int mru_tm_slot;
305 static thread_local time_t cached_minute_start[2];
306 static thread_local
struct tm cached_local_tm[2];
330 struct tm *
SCLocalTime(time_t timep,
struct tm *result)
334 int mru = mru_tm_slot;
336 int mru_seconds = timep - cached_minute_start[mru];
337 int lru_seconds = timep - cached_minute_start[lru];
339 if (cached_minute_start[mru]==0 && cached_minute_start[lru]==0) {
340 localtime_r(&timep, &cached_local_tm[lru]);
342 new_seconds = cached_local_tm[lru].tm_sec;
343 cached_minute_start[lru] = timep - new_seconds;
346 }
else if (lru_seconds > 0 && (mru_seconds >= 0 && mru_seconds <= 59)) {
348 new_seconds = mru_seconds;
349 }
else if (mru_seconds > 0 && (lru_seconds >= 0 && lru_seconds <= 59)) {
351 new_seconds = lru_seconds;
356 if (localtime_r(&timep, &cached_local_tm[lru]) == NULL)
359 new_seconds = cached_local_tm[lru].tm_sec;
360 cached_minute_start[lru] = timep - new_seconds;
364 memcpy(result, &cached_local_tm[mru],
sizeof(
struct tm));
365 result->tm_sec = new_seconds;
371 static int UpdateCachedTime(
int n, time_t time)
374 struct tm *t = (
struct tm *)
SCLocalTime(time, &local_tm);
375 int cached_len = snprintf(cached_local_time[n], MAX_LOCAL_TIME_STRING,
376 "%02d/%02d/%02d-%02d:%02d:",
377 t->tm_mon + 1, t->tm_mday, t->tm_year + 1900,
378 t->tm_hour, t->tm_min);
379 cached_local_time_len[n] = cached_len;
381 last_local_time[n] = time - t->tm_sec;
400 int mru = mru_time_slot;
402 int mru_seconds = time - last_local_time[mru];
403 int lru_seconds = time - last_local_time[lru];
404 if (last_local_time[mru]==0 && last_local_time[lru]==0) {
406 UpdateCachedTime(mru, time);
407 seconds = UpdateCachedTime(lru, time);
408 }
else if (mru_seconds >= 0 && mru_seconds <= 59) {
410 seconds = mru_seconds;
411 }
else if (lru_seconds >= 0 && lru_seconds <= 59) {
413 seconds = lru_seconds;
418 seconds = UpdateCachedTime(lru, time);
423 char *cached_str = cached_local_time[mru_time_slot];
424 int cached_len = cached_local_time_len[mru_time_slot];
425 if (cached_len >= (
int)size)
427 memcpy(
str, cached_str, cached_len);
428 snprintf(
str + cached_len, size - cached_len,
"%02d.%06u", seconds, (uint32_t)
SCTIME_USECS(
ts));
447 #define MONTHSPERYEAR 12
449 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
452 result = (year - 1970) * 365 + mdays[tp->tm_mon %
MONTHSPERYEAR];
453 result += (year - 1968) / 4;
454 result -= (year - 1900) / 100;
455 result += (year - 1600) / 400;
456 if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0) &&
459 result += tp->tm_mday - 1;
461 result += tp->tm_hour;
463 result += tp->tm_min;
465 result += tp->tm_sec;
468 result -= tp->tm_gmtoff;
493 for (i = 0; i < num_patterns; i++)
495 if (patterns[i] == NULL)
498 tp->tm_hour = tp->tm_min = tp->tm_sec = 0;
499 tp->tm_year = tp->tm_mon = tp->tm_mday = tp->tm_wday = INT_MIN;
505 result =
strptime(
string, patterns[i], tp);
507 if (result && *result ==
'\0')
512 if (result == NULL || *result !=
'\0')
516 if (tp->tm_year == INT_MIN && tp->tm_mon == INT_MIN &&
517 tp->tm_mday == INT_MIN)
522 if (tp->tm_year != INT_MIN && tp->tm_mon != INT_MIN &&
528 if (tp->tm_year != INT_MIN && tp->tm_mon <= 0 && tp->tm_mday <= 0) {
551 memset(&tm, 0,
sizeof(tm));
552 struct tm *tp = (
struct tm *)
SCLocalTime(epoch, &tm);
553 char buffer[PATH_MAX] = { 0 };
559 size_t r = strftime(buffer,
sizeof(buffer), pattern, tp);
580 uint64_t modifier = 1;
581 char last =
str[strlen(
str)-1];
600 modifier = 60 * 60 * 24;
604 modifier = 60 * 60 * 24 * 7;
612 size = strtoumax(
str, NULL, 10);
617 return (size * modifier);
630 uint64_t seconds = 0;
632 memset(&tm, 0,
sizeof(tm));
633 struct tm *tp = (
struct tm *)
SCLocalTime(epoch, &tm);
635 if (strcmp(
str,
"minute") == 0)
636 seconds = 60 - tp->tm_sec;
637 else if (strcmp(
str,
"hour") == 0)
638 seconds = (60 * (60 - tp->tm_min)) + (60 - tp->tm_sec);
639 else if (strcmp(
str,
"day") == 0)
640 seconds = (3600 * (24 - tp->tm_hour)) + (60 * (60 - tp->tm_min)) +
648 return ts->tv_sec * 1000L +
ts->tv_nsec / 1000000L;
653 return (uint64_t)(t1.tv_sec - t0.tv_sec) * 1000000L + (t1.tv_usec - t0.tv_usec);
657 static int CreateFormattedTimeStringTest01(
void)
677 struct tm *t =
SCLocalTime(mktime(&tm), &local_tm);
679 char buf[128] = { 0 };
682 FAIL_IF(strcmp(buf,
"01/13/14-04:30:00") != 0);
691 UtRegisterTest(
"CreateFormattedTimeStringTest01", CreateFormattedTimeStringTest01);