<html dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style id="owaParaStyle" type="text/css">P {margin-top:0;margin-bottom:0;}</style>
</head>
<body ocsi="0" fpstyle="1">
<div style="direction: ltr;font-family: Tahoma;color: #000000;font-size: 10pt;">I've started working with tzcode2012b and I've run into a couple of issues.<br>
<br>
The first: in testing, I found that if I set a timezone like "CST6", the tzname[] array would not be initialized. Digging into it, I found that settzname[] depends on having transition rules for the zone, but a zone like "CST6" will only be created with a
single type and no transitions.<br>
<br>
To work around that one I've added the following code to initialize the tzname[] array from the ttis array before running through the types array:<br>
<br>
+ for (i=0; i<sp->typecnt; i++) {<br>
+ const struct ttinfo * const ttisp = &sp->ttis[i];<br>
+ tzname[ttisp->tt_isdst] = &sp->chars[ttisp->tt_abbrind];<br>
+ }<br>
/*<br>
** And to get the latest zone names into tzname. . .<br>
*/<br>
for (i = 0; i < sp->timecnt; ++i) {<br>
register const struct ttinfo * const ttisp =<br>
&sp->ttis[<br>
sp->types[i]];<br>
<br>
The second has to do with our environment. We have an unfortunate time_t definition: an unsigned 32-bit number. The tzload code attempts to take unsigned time_t values into account, but if I'm not making a mistake understanding the way it's supposed to work,
I think it has a few problems.<br>
<br>
First, the loop over (i < sp->timecnt - 2) means that in comparing ats[i] > ats[i+1], you never compare ats[sp->timecnt-2] > ats[sp->timecnt-1]. This means that if all the transitions except the last are pre-epoch (negative number), the list doesn't get trimmed
down.<br>
<br>
Second, with that fixed, there are still problems with zones that only have pre-epoch transitions (e.g. America/Regina). In such a case, the ats[i] > ats[i+1] case never triggers, so you're left with a list of ats[] values that aren't valid -- they're negative
numbers in a system with an unsigned time_t.<br>
<br>
This is rather uglier. I've included my fix for what it's worth, but you can probably work out something better. One thing to note: I try to preserve the last pre-epoch transition, to handle situations where there's a large gap in transitions between the
start of the epoch the the first post-epoch transition.<br>
<br>
/*<br>
** Out-of-sort ats should mean we're running on a<br>
** signed time_t system but using a data file with<br>
** unsigned values (or vice versa).<br>
*/<br>
#if 1<br>
for (i = 0; i <= sp->timecnt - 1; ++i)<br>
if ( (i < sp->timecnt-1 && sp->ats[i] > sp->ats[i + 1] ) || <br>
(i == sp->timecnt-1 && !TYPE_SIGNED(time_t) && sp->ats[i] > INT32_MAX) ) {<br>
if (TYPE_SIGNED(time_t)) {<br>
/*<br>
** Ignore the end (easy).<br>
*/<br>
sp->timecnt = i+1;<br>
} else {<br>
/*<br>
** Ignore the beginning (harder).<br>
*/<br>
register int j;<br>
<br>
// keep the record right before the epoch boundary, but<br>
// tweak it so that it starts right with the epoch<br>
sp->ats[i] = 0;<br>
<br>
// move everything back...<br>
if (i > 0) {<br>
for (j = 0; j + i < sp->timecnt; ++j) {<br>
sp->ats[j] = sp->ats[j + i];<br>
sp->types[j] = sp->types[j + i];<br>
}<br>
sp->timecnt = j;<br>
}<br>
}<br>
break;<br>
}<br>
#else<br>
for (i = 0; i < sp->timecnt - 2; ++i)<br>
if (sp->ats[i] > sp->ats[i + 1]) {<br>
++i;<br>
if (TYPE_SIGNED(time_t)) {<br>
/*<br>
** Ignore the end (easy).<br>
*/<br>
sp->timecnt = i;<br>
} else {<br>
/*<br>
** Ignore the beginning (harder).<br>
*/<br>
register int j;<br>
<br>
for (j = 0; j + i < sp->timecnt; ++j) {<br>
sp->ats[j] = sp->ats[j + i];<br>
sp->types[j] = sp->types[j + i];<br>
}<br>
sp->timecnt = j;<br>
}<br>
break;<br>
}<br>
#endif<br>
<br>
I appreciate any assistance with this.<br>
<br>
Doug<br>
<br>
</div>
</body>
</html>