+- for (i = 0; i < sp->typecnt; ++i) {
+- const struct ttinfo * const ttisp = &sp->ttis[i];
++ /*
++ * PR-3765457: The original settzname went sequentially through the ttis
++ * array, rather than correctly indexing via the types array, to get
++ * the real order of the timezone changes. In addition, as a speed up,
++ * we start at the end of the changes, and work back, so that most of
++ * the time, we don't have to look through the entire array.
++ */
++ if (sp->timecnt == 0 && sp->typecnt == 1) {
++ /*
++ * Unfortunately, there is an edge case when typecnt == 1 and
++ * timecnt == 0, which would cause the loop to never run. So
++ * in that case, we fudge things up so that it is as if
++ * timecnt == 1.
++ */
++ i = 0;
++ types = (unsigned char *)""; /* we use the null as index */
++ } else {
++ /* the usual case */
++ i = sp->timecnt - 1;
++ types = sp->types;
++ }
++ need = NEED_ALL;
++ for (; i >= 0 && need; --i) {
++ const struct ttinfo * const ttisp = &sp->ttis[types[i]];
+
+- tzname[ttisp->tt_isdst] =
+- &sp->chars[ttisp->tt_abbrind];
+ #ifdef USG_COMPAT
+- if (ttisp->tt_isdst)
++ if ((need & NEED_DAYLIGHT) && ttisp->tt_isdst) {
++ need &= ~NEED_DAYLIGHT;