<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 &quot;CST6&quot;, the tzname[] array would not be initialized.&nbsp; Digging into it, I found that settzname[] depends on having transition rules for the zone, but a zone like &quot;CST6&quot; 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>
&#43;&nbsp;&nbsp;&nbsp; for (i=0; i&lt;sp-&gt;typecnt; i&#43;&#43;) {<br>
&#43;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; const struct ttinfo * const&nbsp;&nbsp;&nbsp; ttisp = &amp;sp-&gt;ttis[i];<br>
&#43;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tzname[ttisp-&gt;tt_isdst] = &amp;sp-&gt;chars[ttisp-&gt;tt_abbrind];<br>
&#43;&nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; /*<br>
&nbsp;&nbsp;&nbsp; ** And to get the latest zone names into tzname. . .<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; sp-&gt;timecnt; &#43;&#43;i) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; register const struct ttinfo * const&nbsp;&nbsp;&nbsp; ttisp =<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &amp;sp-&gt;ttis[<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sp-&gt;types[i]];<br>
<br>
The second has to do with our environment.&nbsp; We have an unfortunate time_t definition: an unsigned 32-bit number.&nbsp; 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 &lt; sp-&gt;timecnt - 2) means that in comparing ats[i] &gt; ats[i&#43;1], you never compare ats[sp-&gt;timecnt-2] &gt; ats[sp-&gt;timecnt-1].&nbsp; 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).&nbsp; In such a case, the ats[i] &gt; ats[i&#43;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.&nbsp; I've included my fix for what it's worth, but you can probably work out something better.&nbsp; 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>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /*<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ** Out-of-sort ats should mean we're running on a<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ** signed time_t system but using a data file with<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ** unsigned values (or vice versa).<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; */<br>
#if 1<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for (i = 0; i &lt;= sp-&gt;timecnt - 1; &#43;&#43;i)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if ( (i &lt; sp-&gt;timecnt-1 &amp;&amp; sp-&gt;ats[i] &gt; sp-&gt;ats[i &#43; 1] ) || <br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (i == sp-&gt;timecnt-1 &amp;&amp; !TYPE_SIGNED(time_t) &amp;&amp; sp-&gt;ats[i] &gt; INT32_MAX) ) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (TYPE_SIGNED(time_t)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /*<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ** Ignore the end (easy).<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sp-&gt;timecnt = i&#43;1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /*<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ** Ignore the beginning (harder).<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; register int&nbsp;&nbsp;&nbsp; j;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // keep the record right before the epoch boundary, but<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // tweak it so that it starts right with the epoch<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sp-&gt;ats[i] = 0;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; // move everything back...<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (i &gt; 0) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for (j = 0; j &#43; i &lt; sp-&gt;timecnt; &#43;&#43;j) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sp-&gt;ats[j] = sp-&gt;ats[j &#43; i];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sp-&gt;types[j] = sp-&gt;types[j &#43; i];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sp-&gt;timecnt = j;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
#else<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for (i = 0; i &lt; sp-&gt;timecnt - 2; &#43;&#43;i)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (sp-&gt;ats[i] &gt; sp-&gt;ats[i &#43; 1]) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &#43;&#43;i;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (TYPE_SIGNED(time_t)) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /*<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ** Ignore the end (easy).<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sp-&gt;timecnt = i;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /*<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ** Ignore the beginning (harder).<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; register int&nbsp;&nbsp;&nbsp; j;<br>
<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; for (j = 0; j &#43; i &lt; sp-&gt;timecnt; &#43;&#43;j) {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sp-&gt;ats[j] = sp-&gt;ats[j &#43; i];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sp-&gt;types[j] = sp-&gt;types[j &#43; i];<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sp-&gt;timecnt = j;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; break;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
#endif<br>
<br>
I appreciate any assistance with this.<br>
<br>
Doug<br>
<br>
</div>
</body>
</html>