From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23656 invoked by alias); 6 Mar 2002 16:27:26 -0000 Mailing-List: contact libc-hacker-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sources.redhat.com Received: (qmail 23618 invoked from network); 6 Mar 2002 16:27:23 -0000 Received: from unknown (HELO sunsite.mff.cuni.cz) (195.113.19.66) by sources.redhat.com with SMTP; 6 Mar 2002 16:27:23 -0000 Received: (from jakub@localhost) by sunsite.mff.cuni.cz (8.11.6/8.11.6) id g26GRJS20882; Wed, 6 Mar 2002 17:27:19 +0100 Date: Wed, 06 Mar 2002 08:27:00 -0000 From: Jakub Jelinek To: Ulrich Drepper Cc: Glibc hackers Subject: [PATCH] Fix TZ env var handling Message-ID: <20020306172718.W2204@sunsite.ms.mff.cuni.cz> Reply-To: Jakub Jelinek Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5.1i X-SW-Source: 2002-03/txt/msg00027.txt.bz2 Hi! Setting TZ=AST-10ADT,M10.5.0/2,M3.5.0/3 results in all dates before 5th Sunday in October to use standard time, while only those between 5th Sunday in March and 5th Sunday in October should be standard time, the rest dst. Details in http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=60747 The problem is that tz_compute computes tz_rules[1].change in the next year, so when __tz_convert actually compares the times, it thinks all times until tz_rules[0].change are not daylight saving. This patch should speed things up, because with the next year compute_change we were never caching tz_rules[1].change (well, for southern hemisphere). Also, I have noticed that compute_change never returns anything but 1 (and likewise tz_compute), so I don't see why the return value should be ever checked. 2002-03-06 Jakub Jelinek * time/tzset.c (compute_change): Don't return any value. (tz_compute): Likewise. Don't handle southern hemisphere here. (__tz_convert): But here. --- libc/time/tzset.c.jj Thu Aug 23 18:51:42 2001 +++ libc/time/tzset.c Wed Mar 6 16:56:32 2002 @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-1999, 2000, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1991-1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -69,8 +69,8 @@ typedef struct static tz_rule tz_rules[2]; -static int compute_change __P ((tz_rule *rule, int year)) internal_function; -static int tz_compute __P ((const struct tm *tm)) +static void compute_change __P ((tz_rule *rule, int year)) internal_function; +static void tz_compute __P ((const struct tm *tm)) internal_function; static void tzset_internal __P ((int always)) internal_function; @@ -410,9 +410,8 @@ __tzname_max () /* Figure out the exact time (as a time_t) in YEAR when the change described by RULE will occur and - put it in RULE->change, saving YEAR in RULE->computed_for. - Return nonzero if successful, zero on failure. */ -static int + put it in RULE->change, saving YEAR in RULE->computed_for. */ +static void internal_function compute_change (rule, year) tz_rule *rule; @@ -422,7 +421,7 @@ compute_change (rule, year) if (year != -1 && rule->computed_for == year) /* Operations on times in 2 BC will be slower. Oh well. */ - return 1; + return; /* First set T to January 1st, 0:00:00 GMT in YEAR. */ if (year > 1970) @@ -498,28 +497,18 @@ compute_change (rule, year) rule->change = t - rule->offset + rule->secs; rule->computed_for = year; - return 1; } /* Figure out the correct timezone for TM and set `__tzname', - `__timezone', and `__daylight' accordingly. Return nonzero on - success, zero on failure. */ -static int + `__timezone', and `__daylight' accordingly. */ +static void internal_function tz_compute (tm) const struct tm *tm; { - if (! compute_change (&tz_rules[0], 1900 + tm->tm_year) - || ! compute_change (&tz_rules[1], 1900 + tm->tm_year)) - return 0; - /* We have to distinguish between northern and southern hemisphere. - For the latter the daylight saving time ends in the next year. - It is easier to detect this after first computing the time for the - wrong year since now we simply can compare the times to switch. */ - if (tz_rules[0].change > tz_rules[1].change - && ! compute_change (&tz_rules[1], 1900 + tm->tm_year + 1)) - return 0; + compute_change (&tz_rules[0], 1900 + tm->tm_year); + compute_change (&tz_rules[1], 1900 + tm->tm_year); __daylight = tz_rules[0].offset != tz_rules[1].offset; __timezone = -tz_rules[0].offset; @@ -535,8 +524,6 @@ tz_compute (tm) if (len1 > __tzname_cur_max) __tzname_cur_max = len1; } - - return 1; } /* Reinterpret the TZ environment variable and set `tzname'. */ @@ -590,8 +577,10 @@ __tz_convert (const time_t *timer, int u } else { - if (! (__offtime (timer, 0, tp) && tz_compute (tp))) + if (! __offtime (timer, 0, tp)) tp = NULL; + else + tz_compute (tp); leap_correction = 0L; leap_extra_secs = 0; } @@ -602,8 +591,18 @@ __tz_convert (const time_t *timer, int u { if (!__use_tzfile) { - int isdst = (*timer >= tz_rules[0].change - && *timer < tz_rules[1].change); + int isdst; + + /* We have to distinguish between northern and southern + hemisphere. For the latter the daylight saving time + ends in the next year. */ + if (__builtin_expect (tz_rules[0].change + > tz_rules[1].change, 0)) + isdst = (*timer < tz_rules[1].change + || *timer >= tz_rules[0].change); + else + isdst = (*timer >= tz_rules[0].change + && *timer < tz_rules[1].change); tp->tm_isdst = isdst; tp->tm_zone = __tzname[isdst]; tp->tm_gmtoff = tz_rules[isdst].offset; Jakub