Search code examples
timezoneposixubuntu-16.04

Why is the gettimeofday timezone wrong?


Both ftime and gettimeofday are returning 0 for the current timezone in Ubuntu 16. The timezone is set correctly in the date and time settings provided by Ubuntu. There is no TZ env variable set.

I don't want to just "fix" it because this is production software used in many different contexts. So I just want a reliable way of programmatically getting the timezone (and preferably the current DST offset as well).

My attempts so far:

#if 0
timeb tbTime;
ftime(&tbTime);
int CurTz = -tbTime.timezone;
#else
struct timeval tv;
struct timezone tz;
int r = gettimeofday(&tv, &tz);
if (r)
    return NO_ZONE;

int CurTz = tz.tz_minuteswest;
#endif

The 'date' command is working:

matthew@mallen-ubuntu:~$ date +%Z
AEDT
matthew@mallen-ubuntu:~$ date +%z
+1100

I could just spawn a process to call "date", but that seems very heavy handed when some API calls are available.


Solution

  • On GNU/Linux, the second argument of gettimeofday is quite useless and should always be NULL. The manual page for gettimeofday says this:

    The use of the timezone structure is obsolete; the tz argument should normally be specified as NULL.

    Even on non-Linux systems, the tz_dsttime has useless semantics (e.g., it reports that India uses DST because it did so for a brief period about seventy years ago).

    If you need to obtain the time zone for the current time, you need to use localtime or localtime_r and examine the broken-down time structure it produces (and not global variables such as daylight). The struct tm members you are probably interested are tm_isdst, tm_gmtoff, and perhaps tm_zone. The latter two are glibc extensions.