X-Recipient: archive-cygwin AT delorie DOT com X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE,T_RP_MATCHES_RCVD,UNPARSEABLE_RELAY X-Spam-Check-By: sourceware.org Message-ID: <4F4FD8C6.5000807@t-online.de> Date: Thu, 01 Mar 2012 21:15:02 +0100 From: Christian Franke User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20120216 Firefox/10.0.2 SeaMonkey/2.7.2 MIME-Version: 1.0 To: cygwin AT cygwin DOT com Subject: Setting TZ may break time() in non-Cygwin programs Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 8bit X-IsSubscribed: yes Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com TZ environment variable is set by default since base-files 4.0.7. Unfortunately this breaks the time() calculation for all non-Cygwin programs run from Cygwin if Microsoft C runtime (mscrt*.dll) is used. MS CRT evaluates TZ but supports only a very old syntax subset. IIRC this is the case since VS1.x (DOS/Win16) and did not change since at least VS10. The TZ parser of MS CRT interprets "TZ=Europe/....." as "TZ=Eur+0ope". Hard coded US DST rules are always used if TZ is set. DST specifications in TZ are not supported. See testcase below. Cygwin already converts some environment variables from/to Win32 format. This IMO would make sense for TZ also. Simple: Unset TZ for Win32 programs run from Cygwin. More flexible: Set (unset) TZ=CYGWIN_WINENV_TZ if this variable is set (to empty). Otherwise keep TZ as is. If similar problems appear with other variables, the latter could be generalized for all variable names. Christian PS: Testcase $ uname -srv CYGWIN_NT-6.1-WOW64 1.7.12s(0.260/5/3) 20120227 12:56:51 $ cat tz.c #include #include #include int main() { time_t t; printf("TZ='%s'\n", getenv("TZ")); tzset(); printf("timezone=%ld, daylight=%d, tzname={\"%s\",\"%s\"}\n", timezone, !!daylight, tzname[0], tzname[1]); t = 1331431200-1; printf("%s", ctime(&t)); t++; // first second of US DST printf("%s", ctime(&t)); t += (14*24-1)*3600-1; printf("%s", ctime(&t)); t++; // first second of DE DST printf("%s", ctime(&t)); return 0; } $ gcc -o tzc tz.c $ i686-pc-mingw32-gcc -static -o tzw tz.c $ . /etc/profile.d/tzset.sh $ ./tzc TZ='Europe/Berlin' timezone=-3600, daylight=1, tzname={"CET","CEST"} Sun Mar 11 02:59:59 2012 Sun Mar 11 03:00:00 2012 Sun Mar 25 01:59:59 2012 Sun Mar 25 03:00:00 2012 $ ./tzw TZ='Europe/Berlin' timezone=0, daylight=1, tzname={"Eur","ope"} Sun Mar 11 01:59:59 2012 Sun Mar 11 03:00:00 2012 Sun Mar 25 01:59:59 2012 Sun Mar 25 02:00:00 2012 $ export TZ=CET-1CEST,M3.5.0/2,M10.5.0/2 $ ./tzc TZ='CET-1CEST,M3.5.0/2,M10.5.0/2' timezone=-3600, daylight=1, tzname={"CET","CEST"} Sun Mar 11 02:59:59 2012 Sun Mar 11 03:00:00 2012 Sun Mar 25 01:59:59 2012 Sun Mar 25 03:00:00 2012 $ ./tzw TZ='CET-1CEST,M3.5.0/2,M10.5.0/2' timezone=-3600, daylight=1, tzname={"CET","CES"} Sun Mar 11 03:59:59 2012 Sun Mar 11 04:00:00 2012 Sun Mar 25 02:59:59 2012 Sun Mar 25 03:00:00 2012 $ unset TZ $ ./tzc TZ='(null)' timezone=-3600, daylight=1, tzname={" "," "} Sun Mar 11 02:59:59 2012 Sun Mar 11 03:00:00 2012 Sun Mar 25 01:59:59 2012 Sun Mar 25 03:00:00 2012 $ ./tzw TZ='(null)' timezone=-3600, daylight=1, tzname=\ {"Mitteleuropäische Zeit","Mitteleuropäische Sommerzeit"} Sun Mar 11 02:59:59 2012 Sun Mar 11 03:00:00 2012 Sun Mar 25 01:59:59 2012 Sun Mar 25 03:00:00 2012 -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple