diff --git a/configure.ac b/configure.ac index 5f201c2..c5c6448 100644 --- a/configure.ac +++ b/configure.ac @@ -61,6 +61,14 @@ AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([Doxyfile])], [AC_MSG_WARN(["Doxygen not found; continuing without doxygen support"])]) +# Check for the presence of tm_gmtoff in struct tm. If we have this, then we +# can use it to determine the true GMT offset +AC_CHECK_MEMBERS([struct tm.tm_gmtoff],, + [AC_MSG_WARN(["Cannot find tm_gmtoff in struct tm, using slower method"])], + [#define _GNU_SOURCE + #include + ]) + # Configuration headers AC_CONFIG_HEADERS([config.h]) diff --git a/lib/libx52/x52_date_time.c b/lib/libx52/x52_date_time.c index bd8ad41..fb732aa 100644 --- a/lib/libx52/x52_date_time.c +++ b/lib/libx52/x52_date_time.c @@ -18,6 +18,33 @@ #include "x52_commands.h" #include "x52_common.h" +#if !HAVE_STRUCT_TM_TM_GMTOFF +/* Slow method to compute GMT offset */ +static int _x52_compute_gmtoff(struct tm *timeval) +{ + char buf[20]; + size_t written; + int offset; + + /* This function uses strftime to get the timezone as a string, then + * converts that back into an integer offset. + */ + written = strftime(buf, sizeof(buf), "%z", timeval); + if (written != 5) { + /* Expect %z to return 5 characters - e.g. +0530, -0700, +0000 */ + return 0; + } + + offset = 600 * (buf[1] - '0') + 60 * (buf[2] - '0') + 10 * (buf[3] - '0') + (buf[4] - '0'); + if (buf[0] == '-') { + offset = -offset; + } else if (buf[0] != '+') { + offset = 0; + } + return offset; +} +#endif + int libx52_set_clock(libx52_device *x52, time_t time, int local) { struct tm timeval; @@ -36,10 +63,14 @@ int libx52_set_clock(libx52_device *x52, time_t time, int local) if (local) { ptr = localtime_r(&time, &timeval); - /* timezone from time.h presents the offset in seconds west of GMT. - * Negate and divide by 60 to get the offset in minutes east of GMT. + #if HAVE_STRUCT_TM_TM_GMTOFF + /* If valid, then timeval.tm_gmtoff contains the offset in seconds + * east of GMT. Divide by 60 to get the offset in minutes east of GMT. */ - local_tz = (int)(-timezone / 60); + local_tz = (int)(timeval.tm_gmtoff / 60); + #else + local_tz = _x52_compute_gmtoff(&timeval); + #endif } else { ptr = gmtime_r(&time, &timeval); /* No offset from GMT */ diff --git a/tests/libx52/test_timezone b/tests/libx52/test_timezone index 0a071c9..083e350 100755 --- a/tests/libx52/test_timezone +++ b/tests/libx52/test_timezone @@ -33,9 +33,6 @@ timezone_test() # Pacific Daylight Time # Default offset for clocks 2 & 3 should be +420 minutes off=420 - - # TODO: Remove the following line once #20 is fixed. - TEST_ID="$TEST_ID # TODO Fix issue #20" else # Pacific Standard time # Default offset for clocks 2 & 3 should be +480 minutes