Timezone for Moscow is -10800 after installing tzdata-2014g
Hi All! My timezone is Europe/Moscow. After installing tzdata-2014g, tzset sets value for timezone not -14400 as before, but -10800, although time shift will be only in October 26th. Is this the expected behavior, or maybe I don't understand something? Please see below program I use for the test and output from console. Notice, how depends on what version of tzdata is installed value of timezone is different, although current time is the same. My question is: Why tzdata-2014g returns timezone for the Europe/Moscow -10800 (3 hours)? As far as I understand timezone for Moscow should be changed on the night of 25/26 October. Thank you, Alexander. ========== #include <iostream> #include <ctime> #include <cstdlib> using namespace std; int main() { tzset(); //set all 4 DST globals using TZ cout<< "the difference between UTC and the local standard time is: "<<timezone<<endl; cout<<boolalpha; //switch to verbal representation of bools cout<<"DST in effect: "<<(bool) daylight<<endl; cout<<"local standard time code: "<<tzname[0]<<endl; cout<<"local standard time code: "<<tzname[1]<<endl; } ========== ============== // With tzdata-2014g-installed [root@Linux jgm]# ./jtz the difference between UTC and the local standard time is: -10800 DST in effect: true local standard time code: MSK local standard time code: MSD [root@Linux jgm]# date Птн Окт 3 14:43:37 MSK 2014 //Let's downgrade to tzdata-2014b [root@Linux jgm]# yum downgrade tzdata-2014b-1.el6.noarch // skip lines Removed: tzdata.noarch 0:2014g-1.el6 Installed: tzdata.noarch 0:2014b-1.el6 Complete! [root@Linux jgm]# ./jtz the difference between UTC and the local standard time is: -14400 DST in effect: false local standard time code: MSK local standard time code: MSD [root@Linux jgm]# date Птн Окт 3 14:44:05 MSK 2014 //Let's return back to tzdata-2014g [root@Linux jgm]# yum update tzdata //skip lines Updated: tzdata.noarch 0:2014g-1.el6 Complete! [root@Linux jgm]# ./jtz the difference between UTC and the local standard time is: -10800 DST in effect: true local standard time code: MSK local standard time code: MSD [root@Linux jgm]# date Птн Окт 3 14:44:36 MSK 2014 [root@Linux jgm]# ==============
Alexander Koblov wrote:
Why tzdata-2014g returns timezone for the Europe/Moscow -10800 (3 hours)? As far as I understand timezone for Moscow should be changed on the night of 25/26 October.
Thanks for reporting the problem. It is a bit confusing here. When tzset is called, it does not know what time stamps you are interested in. It guesses, and its guess is based on time stamps that are farthest in the future. Here, tzcode's tzset behaves like the GNU C library and (I expect) like many other libraries. Since tzset is not required to prefer any particular time stamps, its behavior appears to be "correct", in the sense that it conforms to the standard and is reasonable for some applications (though evidently not for yours...). If you have a need for the UTC offset I suggest using the tm_gmtoff member of 'struct tm' if available, as tm_gmtoff is more reliable than 'timezone'. While looking into this issue I noticed a related problem: if your platform lacks tm_gmtoff and you are using single-threaded code, the 'timezone' variable should work better than it does. 'timezone' and 'altzone' should be compatible with what's in 'tzname', but in 2014h sometimes they are not. The attached proposed patch should fix that. This patch won't fix your test case, but it should fix some similar cases based on code that invokes 'localtime' or 'mktime' and which then inspects 'timezone' or 'altzone'. (This is not thread-safe, of course; multithreaded programs should use tm_gmtoff.)
On Fri, 03 Oct 2014, Paul Eggert wrote:
When tzset is called, it does not know what time stamps you are interested in. It guesses, and its guess is based on time stamps that are farthest in the future.
So, after calling tzset(), the global timezone variable will contain the UTC offset that would be in effect at some time in the very distant future. Other global variables similarly refer to what would be in effect in the distant future. Perhaps it would be more useful for tzset() to set global variables based on what would be appropriate for the instant when tzset() is called. This would not detract from tzset()'s other task of setting internal variables to refer to the rules for the local time zone, for use by localtime(), mktime(), and other time zone functions. Are these global variables documented as deprecated? --apb (Alan Barrett)
On 04/10/14 10:58, Alan Barrett wrote:
On Fri, 03 Oct 2014, Paul Eggert wrote:
When tzset is called, it does not know what time stamps you are interested in. It guesses, and its guess is based on time stamps that are farthest in the future.
So, after calling tzset(), the global timezone variable will contain the UTC offset that would be in effect at some time in the very distant future. Other global variables similarly refer to what would be in effect in the distant future.
Perhaps it would be more useful for tzset() to set global variables based on what would be appropriate for the instant when tzset() is called. This would not detract from tzset()'s other task of setting internal variables to refer to the rules for the local time zone, for use by localtime(), mktime(), and other time zone functions.
But then its behaviour would change depending when you called it, which seems undesirable. I guess what's really needed is a version of the function that takes a universal timestamp parameter; then it could set the variables according to the standard time in effect at the specified time.
Are these global variables documented as deprecated?
Are they deprecated? The replacements aren't part of the standard. -- -=( Ian Abbott @ MEV Ltd. E-mail: <abbotti@mev.co.uk> )=- -=( Tel: +44 (0)161 477 1898 FAX: +44 (0)161 718 3587 )=-
On Oct 4, 2014, at 2:58 AM, Alan Barrett <apb@cequrux.com> wrote:
On Fri, 03 Oct 2014, Paul Eggert wrote:
When tzset is called, it does not know what time stamps you are interested in. It guesses, and its guess is based on time stamps that are farthest in the future.
So, after calling tzset(), the global timezone variable will contain the UTC offset that would be in effect at some time in the very distant future. Other global variables similarly refer to what would be in effect in the distant future.
Perhaps it would be more useful for tzset() to set global variables based on what would be appropriate for the instant when tzset() is called. This would not detract from tzset()'s other task of setting internal variables to refer to the rules for the local time zone, for use by localtime(), mktime(), and other time zone functions.
Are these global variables documented as deprecated?
Sadly, no. They're not in the C standard at all. However, they *are* in the current version of POSIX, which is also the current version of the Single UNIX Specification; tzset() sets tzname[] and, if the system conforms to the X/Open System Interfaces option, timezone and daylight, and "local timezone information is used as though localtime() calls tzset()." localtime_r() need not set tzname[] and, if it doesn't, it also need not set timezone nor daylight. The Single UNIX Specification allows the tz database to be used, although it doesn't require it to be used. The TZ environment variable is set either to a standard POSIX-style tz string or to a colon followed by an implementation-dependent string; the latter was put in there for non-standard TZ settings such as tz database tzids. The SUS only specifies the behavior for standard POSIX-style tz string settings of TZ. Those settings specify only one local offset from UTC (which is for standard time), one pair of time zone abbreviations (one for standard time and one for daylight savings/summer time), and one indication of whether daylight savings time is used or not (so that a setting such as EST5EDT would set daylight to a non-zero value and EST5 would set it to 0), so tzname[], timezone, and daylight can be set from TZ and never change. If TZ is set to, for example, refer to a tz database tzid, the SUS doesn't indicate how tzname[], timezone, or daylight are set.
Alan Barrett wrote:
So, after calling tzset(), the global timezone variable will contain the UTC offset that would be in effect at some time in the very distant future. Other global variables similarly refer to what would be in effect in the distant future.
The 'daylight' global variable is OK, as its value is the same no matter what timestamp you're interested in. But yes, the values of 'timezone' and 'tzname' depend on the timestamp. In the POSIX-only world this is not a problem, since its time zones are so simple that 'timezone' and 'tzname' are invariants for each zone. But that is not true of tz database time zones.
Perhaps it would be more useful for tzset() to set global variables based on what would be appropriate for the instant when tzset() is called.
It's probably not worth the bother. For one thing, it'd be another system call; and Guy mentioned it'd cause tzset to behave differently depending on when you called it. If I get up the time and energy I'll try to get them removed from POSIX. There is no need for any of these variables. strftime's %Z obsoletes tzname for practical uses. And 'daylight' and 'timezone' are useless variables; they don't suffice even to support the POSIX model, since they assume that DST is one hour away from standard time, which means one cannot reliably use them to compute the UTC offset when tm_isdst is positive. And all these variables are inherently non-thread-safe, so even tzname is useless in multithreaded programs that call tzset (which is itself required to be thread-safe).
participants (5)
-
Alan Barrett -
Alexander Koblov -
Guy Harris -
Ian Abbott -
Paul Eggert