56 #ifndef _POSIX_C_SOURCE
57 #define _POSIX_C_SOURCE 200809L
68 static struct timeval current_time = { 0, 0 };
72 static bool live_time_tracking =
true;
74 struct tm *
SCLocalTime(time_t timep,
struct tm *result);
75 struct tm *
SCUtcTime(time_t timep,
struct tm *result);
92 if (live_time_tracking)
99 live_time_tracking =
true;
105 live_time_tracking =
false;
111 return live_time_tracking;
116 if (live_time_tracking)
125 if (live_time_tracking)
132 current_time.tv_sec =
tv->tv_sec;
133 current_time.tv_usec =
tv->tv_usec;
135 SCLogDebug(
"time set to %" PRIuMAX
" sec, %" PRIuMAX
" usec",
136 (uintmax_t)current_time.tv_sec, (uintmax_t)current_time.tv_usec);
145 memset(&
tv, 0x00,
sizeof(
tv));
147 gettimeofday(&
tv, NULL);
158 if (live_time_tracking) {
159 gettimeofday(
tv, NULL);
164 tv->tv_sec = current_time.tv_sec;
165 tv->tv_usec = current_time.tv_usec;
175 SCLogDebug(
"time we got is %" PRIuMAX
" sec, %" PRIuMAX
" usec",
176 (uintmax_t)
tv->tv_sec, (uintmax_t)
tv->tv_usec);
185 memset(&
tv, 0x00,
sizeof(
tv));
199 static inline void WinStrftime(
const struct timeval *
ts,
const struct tm *t,
char *
str,
size_t size)
201 char time_fmt[64] = { 0 };
203 const long int tzdiff = -_timezone;
204 const int h = abs(_timezone) / 3600 + _daylight;
205 const int m = (abs(_timezone) % 3600) / 60;
206 snprintf(tz,
sizeof(tz),
"%c%02d%02d", tzdiff < 0 ?
'-' :
'+', h,
m);
207 strftime(time_fmt,
sizeof(time_fmt),
"%Y-%m-%dT%H:%M:%S.%%06u", t);
208 snprintf(
str, size, time_fmt,
ts->tv_usec);
215 time_t time =
ts->tv_sec;
217 memset(&local_tm, 0,
sizeof(local_tm));
218 struct tm *t = (
struct tm*)
SCLocalTime(time, &local_tm);
222 WinStrftime(
ts, t,
str, size);
224 char time_fmt[64] = { 0 };
225 int64_t usec =
ts->tv_usec;
226 strftime(time_fmt,
sizeof(time_fmt),
"%Y-%m-%dT%H:%M:%S.%%06" PRIi64
"%z", t);
227 snprintf(
str, size, time_fmt, usec);
230 snprintf(
str, size,
"ts-error");
236 time_t time =
ts->tv_sec;
238 memset(&local_tm, 0,
sizeof(local_tm));
239 struct tm *t = (
struct tm*)
SCUtcTime(time, &local_tm);
242 char time_fmt[64] = { 0 };
243 strftime(time_fmt,
sizeof(time_fmt),
"%Y-%m-%dT%H:%M:%S", t);
244 snprintf(
str, size, time_fmt,
ts->tv_usec);
246 snprintf(
str, size,
"ts-error");
253 strftime(
str, size, fmt, t);
255 snprintf(
str, size,
"ts-error");
261 return gmtime_r(&timep, result);
273 return localtime_r(&timep, result);
278 time_t time =
ts->tv_sec;
280 struct tm *t = (
struct tm*)
SCLocalTime(time, &local_tm);
283 snprintf(
str, size,
"%02d/%02d/%02d-%02d:%02d:%02d.%06u",
284 t->tm_mon + 1, t->tm_mday, t->tm_year + 1900, t->tm_hour,
285 t->tm_min, t->tm_sec, (uint32_t)
ts->tv_usec);
287 snprintf(
str, size,
"ts-error");
299 #define MAX_LOCAL_TIME_STRING 32
301 static thread_local
int mru_time_slot;
302 static thread_local time_t last_local_time[2];
303 static thread_local
short int cached_local_time_len[2];
304 static thread_local
char cached_local_time[2][MAX_LOCAL_TIME_STRING];
308 static thread_local
int mru_tm_slot;
309 static thread_local time_t cached_minute_start[2];
310 static thread_local
struct tm cached_local_tm[2];
334 struct tm *
SCLocalTime(time_t timep,
struct tm *result)
338 int mru = mru_tm_slot;
340 int mru_seconds = timep - cached_minute_start[mru];
341 int lru_seconds = timep - cached_minute_start[lru];
343 if (cached_minute_start[mru]==0 && cached_minute_start[lru]==0) {
344 localtime_r(&timep, &cached_local_tm[lru]);
346 new_seconds = cached_local_tm[lru].tm_sec;
347 cached_minute_start[lru] = timep - new_seconds;
350 }
else if (lru_seconds > 0 && (mru_seconds >= 0 && mru_seconds <= 59)) {
352 new_seconds = mru_seconds;
353 }
else if (mru_seconds > 0 && (lru_seconds >= 0 && lru_seconds <= 59)) {
355 new_seconds = lru_seconds;
360 if (localtime_r(&timep, &cached_local_tm[lru]) == NULL)
363 new_seconds = cached_local_tm[lru].tm_sec;
364 cached_minute_start[lru] = timep - new_seconds;
368 memcpy(result, &cached_local_tm[mru],
sizeof(
struct tm));
369 result->tm_sec = new_seconds;
375 static int UpdateCachedTime(
int n, time_t time)
378 struct tm *t = (
struct tm *)
SCLocalTime(time, &local_tm);
379 int cached_len = snprintf(cached_local_time[n], MAX_LOCAL_TIME_STRING,
380 "%02d/%02d/%02d-%02d:%02d:",
381 t->tm_mon + 1, t->tm_mday, t->tm_year + 1900,
382 t->tm_hour, t->tm_min);
383 cached_local_time_len[n] = cached_len;
385 last_local_time[n] = time - t->tm_sec;
399 time_t time =
ts->tv_sec;
404 int mru = mru_time_slot;
406 int mru_seconds = time - last_local_time[mru];
407 int lru_seconds = time - last_local_time[lru];
408 if (last_local_time[mru]==0 && last_local_time[lru]==0) {
410 UpdateCachedTime(mru, time);
411 seconds = UpdateCachedTime(lru, time);
412 }
else if (mru_seconds >= 0 && mru_seconds <= 59) {
414 seconds = mru_seconds;
415 }
else if (lru_seconds >= 0 && lru_seconds <= 59) {
417 seconds = lru_seconds;
422 seconds = UpdateCachedTime(lru, time);
427 char *cached_str = cached_local_time[mru_time_slot];
428 int cached_len = cached_local_time_len[mru_time_slot];
429 if (cached_len >= (
int)size)
431 memcpy(
str, cached_str, cached_len);
432 snprintf(
str + cached_len, size - cached_len,
434 seconds, (uint32_t)
ts->tv_usec);
453 #define MONTHSPERYEAR 12
455 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
458 result = (year - 1970) * 365 + mdays[tp->tm_mon %
MONTHSPERYEAR];
459 result += (year - 1968) / 4;
460 result -= (year - 1900) / 100;
461 result += (year - 1600) / 400;
462 if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0) &&
465 result += tp->tm_mday - 1;
467 result += tp->tm_hour;
469 result += tp->tm_min;
471 result += tp->tm_sec;
474 result -= tp->tm_gmtoff;
499 for (i = 0; i < num_patterns; i++)
501 if (patterns[i] == NULL)
504 tp->tm_hour = tp->tm_min = tp->tm_sec = 0;
505 tp->tm_year = tp->tm_mon = tp->tm_mday = tp->tm_wday = INT_MIN;
511 result =
strptime(
string, patterns[i], tp);
513 if (result && *result ==
'\0')
518 if (result == NULL || *result !=
'\0')
522 if (tp->tm_year == INT_MIN && tp->tm_mon == INT_MIN &&
523 tp->tm_mday == INT_MIN)
528 if (tp->tm_year != INT_MIN && tp->tm_mon != INT_MIN &&
551 memset(&tm, 0,
sizeof(tm));
552 struct tm *tp = (
struct tm *)
SCLocalTime(epoch, &tm);
553 char buffer[PATH_MAX] = { 0 };
559 int 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;