Skip to content

Commit 33e624f

Browse files
parser: Support system timezone in Time_Offset
Add the 'System' option to Time_Offset that uses the system timezone to compute the UTC offset during startup. As proposed in #593 Signed-off-by: Sijmen Huizenga <[email protected]>
1 parent b7ee1e8 commit 33e624f

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

src/flb_parser.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <sys/stat.h>
4444
#include <limits.h>
4545
#include <string.h>
46+
#include <time.h>
4647

4748
static inline uint32_t digits10(uint64_t v) {
4849
if (v < 10) return 1;
@@ -993,6 +994,21 @@ int flb_parser_do(struct flb_parser *parser, const char *buf, size_t length,
993994
return -1;
994995
}
995996

997+
int system_utc_offset(int *tmdiff)
998+
{
999+
#ifdef _WIN32
1000+
// Adjust the sign to match tm_gmtoff
1001+
*tmdiff = -_timezone;
1002+
return 0;
1003+
#else
1004+
time_t currentTime = time(NULL);
1005+
struct tm localTime = {0};
1006+
localtime_r(&currentTime, &localTime);
1007+
*tmdiff = localTime.tm_gmtoff;
1008+
return 0;
1009+
#endif
1010+
}
1011+
9961012
/* Given a timezone string, return it numeric offset */
9971013
int flb_parser_tzone_offset(const char *str, int len, int *tmdiff)
9981014
{
@@ -1009,6 +1025,11 @@ int flb_parser_tzone_offset(const char *str, int len, int *tmdiff)
10091025
return 0;
10101026
}
10111027

1028+
/* Check system timezones */
1029+
if (*p == 'S') {
1030+
return system_utc_offset(tmdiff);
1031+
}
1032+
10121033
/* Unexpected timezone string */
10131034
if (*p != '+' && *p != '-') {
10141035
*tmdiff = 0;

tests/internal/parser.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ struct tz_check tz_entries_ok[] = {
3737
{"-0600", -21600},
3838
{"-06:00", -21600},
3939
{"Z", 0},
40+
// System is mocked to timezone "HST" is -10 hours
41+
{"System", -36000},
4042
};
4143

4244
struct tz_check tz_entries_error[] = {
@@ -126,6 +128,35 @@ int flb_parser_regex_do(struct flb_parser *parser,
126128
void **out_buf, size_t *out_size,
127129
struct flb_time *out_time);
128130

131+
static char* mock_timezone(char *tz)
132+
{
133+
char *original_tz = getenv("TZ");
134+
if (original_tz) {
135+
original_tz = strdup(original_tz);
136+
if (!original_tz) {
137+
perror("Failed to allocate memory for original_tz");
138+
exit(EXIT_FAILURE);
139+
}
140+
}
141+
142+
setenv("TZ", tz, 1);
143+
tzset();
144+
145+
return original_tz;
146+
}
147+
148+
static void undo_mock_timezone(char *original_tz)
149+
{
150+
if (original_tz) {
151+
setenv("TZ", original_tz, 1);
152+
} else {
153+
unsetenv("TZ");
154+
}
155+
tzset();
156+
free(original_tz);
157+
}
158+
159+
129160
/* Parse timezone string and get the offset */
130161
void test_parser_tzone_offset()
131162
{
@@ -135,6 +166,9 @@ void test_parser_tzone_offset()
135166
int diff;
136167
struct tz_check *t;
137168

169+
/* Hawaii Standard Time chosen for not having daylight saving time */
170+
char *original_timezone = mock_timezone("HST");
171+
138172
/* Valid offsets */
139173
for (i = 0; i < sizeof(tz_entries_ok) / sizeof(struct tz_check); i++) {
140174
t = &tz_entries_ok[i];
@@ -154,6 +188,8 @@ void test_parser_tzone_offset()
154188
ret = flb_parser_tzone_offset(t->val, len, &diff);
155189
TEST_CHECK(ret != 0);
156190
}
191+
192+
undo_mock_timezone(original_timezone);
157193
}
158194

159195
static void load_json_parsers(struct flb_config *config)

0 commit comments

Comments
 (0)