X-Recipient: archive-cygwin@delorie.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 <Christian.Franke@t-online.de>
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@cygwin.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@cygwin.com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe@cygwin.com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin@cygwin.com>
List-Help: <mailto:cygwin-help@cygwin.com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner@cygwin.com
Mail-Followup-To: cygwin@cygwin.com
Delivered-To: mailing list cygwin@cygwin.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 <stdio.h>
#include <stdlib.h>
#include <time.h>

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

