- long absoff;
- if (t->tm_gmtoff >= 0) {
- absoff = t->tm_gmtoff;
- pt = _add("+", pt, ptlim);
- } else {
- absoff = -t->tm_gmtoff;
- pt = _add("-", pt, ptlim);
- }
- pt = _conv(absoff / 3600, "%02d",
- pt, ptlim);
- pt = _conv((absoff % 3600) / 60, "%02d",
- pt, ptlim);
- };
+ int diff;
+ char const * sign;
+
+ if (t->tm_isdst < 0)
+ continue;
+#if defined(TM_GMTOFF) && !__DARWIN_UNIX03
+ diff = t->TM_GMTOFF;
+#else /* !defined TM_GMTOFF || __DARWIN_UNIX03 */
+ /*
+ ** C99 says that the UTC offset must
+ ** be computed by looking only at
+ ** tm_isdst. This requirement is
+ ** incorrect, since it means the code
+ ** must rely on magic (in this case
+ ** altzone and timezone), and the
+ ** magic might not have the correct
+ ** offset. Doing things correctly is
+ ** tricky and requires disobeying C99;
+ ** see GNU C strftime for details.
+ ** For now, punt and conform to the
+ ** standard, even though it's incorrect.
+ **
+ ** C99 says that %z must be replaced by the
+ ** empty string if the time zone is not
+ ** determinable, so output nothing if the
+ ** appropriate variables are not available.
+ */
+ if (t->tm_isdst == 0)
+#ifdef USG_COMPAT
+ diff = -_st_get_timezone();
+#else /* !defined USG_COMPAT */
+ continue;
+#endif /* !defined USG_COMPAT */
+ else
+#ifdef ALTZONE
+ diff = -altzone;
+#else /* !defined ALTZONE */
+ continue;
+#endif /* !defined ALTZONE */
+#endif /* !defined TM_GMTOFF || __DARWIN_UNIX03 */
+ if (diff < 0) {
+ sign = "-";
+ diff = -diff;
+ } else sign = "+";
+ pt = _add(sign, pt, ptlim);
+ diff /= SECSPERMIN;
+ diff = (diff / MINSPERHOUR) * 100 +
+ (diff % MINSPERHOUR);
+ pt = _conv(diff,
+ fmt_padding[PAD_FMT_YEAR][PadIndex], pt, ptlim, loc);
+ }