Subject: Notes about timezones...
From: [email-masked] (Keet / Foxbird)

2 Nov 1998 17:32:03 -0800
Message-ID: <[email-masked]>
Mime-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
To: [email-masked]

I've got a small program that utilizes the 'timezone' variable, or the
struct tm part of timezone. Appearently cygwin supports the 'timezone'
variable, but it doesn't work correctly. Here's part of the program:

    time_t lt = time((long *) 0);
    extern long timezone;
    return timezone;

That part will not compile because of the following error message:

temp.c: In function `main':
temp.c:10: `timezone' redeclared as different kind of symbol
D:\CygWin\b20\H-i586-cygwin32\lib\gcc-lib\i586-cygwin32\egcs-2.91.57\..\..\.
..\..
\i586-cygwin32\include\time.h:82: previous declaration of `timezone'

So I open up time.h and quote the following from line 82:

char *_EXFUN(timezone, (void));

So I take that to mean that timezone should be set as 'extern char
*timezone' or some derrivative.. I've tried just about everything, and no
go. I know I'm missing something here, but under unix 'extern long
timezone' is the correct way to define it.

Looking for an alternative, I decided to use _timezone, now that, is
defined as 'extern long _timezone' or as 'extern time_t timezone'  (either
work) and that compiles fine, if I change the above example to this:

    time_t lt = time((long *) 0);
    extern long _timezone;
    return _timezone;

and all compiles and runs until I look at the result:

    _timezone = 0 ???

That's certainly not true. So I snag a copy of the source (which took
forever to get over a 28.8 connection) and look in the winspu/times.cc file
and spot the following section:

--------------------------------------
#undef _timezone
#undef _daylight
#undef _tzname

time_t _timezone;
int _daylight;
char *_tzname[2] = { (char *) "GMT", (char *) "   " };

/* tzset: POSIX 8.3.2.1 */
/* This function initializes timezone variables.  */
extern "C"
void
tzset ()
{
  static NO_COPY char buf1[33], buf2[33];

  /* FIXME: This function should examine the TZ environment variable.
     Right now it just always sets information based on the system
     time zone.  */

  TIME_ZONE_INFORMATION tz;

  GetTimeZoneInformation (&tz);

  _timezone = tz.Bias * SECSPERMIN;
  _daylight = tz.DaylightBias != 0;
  WideCharToMultiByte (CP_ACP, 0, tz.StandardName, -1, buf1, sizeof buf1 - 1,
                       NULL, NULL);
  buf1[sizeof buf1 - 1] = '\0';
  _tzname[0] = buf1;
  WideCharToMultiByte (CP_ACP, 0, tz.DaylightName, -1, buf2, sizeof buf2 - 1,
                       NULL, NULL);
  buf2[sizeof buf2 - 1] = '\0';
  _tzname[1] = buf2;
}
-----------------------------

I looked at this and thought, hmmm.. it looks like it's definging _timezone
as the result of calling a WinAPI function, and multiplying by 60... and
the WinAPI function returns the # of minutes from UTC. Looks like it should
work to me, so where's the problem? To figure this out, I wrote a small
sample program that compares a bunch of variables.. but I need some help
interpreting this, and hopefully reach a fix for this ANNOYING problem.

--------- TEMP.C ----------------

#include <time.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <windows.h>

int main () {

extern long int _timezone;
//extern time_t _timezone;
extern long int *__imp__timezone;
struct timezone tzone;
TIME_ZONE_INFORMATION tz;
time_t lt = time((long *) 0);

GetTimeZoneInformation (&tz);

fprintf(stderr, "Using GetTimeZoneInformation: %d\n", tz.Bias * 60);
fprintf(stderr, "_timezone: %ld\n", _timezone);
fprintf(stderr, "*__imp__timezone: %ld\n", *__imp__timezone);
fprintf(stderr, "timezone.tz_minuteswest: %ld\n", tzone.tz_minuteswest);

}

-----------------------

The output is as follows:

Using GetTimeZoneInformation: 18000
_timezone: 0
*__imp__timezone: 0
timezone.tz_minuteswest: 39189696

Considering that I am in the -0500 timezone, 18000 is right for the number
of seconds from UTC, but 0, 0, and that 39189696 numbers are WAY off.
Looking back in review, I discover that calling the WinAPI function
directly returns the right timezone information, but calling the CygWin
functions that set that information based on the WinAPI call, are all
hosed. Anyone have any bright ideas?

Notice, that in the above example, I've got the 'time_t _timezone' part
commented out. The result is the same either way, I just left it that way
when I last compiled it.

Here are my system specs:

P133 - 80MB Ram
Windows 98
Cygwin B20

Results of cygcheck -s

----------------------

Cygnus Win95/NT Configuration Diagnostics
Current System Time: Sun Nov 01 22:21:36 1998

Win9X Ver 4.10 build 67766222  

Path:	/secondary/CYGWIN/B20/H-I586-CYGWIN32/BIN
	/secondary/CYGWIN/B20/TCL/BIN
	/secondary/BIN
	/usr/X11
	/usr/X11/BIN
	/usr/local/info
	/usr/local/include
	/usr/local/lib
	./
	/primary/WINDOWS
	/primary/WINDOWS/COMMAND
	/primary/WINDOWS
	/primary/WINDOWS/COMMAND
	/primary/MOONGLOW/FTP/BIN/PERL/BIN
	/primary/BIN
	/primary/XSW
	//E/MOONGLOW/FTP/BIN/BIN
	/secondary/PKWARE
	/primary/F-PROT
	/usr/local/include/X11R6.3
	/usr/X11/X11R6.3/BIN

SysDir: C:\WINDOWS\SYSTEM
WinDir: C:\WINDOWS

GCC_EXEC_PREFIX = `D:\CygWin\b20\H-i586-cygwin32\lib\gcc-lib\'
TCL_LIBRARY = `d:\CygWin\b20\share\tcl8.0\'
MAKE_MODE = `unix'
HOME = `/usr'

Use `-r' to scan registry

a:\ fd           N/A    N/A                    
c:\ hd  FAT32   1031Mb  83% CP    UN           HDA
d:\ hd  FAT32   1031Mb  31% CP    UN           HDB
e:\ hd  FAT32    956Mb  72% CP    UN           HDC1
f:\ fd  FAT       95Mb 100% CP    UN           CYGWIN32
g:\ cd           N/A    N/A                    

d:              /                   native  text!=binary
D:\bin          /bin                native  text!=binary
\\.\a:          /dev/fd0            native  text!=binary
\\.\b:          /dev/fd1            native  text!=binary
\\.\tape0:      /dev/st0            native  text!=binary
\\.\tape1:      /dev/st1            native  text!=binary
d:\usr\lib      /lib                native  text!=binary
d:\usr\man      /man                native  text!=binary
c:              /primary            native  text!=binary
d:              /secondary          native  text!=binary
d:\usr          /tertiary           native  text!=binary
d:\usr          /usr/X11            native  text!=binary
d:\usr\include  /usr/local/include  native  text!=binary
d:\usr\lib      /usr/local/info     native  text!=binary
d:\usr\man      /usr/local/lib      native  text!=binary
d:\usr\info     /usr/local/man      native  text!=binary

Found: d:\CYGWIN\B20\H-I586-CYGWIN32\BIN\bash.exe
Found: d:\BIN\bash.exe
Found: d:\CYGWIN\B20\H-I586-CYGWIN32\BIN\cat.exe
Not Found: cpp
Found: d:\CYGWIN\B20\H-I586-CYGWIN32\BIN\find.exe
Found: c:\WINDOWS\COMMAND\find.exe
Found: d:\CYGWIN\B20\H-I586-CYGWIN32\BIN\gcc.exe
Not Found: gdb
Found: d:\CYGWIN\B20\H-I586-CYGWIN32\BIN\ld.exe
Found: d:\CYGWIN\B20\H-I586-CYGWIN32\BIN\ls.exe
Found: d:\CYGWIN\B20\H-I586-CYGWIN32\BIN\make.exe
Found: d:\CYGWIN\B20\H-I586-CYGWIN32\BIN\sh.exe
Found: d:\BIN\sh.exe

  371k 1998/10/29 d:\CYGWIN\B20\H-I586-CYGWIN32\BIN\cygtcl80.dll
    5k 1998/10/29 d:\CYGWIN\B20\H-I586-CYGWIN32\BIN\cygtclpip80.dll
   10k 1998/10/29 d:\CYGWIN\B20\H-I586-CYGWIN32\BIN\cygtclreg80.dll
  600k 1998/10/29 d:\CYGWIN\B20\H-I586-CYGWIN32\BIN\cygtk80.dll
  429k 1998/10/29 d:\CYGWIN\B20\H-I586-CYGWIN32\BIN\cygwin1.dll
  429k 1998/10/29 d:\usr\cygwin1.dll
  429k 1998/10/29 d:\usr\cygwinb19.dll
Use -h to see help about each section

-------------------

Any help anyone could provide me would be GREATLY appreciated.

- Greg Neujahr
  [email-masked]

PS -- Please reply to my address, as well as the list.. it takes forever to
get traffic from the list for some reason.

-
For help on using this list (especially unsubscribing), send a message to
"[email-masked]" with one line of text: "help".