Exemple #1
0
/*========================================================================
 * Function name        : gmt_convert_local
 * Description            : 将格林尼治时间转换为本地时间
 * Return type                : bool 
 * Argument         : 
 *                  : const char* gmt 格林尼治时间 20091105082121
 *                  : char* local        20091105/162121
 ========================================================================*/
bool gmt_convert_local(const char* gmt, char* local)
{
	if ( strlen(gmt) != 14 )
		return false;
	//格林尼治时间转换为本地时间
	char year[5];
	char month[3];
	char day[3];
	char hour[3];
	char minute[3];
	char second[3];

	sscanf(gmt, "%4s%2s%2s%2s%2s%2s", year, month, day, hour, minute, second);

	tm utc_time;
	tm local_time;

	utc_time.tm_year = atoi(year);
	utc_time.tm_mon = atoi(month);
	utc_time.tm_mday = atoi(day);
	utc_time.tm_hour = atoi(hour);
	utc_time.tm_min = atoi(minute);
	utc_time.tm_sec = atoi(second);

	time64_t time_second = mktime64(&utc_time, 0);//utc时间, 0 时区

	localtime64(&local_time, time_second,8);

	return true;
}
Exemple #2
0
static struct tm *_localtime64_r (const time_t * now, double *_t, struct tm *p)
{
    double tl;
    time_t t;
    struct tm tm, tm_localtime, tm_gmtime;
    _gmtime64_r (now, _t, &tm);
    if (tm.tm_year > (2037 - 1900))
        tm.tm_year = 2037 - 1900;
    t = mktime64 (&tm);
    localtime_r (&t, &tm_localtime);
    gmtime_r (&t, &tm_gmtime);
    tl = *_t;
    tl += (mktime64 (&tm_localtime) - mktime64 (&tm_gmtime));
    _gmtime64_r (now, &tl, p);
    p->tm_isdst = tm_localtime.tm_isdst;
    return p;
}
Exemple #3
0
int iso_date(char * p, int flag)
{
	int year, month, day, hour, minute, second, tz;
	int crtime;

	year = p[0];
	month = p[1];
	day = p[2];
	hour = p[3];
	minute = p[4];
	second = p[5];
	if (flag == 0) tz = p[6]; /* High sierra has no time zone */
	else tz = 0;
	
	if (year < 0) {
		crtime = 0;
	} else {
		crtime = mktime64(year+1900, month, day, hour, minute, second);

		/* sign extend */
		if (tz & 0x80)
			tz |= (-1 << 8);
		
		/* 
		 * The timezone offset is unreliable on some disks,
		 * so we make a sanity check.  In no case is it ever
		 * more than 13 hours from GMT, which is 52*15min.
		 * The time is always stored in localtime with the
		 * timezone offset being what get added to GMT to
		 * get to localtime.  Thus we need to subtract the offset
		 * to get to true GMT, which is what we store the time
		 * as internally.  On the local system, the user may set
		 * their timezone any way they wish, of course, so GMT
		 * gets converted back to localtime on the receiving
		 * system.
		 *
		 * NOTE: mkisofs in versions prior to mkisofs-1.10 had
		 * the sign wrong on the timezone offset.  This has now
		 * been corrected there too, but if you are getting screwy
		 * results this may be the explanation.  If enough people
		 * complain, a user configuration option could be added
		 * to add the timezone offset in with the wrong sign
		 * for 'compatibility' with older discs, but I cannot see how
		 * it will matter that much.
		 *
		 * Thanks to [email protected] (Volker Kuhlmann)
		 * for pointing out the sign error.
		 */
		if (-52 <= tz && tz <= 52)
			crtime -= tz * 15 * 60;
	}
	return crtime;
}		
static int line2DeductionNoAdjEvent(char *line,EVENT_INTERFACE *pEvent)
{
	struct tm tm_A;
	time64_t time64A;
	long double ratio;
	
	memset(&tm_A,'\0',sizeof(tm_A));
	tm_A.tm_year=getNum(line,4)-1900;
	tm_A.tm_mon=getNum(line+4,2)-1;
	tm_A.tm_mday=global_debt.deductionPerMonDay;
	time64A=mktime64(&tm_A);
	sscanf(strstr(line,",")+1,"%Lf",&ratio);
	event_class_deduction_no_adjust_init(pEvent,time64A,global_debt.deductionPerMonAmount,ratio);
	return 0;
}
Exemple #5
0
static int line2IntrEvent(char *line,EVENT_INTERFACE *pEvent)
{
	struct tm tm_A;
	time64_t time64A;
	long double intr;
	
	memset(&tm_A,'\0',sizeof(tm_A));
	tm_A.tm_year=getNum(line,4)-1900;
	tm_A.tm_mon=getNum(line+4,2)-1;
	tm_A.tm_mday=getNum(line+6,2);
	time64A=mktime64(&tm_A);
	sscanf(strstr(line,",")+1,"%Lf",&intr);
	event_class_adjust_intr_init(pEvent,time64A,intr);
	return 0;
}
Exemple #6
0
/**
 * x509_decode_time - Decode an X.509 time ASN.1 object
 * @_t: The time to fill in
 * @hdrlen: The length of the object header
 * @tag: The object tag
 * @value: The object value
 * @vlen: The size of the object value
 *
 * Decode an ASN.1 universal time or generalised time field into a struct the
 * kernel can handle and check it for validity.  The time is decoded thus:
 *
 *	[RFC5280 §4.1.2.5]
 *	CAs conforming to this profile MUST always encode certificate validity
 *	dates through the year 2049 as UTCTime; certificate validity dates in
 *	2050 or later MUST be encoded as GeneralizedTime.  Conforming
 *	applications MUST be able to process validity dates that are encoded in
 *	either UTCTime or GeneralizedTime.
 */
int x509_decode_time(time64_t *_t,  size_t hdrlen,
		     unsigned char tag,
		     const unsigned char *value, size_t vlen)
{
	static const unsigned char month_lengths[] = { 31, 29, 31, 30, 31, 30,
						       31, 31, 30, 31, 30, 31 };
	const unsigned char *p = value;
	unsigned year, mon, day, hour, min, sec, mon_len;

#define dec2bin(X) ({ unsigned char x = (X) - '0'; if (x > 9) goto invalid_time; x; })
#define DD2bin(P) ({ unsigned x = dec2bin(P[0]) * 10 + dec2bin(P[1]); P += 2; x; })

	if (tag == ASN1_UNITIM) {
		/* UTCTime: YYMMDDHHMMSSZ */
		if (vlen != 13)
			goto unsupported_time;
		year = DD2bin(p);
		if (year >= 50)
			year += 1900;
		else
			year += 2000;
	} else if (tag == ASN1_GENTIM) {
		/* GenTime: YYYYMMDDHHMMSSZ */
		if (vlen != 15)
			goto unsupported_time;
		year = DD2bin(p) * 100 + DD2bin(p);
		if (year >= 1950 && year <= 2049)
			goto invalid_time;
	} else {
		goto unsupported_time;
	}

	mon  = DD2bin(p);
	day = DD2bin(p);
	hour = DD2bin(p);
	min  = DD2bin(p);
	sec  = DD2bin(p);

	if (*p != 'Z')
		goto unsupported_time;

	mon_len = month_lengths[mon];
	if (mon == 2) {
		if (year % 4 == 0) {
			mon_len = 29;
			if (year % 100 == 0) {
				year /= 100;
				if (year % 4 != 0)
					mon_len = 28;
			}
		}
	}

	if (year < 1970 ||
	    mon < 1 || mon > 12 ||
	    day < 1 || day > mon_len ||
	    hour < 0 || hour > 23 ||
	    min < 0 || min > 59 ||
	    sec < 0 || sec > 59)
		goto invalid_time;
	
	*_t = mktime64(year, mon, day, hour, min, sec);
	return 0;

unsupported_time:
	pr_debug("Got unsupported time [tag %02x]: '%*phN'\n",
		 tag, (int)vlen, value);
	return -EBADMSG;
invalid_time:
	pr_debug("Got invalid time [tag %02x]: '%*phN'\n",
		 tag, (int)vlen, value);
	return -EBADMSG;
}
Exemple #7
0
/* Because I think mktime() is a crappy name */
Time64_T timelocal64(const struct TM *date) {
    return mktime64(date);
}
Exemple #8
0
/*
 * rtc_tm_to_time64 - Converts rtc_time to time64_t.
 * Convert Gregorian date to seconds since 01-01-1970 00:00:00.
 */
time64_t rtc_tm_to_time64(struct rtc_time *tm)
{
	return mktime64(((unsigned)tm->tm_year + 1900), tm->tm_mon + 1,
			tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
}
time_t EppUtil::getDate( const char * s, bool dateOnly )
{
	time_t cal = 0;
	struct tm tmp;
#if       defined(win32)      /* { */
	const char * fmt = dateOnly ? "%4d-%2d-%2d" : "%4d-%2d-%2dT%2d:%2d:%2d.0Z";
#else  /* defined(win32) */   /* } { */
#if       defined(hpux)       /* { */
	const char * fmt = dateOnly ? "%Y-%m-%d" : "%Y-%m-%d %H:%M:%S.0Z";
#else  /* defined(hpux) */    /* } { */
	const char * fmt = dateOnly ? "%Y-%m-%d" : "%Y-%m-%dT%H:%M:%S.0Z";
#endif /* defined(hpux) */    /* } */
#endif /* defined(win32) */   /* } */

	if( (s != null) && (*s != '\0') )
	{
		char * buf = ::strdup(s);
		if( buf != null )
		{
#if       defined(hpux)       /* { */
			char * cp = buf;
			while( *cp != '\0' )
			{
				if( *cp == 'T' )
				{
					*cp = ' ';
					break;
				}
				cp++;
			}
#endif /* defined(hpux) */    /* } */

			(void) memset((char *) &tmp, '\0', sizeof(tmp));

#if       defined(win32)      /* { */

			char * c = "";
			if( dateOnly )
			{
				if( sscanf(buf, fmt, &tmp.tm_year, &tmp.tm_mon,
					&tmp.tm_mday) != 3 )
				{
					c = null;
				}
			}
			else
			{
				if( sscanf(buf, fmt, &tmp.tm_year, &tmp.tm_mon,
					&tmp.tm_mday, &tmp.tm_hour, &tmp.tm_min,
					&tmp.tm_sec) != 6 )
				{
					c = null;
				}
			}
			if( c != null )
			{
				tmp.tm_year -= 1900;
				tmp.tm_mon--;
			}

#else  /* defined(win32) */   /* } { */
			if ( dateOnly )
			{
				strptime(buf, fmt, &tmp);
			}
			else
			{
				// Parse the GMT offset if present.
				struct tm junk; // Values inside are not used. Defined this instead of defining may ints.
				char tStr[32];

				(void) memset(tStr, '\0', sizeof(tStr));
				(void) memset((char *) &junk, '\0', sizeof(junk));

				// Quick check on whats inside....
				if ( sscanf(buf, "%u-%u-%uT%u:%u:%s",
					&junk.tm_year, &junk.tm_mon, &junk.tm_mday, &junk.tm_hour, &junk.tm_min,
					tStr) )
				{
					const char * fmt2 = "%Y-%m-%dT%H:%M:%S%z";

					char* subPtr;
					if ( subPtr = strchr(tStr, 'Z') )
					{
						strptime(buf, fmt, &tmp);
					}
					else if ( NULL == strchr(tStr, ':') ) // timezone offset is something like +/-hhmm
					{
						strptime(buf, fmt2, &tmp);
					}
					else // timezone offset is something like +/-hh:mm
					{
						std::string input(buf);
						std::string subString(tStr);

						for ( int index = input.find(subString);
							index <input.length();
							index++ )
						{
							if ( input[index]==':' )
							{
								input.erase(index, 1);
							}
						}
						strptime(input.c_str(), fmt2, &tmp);
					}
				}
			}
#endif /* defined(win32) */   /* } */

#if	   EPP_SUPPORT_UNSIGNED_TIME_T		/* { */

			long long t = mktime64(&tmp) - timezone + daylight * 3600;
			cal = t & 0xFFFFFFFF;

#else	/* EPP_SUPPORT_UNSIGNED_TIME_T	*/	/* } */

			//			if( strptime(buf, fmt, &tmp) == null )
			//			if( (c == null) || (*c == '\0') )
			{
				cal = mktime(&tmp) - timezone + daylight * 3600;
			}

#endif	/* EPP_SUPPORT_UNSIGNED_TIME_T	*/	/* } */

			(void) ::free(buf);
		}
	}

	return cal;
}
Exemple #10
0
static char *
_fmt(const char *format, const struct tm *t, char *pt,
        const char *ptlim, int *warnp)
{
    for ( ; *format; ++format) {
        if (*format == '%') {
            int modifier = 0;
label:
            switch (*++format) {
            case '\0':
                --format;
                break;
            case 'A':
                pt = _add((t->tm_wday < 0 ||
                    t->tm_wday >= DAYSPERWEEK) ?
                    "?" : Locale->weekday[t->tm_wday],
                    pt, ptlim, modifier);
                continue;
            case 'a':
                pt = _add((t->tm_wday < 0 ||
                    t->tm_wday >= DAYSPERWEEK) ?
                    "?" : Locale->wday[t->tm_wday],
                    pt, ptlim, modifier);
                continue;
            case 'B':
                pt = _add((t->tm_mon < 0 ||
                                t->tm_mon >= MONSPERYEAR) ?
                                "?" : Locale->month[t->tm_mon],
                                pt, ptlim, modifier);
                continue;
            case 'b':
            case 'h':
                pt = _add((t->tm_mon < 0 ||
                    t->tm_mon >= MONSPERYEAR) ?
                    "?" : Locale->mon[t->tm_mon],
                    pt, ptlim, modifier);
                continue;
            case 'C':
                /*
                ** %C used to do a...
                **  _fmt("%a %b %e %X %Y", t);
                ** ...whereas now POSIX 1003.2 calls for
                ** something completely different.
                ** (ado, 1993-05-24)
                */
                pt = _yconv(t->tm_year, TM_YEAR_BASE,
                    true, false, pt, ptlim, modifier);
                continue;
            case 'c':
                {
                int warn2 = IN_SOME;

                pt = _fmt(Locale->c_fmt, t, pt, ptlim, &warn2);
                if (warn2 == IN_ALL)
                    warn2 = IN_THIS;
                if (warn2 > *warnp)
                    *warnp = warn2;
                }
                continue;
            case 'D':
                                pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp);
                continue;
            case 'd':
                                pt = _conv(t->tm_mday, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
                continue;
            case 'E':
            case 'O':
                /*
                ** C99 locale modifiers.
                ** The sequences
                **  %Ec %EC %Ex %EX %Ey %EY
                **  %Od %oe %OH %OI %Om %OM
                **  %OS %Ou %OU %OV %Ow %OW %Oy
                ** are supposed to provide alternate
                ** representations.
                */
                goto label;
            case '_':
            case '-':
            case '0':
            case '^':
            case '#':
                modifier = *format;
                goto label;
            case 'e':
                pt = _conv(t->tm_mday, getformat(modifier, "%2d", "%2d", "%d", "%02d"), pt, ptlim);
                continue;
            case 'F':
                pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp);
                continue;
            case 'H':
                pt = _conv(t->tm_hour, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
                continue;
            case 'I':
                pt = _conv((t->tm_hour % 12) ?
                    (t->tm_hour % 12) : 12,
                    getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
                continue;
            case 'j':
                pt = _conv(t->tm_yday + 1, getformat(modifier, "%03d", "%3d", "%d", "%03d"), pt, ptlim);
                continue;
            case 'k':
                /*
                ** This used to be...
                **  _conv(t->tm_hour % 12 ?
                **      t->tm_hour % 12 : 12, 2, ' ');
                ** ...and has been changed to the below to
                ** match SunOS 4.1.1 and Arnold Robbins'
                ** strftime version 3.0. That is, "%k" and
                ** "%l" have been swapped.
                ** (ado, 1993-05-24)
                */
                pt = _conv(t->tm_hour, getformat(modifier, "%2d", "%2d", "%d", "%02d"), pt, ptlim);
                continue;
#ifdef KITCHEN_SINK
            case 'K':
                /*
                ** After all this time, still unclaimed!
                */
                pt = _add("kitchen sink", pt, ptlim);
                continue;
#endif /* defined KITCHEN_SINK */
            case 'l':
                /*
                ** This used to be...
                **  _conv(t->tm_hour, 2, ' ');
                ** ...and has been changed to the below to
                ** match SunOS 4.1.1 and Arnold Robbin's
                ** strftime version 3.0. That is, "%k" and
                ** "%l" have been swapped.
                ** (ado, 1993-05-24)
                */
                pt = _conv((t->tm_hour % 12) ?
                    (t->tm_hour % 12) : 12,
                    getformat(modifier, "%2d", "%2d", "%d", "%02d"), pt, ptlim);
                continue;
            case 'M':
                pt = _conv(t->tm_min, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
                continue;
            case 'm':
                pt = _conv(t->tm_mon + 1, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
                continue;
            case 'n':
                pt = _add("\n", pt, ptlim, modifier);
                continue;
            case 'P':
            case 'p':
                pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?
                    Locale->pm :
                    Locale->am,
                    pt, ptlim, (*format == 'P') ? FORCE_LOWER_CASE : modifier);
                continue;
            case 'R':
                pt = _fmt("%H:%M", t, pt, ptlim, warnp);
                continue;
            case 'r':
                pt = _fmt("%I:%M:%S %p", t, pt, ptlim, warnp);
                continue;
            case 'S':
                pt = _conv(t->tm_sec, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
                continue;
            case 's':
                {
                    struct tm   tm;
                    char        buf[INT_STRLEN_MAXIMUM(
                                time64_t) + 1];
                    time64_t    mkt;

                    tm = *t;
                    mkt = mktime64(&tm);
                    if (TYPE_SIGNED(time64_t))
                        snprintf(buf, sizeof(buf), "%"PRIdMAX,
                                 (intmax_t) mkt);
                    else    snprintf(buf, sizeof(buf), "%"PRIuMAX,
                                     (uintmax_t) mkt);
                    pt = _add(buf, pt, ptlim, modifier);
                }
                continue;
            case 'T':
                pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp);
                continue;
            case 't':
                pt = _add("\t", pt, ptlim, modifier);
                continue;
            case 'U':
                pt = _conv((t->tm_yday + DAYSPERWEEK -
                    t->tm_wday) / DAYSPERWEEK,
                    getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
                continue;
            case 'u':
                /*
                ** From Arnold Robbins' strftime version 3.0:
                ** "ISO 8601: Weekday as a decimal number
                ** [1 (Monday) - 7]"
                ** (ado, 1993-05-24)
                */
                pt = _conv((t->tm_wday == 0) ?
                    DAYSPERWEEK : t->tm_wday,
                    "%d", pt, ptlim);
                continue;
            case 'V':   /* ISO 8601 week number */
            case 'G':   /* ISO 8601 year (four digits) */
            case 'g':   /* ISO 8601 year (two digits) */
/*
** From Arnold Robbins' strftime version 3.0: "the week number of the
** year (the first Monday as the first day of week 1) as a decimal number
** (01-53)."
** (ado, 1993-05-24)
**
** From <http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html> by Markus Kuhn:
** "Week 01 of a year is per definition the first week which has the
** Thursday in this year, which is equivalent to the week which contains
** the fourth day of January. In other words, the first week of a new year
** is the week which has the majority of its days in the new year. Week 01
** might also contain days from the previous year and the week before week
** 01 of a year is the last week (52 or 53) of the previous year even if
** it contains days from the new year. A week starts with Monday (day 1)
** and ends with Sunday (day 7). For example, the first week of the year
** 1997 lasts from 1996-12-30 to 1997-01-05..."
** (ado, 1996-01-02)
*/
                {
                    int year;
                    int base;
                    int yday;
                    int wday;
                    int w;

                    year = t->tm_year;
                    base = TM_YEAR_BASE;
                    yday = t->tm_yday;
                    wday = t->tm_wday;
                    for ( ; ; ) {
                        int len;
                        int bot;
                        int top;

                        len = isleap_sum(year, base) ?
                            DAYSPERLYEAR :
                            DAYSPERNYEAR;
                        /*
                        ** What yday (-3 ... 3) does
                        ** the ISO year begin on?
                        */
                        bot = ((yday + 11 - wday) %
                            DAYSPERWEEK) - 3;
                        /*
                        ** What yday does the NEXT
                        ** ISO year begin on?
                        */
                        top = bot -
                            (len % DAYSPERWEEK);
                        if (top < -3)
                            top += DAYSPERWEEK;
                        top += len;
                        if (yday >= top) {
                            ++base;
                            w = 1;
                            break;
                        }
                        if (yday >= bot) {
                            w = 1 + ((yday - bot) /
                                DAYSPERWEEK);
                            break;
                        }
                        --base;
                        yday += isleap_sum(year, base) ?
                            DAYSPERLYEAR :
                            DAYSPERNYEAR;
                    }
#ifdef XPG4_1994_04_09
                    if ((w == 52 &&
                        t->tm_mon == TM_JANUARY) ||
                        (w == 1 &&
                        t->tm_mon == TM_DECEMBER))
                            w = 53;
#endif /* defined XPG4_1994_04_09 */
                    if (*format == 'V')
                        pt = _conv(w, getformat(modifier, "%02d", "%2d", "%d", "%02d"),
                               pt, ptlim);
                    else if (*format == 'g') {
                        *warnp = IN_ALL;
                        pt = _yconv(year, base,
                            false, true,
                            pt, ptlim, modifier);
                    } else  pt = _yconv(year, base,
                            true, true,
                            pt, ptlim, modifier);
                }
                continue;
            case 'v':
                /*
                ** From Arnold Robbins' strftime version 3.0:
                ** "date as dd-bbb-YYYY"
                ** (ado, 1993-05-24)
                */
                pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp);
                continue;
            case 'W':
                pt = _conv((t->tm_yday + DAYSPERWEEK -
                    (t->tm_wday ?
                    (t->tm_wday - 1) :
                    (DAYSPERWEEK - 1))) / DAYSPERWEEK,
                    getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
                continue;
            case 'w':
                pt = _conv(t->tm_wday, "%d", pt, ptlim);
                continue;
            case 'X':
                pt = _fmt(Locale->X_fmt, t, pt, ptlim, warnp);
                continue;
            case 'x':
                {
                int warn2 = IN_SOME;

                pt = _fmt(Locale->x_fmt, t, pt, ptlim, &warn2);
                if (warn2 == IN_ALL)
                    warn2 = IN_THIS;
                if (warn2 > *warnp)
                    *warnp = warn2;
                }
                continue;
            case 'y':
                *warnp = IN_ALL;
                pt = _yconv(t->tm_year, TM_YEAR_BASE,
                    false, true,
                    pt, ptlim, modifier);
                continue;
            case 'Y':
                pt = _yconv(t->tm_year, TM_YEAR_BASE,
                    true, true,
                    pt, ptlim, modifier);
                continue;
            case 'Z':
#ifdef TM_ZONE
                // BEGIN: Android-changed.
                {
                    const char* zone = t->TM_ZONE;
                    if (!zone || !*zone) {
                        // "The value of tm_isdst shall be positive if Daylight Savings Time is
                        // in effect, 0 if Daylight Savings Time is not in effect, and negative
                        // if the information is not available."
                        if (t->tm_isdst == 0) zone = tzname[0];
                        else if (t->tm_isdst > 0) zone = tzname[1];

                        // "Replaced by the timezone name or abbreviation, or by no bytes if no
                        // timezone information exists."
                        if (!zone || !*zone) zone = "";
                    }
                    pt = _add(zone, pt, ptlim, modifier);
                }
                // END: Android-changed.
#else
                if (t->tm_isdst >= 0)
                    pt = _add(tzname[t->tm_isdst != 0],
                        pt, ptlim);
#endif
                /*
                ** C99 says that %Z must be replaced by the
                ** empty string if the time zone is not
                ** determinable.
                */
                continue;
            case 'z':
                {
                long     diff;
                char const *    sign;

                if (t->tm_isdst < 0)
                    continue;
#ifdef TM_GMTOFF
                diff = t->TM_GMTOFF;
#else /* !defined TM_GMTOFF */
                /*
                ** C99 says that the UT 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 = -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 */
                if (diff < 0) {
                    sign = "-";
                    diff = -diff;
                } else  sign = "+";
                pt = _add(sign, pt, ptlim, modifier);
                diff /= SECSPERMIN;
                diff = (diff / MINSPERHOUR) * 100 +
                    (diff % MINSPERHOUR);
                pt = _conv(diff, getformat(modifier, "%04d", "%4d", "%d", "%04d"), pt, ptlim);
                }
                continue;
            case '+':
                pt = _fmt(Locale->date_fmt, t, pt, ptlim,
                    warnp);
                continue;
            case '%':
            /*
            ** X311J/88-090 (4.12.3.5): if conversion char is
            ** undefined, behavior is undefined. Print out the
            ** character itself as printf(3) also does.
            */
            default:
                break;
            }
        }