<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>