While working on the Ubuntu 12.04.3 LTS box, I just noticed that localtime () and localtime_r () behave differently when the system time zone changes throughout the entire life cycle of the process: localtime () immediately changes the time zone change, whereas localtime_r () does not seem to adhere to what was the time zone when starting the process. Is this expected behavior? I have not seen this anywhere.
More precisely, when I use the following code ...
#include <stdio.h> #include <sys/time.h> #include <time.h> #include <unistd.h> int main() { while (1) { time_t t = time(NULL); struct tm *tm = localtime(&t); printf("localtime:%02d/%02d/%02d-%02d:%02d:%02d\n", tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec); sleep(1); } return 0; }
... and change the time zone from UTC through ...
# echo 'Europe/Berlin' > /etc/timezone
... then the code creates the following ...
localtime:10/04/2013-01:11:33 localtime:10/04/2013-01:11:34 localtime:10/04/2013-01:11:35 localtime:10/03/2013-23:11:36 localtime:10/03/2013-23:11:37 localtime:10/03/2013-23:11:38
... but if I use:
#include <stdio.h> #include <sys/time.h> #include <time.h> #include <unistd.h> int main() { while (1) { time_t t = time(NULL); struct tm local_tm; struct tm *tm = localtime_r(&t, &local_tm); printf("localtime_r:%02d/%02d/%02d-%02d:%02d:%02d\n", tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec); sleep(1); } return 0; }
... then there are no changes when making a similar change in time zone:
localtime_r:10/04/2013-01:15:37 localtime_r:10/04/2013-01:15:38 localtime_r:10/04/2013-01:15:39 localtime_r:10/04/2013-01:15:40 localtime_r:10/04/2013-01:15:41 localtime_r:10/04/2013-01:15:42
UPDATE: adding a call to tzset () before calling localtime_r () causes the expected behavior. Whether this is clear from the spec / manpage or not (see the discussion below) is a question for mentalhealth.stackexchange.com ...