BE VERY CAREFUL when using setenv()/putenv(), there is a known memory
leak in the WATCOM Library. If you repeatedly set TZ (or any
envirenment var) in a process via setenv() you will eventually blow up
the heap and/or run out of memory on the machine.
What we have done is write our own fmt_local_time() function that does
local substitution of the TZ string in the (global) environ[] array, and
set our own time zone name if/when necessary. Modify as you see fit.
Note, dst is a flag meaning daylight savings time is supported for this
time zone (not that dst is in effect at “this” time). Also, we use an
internal format for time zone…
/*
- ushort_t timezone Local timezone in ZZ[MM]D format.
-
ZZ = standard "westerly" offset from UTC (00-23).
-
MM = Deviation from "on-the-hour" UTC in minutes.
-
D = 0/1 flag for dst is supported in this TZ
*/
char *fmt_local_time( ushort_t timezone, char *fmt, time_t *utc )
{
static char buf[80];
char *tz = NULL;
int i;
short dst,
zone,
mm;
char zn;
char tzn[2][8];
char *tznsav[2];
struct tm *tm;
/*
** Set new TZ environment variable, get local time, reset TZ
** Because there seems to be a bug in putenv() we’ll be doing a little
** fake out using ‘environ’
*/
dst = (timezone % 10) != 0;
zone = timezone / 10;
if ( zone > 99 ) {
mm = zone % 100;
zone = zone / 100;
} else {
mm = 0;
}
if ( zone > 23 || zone < 0 ) {
zone = 0;
} else
if ( zone > 11 ) {
zone = zone - 24;
}
switch( zone ) {
case 5: zn = ‘e’; break;
case 6: zn = ‘c’; break;
case 7: zn = ‘m’; break;
case 8: zn = ‘p’; break;
case 9: zn = ‘a’; break;
case 10: zn = ‘h’; break;
default: zn = ‘z’;
sprintf( tzn[0], “Z%+.2d%.2d”, -zone, mm );
sprintf( tzn[1], “Z%+.2d%.2d”, -(zone - 1), mm );
break;
}
if ( dst )
sprintf( buf, “TZ=%cst%d:%.2d%cdt%d:%.2d,M4.1.0/2,M10.5.0/2”
, zn, zone, mm, zn, zone-1, mm
);
else
sprintf( buf, “TZ=%cst%d:%.2d”, zn, zone, mm );
for ( i = 0; environ != NULL; i++ )
if ( memcmp( environ, “TZ=”, 3 ) == 0 ) {
tz = environ;
break;
}
if ( tz )
environ = buf;
else
putenv( buf );
tzset( );
tm = localtime( utc );
if ( zn == ‘z’ ) {
tznsav[0] = tzname[0];
tznsav[1] = tzname[1];
tzname[0] = tzn[0];
tzname[1] = tzn[1];
}
strftime( buf, 80, fmt, tm );
if ( tz )
environ = tz;
if ( zn == ‘z’ ) {
tzname[0] = tznsav[0];
tzname[1] = tznsav[1];
}
tzset( );
return( buf );
}
------------
-Rob
Robert Rutherford wrote:
On Mon, 23 May 2005 02:26:54 +0400, Tony wrote:
What is the easiest way of obtaining the UTC time and date in a process
running in the environment where the TZ is not UTC0?
I need both - having the TZ=MST-3MDT-4,M3.5.0/2,M10.5.0/3 in the
environment (the process must know the local time) and be able to get the
MJD (Modified Julian Date) in the same process.
gmtime() gives you the time in UTC
localtime() gives you the time according to the TZ variable
If you need anything more fancy than that, then you can always change the
value of the TZ variable using setenv() before you call any of the time
library functions (of course that is a bit more tricky if you have a
multi-threaded application).
Rob Rutherford
Ruzz Technology