예제 #1
0
파일: time.c 프로젝트: yezhejack/QAMining
size_t
gstrftime(char *s, size_t bsz, const char *fmt, double l_clock)
{
    struct tm tm;
    double usec;

    ggmtime(&tm, l_clock);

    usec = l_clock - (double)floor(l_clock);

    return xstrftime(s, bsz, fmt, &tm, usec, l_clock);
}
예제 #2
0
파일: time.c 프로젝트: n054/gnuplot-android
size_t
gstrftime(char *s, size_t bsz, const char *fmt, double l_clock)
{
    struct tm tm;

    ggmtime(&tm, l_clock);
#if 0
    if ((tm.tm_zone = (char *) malloc(strlen(xtm->tm_zone) + 1)))
        strcpy(tm.tm_zone, xtm->tm_zone);
    /* printf("zone: %s - %s\n",tm.tm_zone,xtm->tm_zone); */
#endif

    return xstrftime(s, bsz, fmt, &tm);
}
예제 #3
0
파일: time.c 프로젝트: n054/gnuplot-android
int
main(int argc, char *argv[])
{
    char output[80];

    if (argc < 2) {
        fputs("usage : test 'format' ['time']\n", stderr);
        exit(EXIT_FAILURE);
    }
    if (argc == 2) {
        struct timeb now;
        struct tm *tm;
        ftime(&now);
        tm = gmtime(&now.time);
        xstrftime(output, 80, argv[1], tm);
        puts(output);
    } else {
        struct tm tm;
        gstrptime(argv[2], argv[1], &tm);
        puts(asctime(&tm));
    }
    exit(EXIT_SUCCESS);
}
예제 #4
0
static void print_status_info(const StatusInfo *i) {
        char a[FORMAT_TIMESTAMP_MAX];
        struct tm tm;
        time_t sec;
        bool have_time = false;
        const char *old_tz = NULL, *tz;
        int r;

        assert(i);

        /* Save the old $TZ */
        tz = getenv("TZ");
        if (tz)
                old_tz = strdupa(tz);

        /* Set the new $TZ */
        if (setenv("TZ", isempty(i->timezone) ? "UTC" : i->timezone, true) < 0)
                log_warning_errno(errno, "Failed to set TZ environment variable, ignoring: %m");
        else
                tzset();

        if (i->time != 0) {
                sec = (time_t) (i->time / USEC_PER_SEC);
                have_time = true;
        } else if (IN_SET(arg_transport, BUS_TRANSPORT_LOCAL, BUS_TRANSPORT_MACHINE)) {
                sec = time(NULL);
                have_time = true;
        } else
                log_warning("Could not get time from timedated and not operating locally, ignoring.");

        if (have_time) {
                xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm));
                printf("      Local time: %.*s\n", (int) sizeof(a), a);

                xstrftime(a, "%a %Y-%m-%d %H:%M:%S UTC", gmtime_r(&sec, &tm));
                printf("  Universal time: %.*s\n", (int) sizeof(a), a);
        } else {
                printf("      Local time: %s\n", "n/a");
                printf("  Universal time: %s\n", "n/a");
        }

        if (i->rtc_time > 0) {
                time_t rtc_sec;

                rtc_sec = (time_t) (i->rtc_time / USEC_PER_SEC);
                xstrftime(a, "%a %Y-%m-%d %H:%M:%S", gmtime_r(&rtc_sec, &tm));
                printf("        RTC time: %.*s\n", (int) sizeof(a), a);
        } else
                printf("        RTC time: %s\n", "n/a");

        if (have_time)
                xstrftime(a, "%Z, %z", localtime_r(&sec, &tm));

        /* Restore the $TZ */
        if (old_tz)
                r = setenv("TZ", old_tz, true);
        else
                r = unsetenv("TZ");
        if (r < 0)
                log_warning_errno(errno, "Failed to set TZ environment variable, ignoring: %m");
        else
                tzset();

        printf("       Time zone: %s (%.*s)\n"
               " Network time on: %s\n"
               "NTP synchronized: %s\n"
               " RTC in local TZ: %s\n",
               strna(i->timezone), (int) sizeof(a), have_time ? a : "n/a",
               i->ntp_capable ? yes_no(i->ntp_enabled) : "n/a",
               yes_no(i->ntp_synced),
               yes_no(i->rtc_local));

        if (i->rtc_local)
                printf("\n%s"
                       "Warning: The system is configured to read the RTC time in the local time zone.\n"
                       "         This mode can not be fully supported. It will create various problems\n"
                       "         with time zone changes and daylight saving time adjustments. The RTC\n"
                       "         time is never updated, it relies on external facilities to maintain it.\n"
                       "         If at all possible, use RTC in UTC by calling\n"
                       "         'timedatectl set-local-rtc 0'.%s\n", ansi_highlight(), ansi_normal());
}
예제 #5
0
static ssize_t
_popul_ehdr(struct archive_string *tgt, size_t tsz, warc_essential_hdr_t hdr)
{
	static const char _ver[] = "WARC/1.0\r\n";
	static const char * const _typ[LAST_WT] = {
		NULL, "warcinfo", "metadata", "resource", NULL
	};
	char std_uuid[48U];

	if (hdr.type == WT_NONE || hdr.type > WT_RSRC) {
		/* brilliant, how exactly did we get here? */
		return -1;
	}

	archive_strcpy(tgt, _ver);

	archive_string_sprintf(tgt, "WARC-Type: %s\r\n", _typ[hdr.type]);

	if (hdr.tgturi != NULL) {
		/* check if there's a xyz:// */
		static const char _uri[] = "";
		static const char _fil[] = "file://";
		const char *u;
		char *chk = strchr(hdr.tgturi, ':');

		if (chk != NULL && chk[1U] == '/' && chk[2U] == '/') {
			/* yep, it's definitely a URI */
			u = _uri;
		} else {
			/* hm, best to prepend file:// then */
			u = _fil;
		}
		archive_string_sprintf(tgt,
			"WARC-Target-URI: %s%s\r\n", u, hdr.tgturi);
	}

	/* record time is usually when the http is sent off,
	 * just treat the archive writing as such for a moment */
	xstrftime(tgt, "WARC-Date: %Y-%m-%dT%H:%M:%SZ\r\n", hdr.rtime);

	/* while we're at it, record the mtime */
	xstrftime(tgt, "Last-Modified: %Y-%m-%dT%H:%M:%SZ\r\n", hdr.mtime);

	if (hdr.recid == NULL) {
		/* generate one, grrrr */
		warc_uuid_t u;

		_gen_uuid(&u);
		/* Unfortunately, archive_string_sprintf does not
		 * handle the minimum number following '%'.
		 * So we have to use snprintf function here instead
		 * of archive_string_snprintf function. */
#if defined(_WIN32) && !defined(__CYGWIN__) && !( defined(_MSC_VER) && _MSC_VER >= 1900)
#define snprintf _snprintf
#endif
		snprintf(
			std_uuid, sizeof(std_uuid),
			"<urn:uuid:%08x-%04x-%04x-%04x-%04x%08x>",
			u.u[0U],
			u.u[1U] >> 16U, u.u[1U] & 0xffffU,
			u.u[2U] >> 16U, u.u[2U] & 0xffffU,
			u.u[3U]);
		hdr.recid = std_uuid;
	}
예제 #6
0
파일: time.c 프로젝트: yezhejack/QAMining
static size_t
xstrftime(
    char *str,			/* output buffer */
    size_t bsz,			/* space available */
    const char *fmt,
    struct tm *tm,
    double usec,
    double fulltime)
{
    size_t l = 0;			/* chars written so far */
    int incr = 0;			/* chars just written */
    char *s = str;
    TBOOLEAN sign_printed = FALSE;

    memset(str, '\0', bsz);

    while (*fmt != '\0') {
        if (*fmt != '%') {
            if (l >= bsz-1)
                return 0;
            *s++ = *fmt++;
            l++;
        } else {
            /* set up format modifiers */
            int w = 0;
            int z = 0;
            int p = 0;

            if (*++fmt == '0') {
                z = 1;
                ++fmt;
            }
            while (*fmt >= '0' && *fmt <= '9') {
                w = w * 10 + (*fmt - '0');
                ++fmt;
            }
            if (*fmt == '.') {
                ++fmt;
                while (*fmt >= '0' && *fmt <= '9') {
                    p = p * 10 + (*fmt - '0');
                    ++fmt;
                }
                if (p > 6) p = 6;
            }

            switch (*fmt++) {

                /* some shorthands : check that there is space in the
                 * output string. */
#define CHECK_SPACE(n) do {				\
		    if ((l+(n)) > bsz) return 0;	\
		} while (0)

                /* copy a fixed string, checking that there's room */
#define COPY_STRING(z) do {			\
		    CHECK_SPACE(strlen(z)) ;	\
		    strcpy(s, z);		\
		} while (0)

                /* format a string, using default spec if none given w
                 * and z are width and zero-flag dw and dz are the
                 * defaults for these In fact, CHECK_SPACE(w) is not a
                 * sufficient test, since sprintf("%2d", 365) outputs
                 * three characters
                 */
#define FORMAT_STRING(dz, dw, x) do {				\
		    if (w==0) {					\
			w=(dw);					\
			if (!z)					\
			    z=(dz);				\
		    }						\
		    incr = snprintf(s, bsz-l-1, z ? "%0*d" : "%*d", w, (x));	\
		    CHECK_SPACE(incr);				\
		} while(0)

            case '%':
                CHECK_SPACE(1);
                *s = '%';
                break;

            case 'a':
                COPY_STRING(abbrev_day_names[tm->tm_wday]);
                break;

            case 'A':
                COPY_STRING(full_day_names[tm->tm_wday]);
                break;

            case 'b':
            case 'h':
                COPY_STRING(abbrev_month_names[tm->tm_mon]);
                break;

            case 'B':
                COPY_STRING(full_month_names[tm->tm_mon]);
                break;

            case 'd':
                FORMAT_STRING(1, 2, tm->tm_mday);	/* %02d */
                break;

            case 'D':
                if (!xstrftime(s, bsz - l, "%m/%d/%y", tm, 0., fulltime))
                    return 0;
                break;

            case 'F':
                if (!xstrftime(s, bsz - l, "%Y-%m-%d", tm, 0., fulltime))
                    return 0;
                break;

            case 'H':
                FORMAT_STRING(1, 2, tm->tm_hour);	/* %02d */
                break;

            case 'I':
                FORMAT_STRING(1, 2, (tm->tm_hour + 11) % 12 + 1); /* %02d */
                break;

            case 'j':
                FORMAT_STRING(1, 3, tm->tm_yday + 1);	/* %03d */
                break;

            /* not in linux strftime man page. Not really needed now */
            case 'k':
                FORMAT_STRING(0, 2, tm->tm_hour);	/* %2d */
                break;

            case 'l':
                FORMAT_STRING(0, 2, (tm->tm_hour + 11) % 12 + 1); /* %2d */
                break;

            case 'm':
                FORMAT_STRING(1, 2, tm->tm_mon + 1);	/* %02d */
                break;

            case 'M':
                FORMAT_STRING(1, 2, tm->tm_min);	/* %02d */
                break;

            case 'p':
                CHECK_SPACE(2);
                strcpy(s, (tm->tm_hour < 12) ? "am" : "pm");
                break;

            case 'r':
                if (!xstrftime(s, bsz - l, "%I:%M:%S %p", tm, 0., fulltime))
                    return 0;
                break;

            case 'R':
                if (!xstrftime(s, bsz - l, "%H:%M", tm, 0., fulltime))
                    return 0;
                break;

            case 's':
                CHECK_SPACE(12); /* large enough for year 9999 */
                sprintf(s, "%.0f", gtimegm(tm));
                break;

            case 'S':
                FORMAT_STRING(1, 2, tm->tm_sec);	/* %02d */

                /* EAM FIXME - need to implement an actual format specifier */
                if (p > 0) {
                    double base = pow(10., (double)p);
                    int msec = floor(0.5 + base * usec);
                    char *f = &s[strlen(s)];
                    CHECK_SPACE(p+1);
                    sprintf(f, ".%0*d", p, msec<(int)base?msec:(int)base-1);
                }
                break;

            case 'T':
                if (!xstrftime(s, bsz - l, "%H:%M:%S", tm, 0., fulltime))
                    return 0;
                break;

            case 't':		/* Time (as opposed to Date) formats */
            {
                int tminute, tsecond;

                switch (*fmt++) {
                case 'H':
                    /* +/- fractional hours (not wrapped at 24h) */
                    if (p > 0) {
                        incr = snprintf(s, bsz-l-1, "%*.*f", w, p, fulltime/3600.);
                        CHECK_SPACE(incr);
                        break;
                    }
                    /* Set flag in case minutes come next */
                    if (fulltime < 0) {
                        CHECK_SPACE(1);	/* the minus sign */
                        sign_printed = TRUE;
                        *s++ = '-';
                        l++;
                    }
                    /* +/- integral hour truncated toward zero */
                    sprintf(s, "%0*d", w, (int)floor(fabs(fulltime/3600.)));
                    break;
                case 'M':
                    /* +/- fractional minutes (not wrapped at 60m) */
                    if (p > 0) {
                        incr = snprintf(s, bsz-l-1, "%*.*f", w, p,
                                        sign_printed ? fabs(fulltime)/60. : fulltime/60.);
                        CHECK_SPACE(incr);
                        break;
                    }
                    /* +/- integral minute truncated toward zero */
                    tminute = floor(60. * (fabs(fulltime/3600.) - floor(fabs(fulltime/3600.))));
                    if (fulltime < 0) {
                        if (!sign_printed) {
                            sign_printed = TRUE;
                            *s++ = '-';
                            l++;
                        }
                    }
                    FORMAT_STRING(1, 2, tminute);	/* %02d */
                    break;
                case 'S':
                    /* +/- fractional seconds */
                    tsecond = floor(60. * (fabs(fulltime/60.) - floor(fabs(fulltime/60.))));
                    if (fulltime < 0) {
                        if (usec > 0)
                            usec = 1.0 - usec;
                        if (!sign_printed) {
                            *s++ = '-';
                            l++;
                        }
                    }
                    FORMAT_STRING(1, 2, tsecond);	/* %02d */
                    if (p > 0) {
                        double base = pow(10., (double)p);
                        int msec = floor(0.5 + base * usec);
                        char *f = &s[strlen(s)];
                        CHECK_SPACE(p+1);
                        sprintf(f, ".%0*d", p, msec<(int)base?msec:(int)base-1);
                    }
                    break;
                default:
                    break;
                }
                break;
            }

            case 'W':		/* mon 1 day of week */
            {
                int week;
                if (tm->tm_yday <= tm->tm_wday) {
                    week = 1;

                    if ((tm->tm_mday - tm->tm_yday) > 4) {
                        week = 52;
                    }
                    if (tm->tm_yday == tm->tm_wday && tm->tm_wday == 0)
                        week = 52;

                } else {

                    /* sun prev week */
                    int bw = tm->tm_yday - tm->tm_wday;

                    if (tm->tm_wday > 0)
                        bw += 7;	/* sun end of week */

                    week = (int) bw / 7;

                    if ((bw % 7) > 2)	/* jan 1 is before friday */
                        week++;
                }
                FORMAT_STRING(1, 2, week);	/* %02d */
                break;
            }

            case 'U':		/* sun 1 day of week */
            {
                int week, bw;

                if (tm->tm_yday <= tm->tm_wday) {
                    week = 1;
                    if ((tm->tm_mday - tm->tm_yday) > 4) {
                        week = 52;
                    }
                } else {
                    /* sat prev week */
                    bw = tm->tm_yday - tm->tm_wday - 1;
                    if (tm->tm_wday >= 0)
                        bw += 7;	/* sat end of week */
                    week = (int) bw / 7;
                    if ((bw % 7) > 1) {	/* jan 1 is before friday */
                        week++;
                    }
                }
                FORMAT_STRING(1, 2, week);	/* %02d */
                break;
            }

            case 'w':		/* day of week, sun=0 */
                FORMAT_STRING(1, 2, tm->tm_wday);	/* %02d */
                break;

            case 'y':
                FORMAT_STRING(1, 2, tm->tm_year % 100);		/* %02d */
                break;

            case 'Y':
                FORMAT_STRING(1, 4, tm->tm_year);	/* %04d */
                break;

            }			/* switch */

            while (*s != '\0') {
                s++;
                l++;
            }
#undef CHECK_SPACE
#undef COPY_STRING
#undef FORMAT_STRING
        } /* switch(fmt letter) */
    } /* if(fmt letter not '%') */
    return (l);
}
예제 #7
0
static void print_status_info(const StatusInfo *i) {
        char a[FORMAT_TIMESTAMP_MAX];
        char b[FORMAT_TIMESTAMP_MAX];
        char s[32];
        struct tm tm;
        time_t sec;
        bool have_time = false;
        _cleanup_free_ char *zc = NULL, *zn = NULL;
        time_t t, tc, tn;
        int dn = 0;
        bool is_dstc = false, is_dstn = false;
        int r;

        assert(i);

        /* Enforce the values of /etc/localtime */
        if (getenv("TZ")) {
                fprintf(stderr, "Warning: Ignoring the TZ variable. Reading the system's time zone setting only.\n\n");
                unsetenv("TZ");
        }

        if (i->time != 0) {
                sec = (time_t) (i->time / USEC_PER_SEC);
                have_time = true;
        } else if (arg_transport == BUS_TRANSPORT_LOCAL) {
                sec = time(NULL);
                have_time = true;
        } else
                fprintf(stderr, "Warning: Could not get time from timedated and not operating locally.\n\n");

        if (have_time) {
                xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm));
                printf("      Local time: %.*s\n", (int) sizeof(a), a);

                xstrftime(a, "%a %Y-%m-%d %H:%M:%S UTC", gmtime_r(&sec, &tm));
                printf("  Universal time: %.*s\n", (int) sizeof(a), a);
        } else {
                printf("      Local time: %s\n", "n/a");
                printf("  Universal time: %s\n", "n/a");
        }

        if (i->rtc_time > 0) {
                time_t rtc_sec;

                rtc_sec = (time_t)(i->rtc_time / USEC_PER_SEC);
                xstrftime(a, "%a %Y-%m-%d %H:%M:%S", gmtime_r(&rtc_sec, &tm));
                printf("        RTC time: %.*s\n", (int) sizeof(a), a);
        } else
                printf("        RTC time: %s\n", "n/a");

        if (have_time)
                xstrftime(a, "%Z, %z", localtime_r(&sec, &tm));

        printf("       Time zone: %s (%.*s)\n"
               "     NTP enabled: %s\n"
               "NTP synchronized: %s\n"
               " RTC in local TZ: %s\n",
               strna(i->timezone), (int) sizeof(a), have_time ? a : "n/a",
               i->ntp_capable ? yes_no(i->ntp_enabled) : "n/a",
               yes_no(i->ntp_synced),
               yes_no(i->rtc_local));

        if (have_time) {
                r = time_get_dst(sec, "/etc/localtime",
                                 &tc, &zc, &is_dstc,
                                 &tn, &dn, &zn, &is_dstn);
                if (r < 0)
                        printf("      DST active: %s\n", "n/a");
                else {
                        printf("      DST active: %s\n", yes_no(is_dstc));

                        t = tc - 1;
                        xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm));

                        xstrftime(b, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tc, &tm));
                        printf(" Last DST change: DST %s at\n"
                               "                  %.*s\n"
                               "                  %.*s\n",
                               is_dstc ? "began" : "ended",
                               (int) sizeof(a), a,
                               (int) sizeof(b), b);

                        t = tn - 1;
                        xstrftime(a, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&t, &tm));
                        xstrftime(b, "%a %Y-%m-%d %H:%M:%S %Z", localtime_r(&tn, &tm));
                        printf(" Next DST change: DST %s (the clock jumps %s) at\n"
                               "                  %.*s\n"
                               "                  %.*s\n",
                               is_dstn ? "begins" : "ends",
                               jump_str(dn, s, sizeof(s)),
                               (int) sizeof(a), a,
                               (int) sizeof(b), b);
                }
        } else
                printf("      DST active: %s\n", yes_no(is_dstc));

        if (i->rtc_local)
                fputs("\n" ANSI_HIGHLIGHT_ON
                      "Warning: The system is configured to read the RTC time in the local time zone. This\n"
                      "         mode can not be fully supported. It will create various problems with time\n"
                      "         zone changes and daylight saving time adjustments. The RTC time is never updated,\n"
                      "         it relies on external facilities to maintain it. If at all possible, use\n"
                      "         RTC in UTC by calling 'timedatectl set-local-rtc 0'" ANSI_HIGHLIGHT_OFF ".\n", stdout);
}
예제 #8
0
파일: time.c 프로젝트: n054/gnuplot-android
static size_t
xstrftime(
    char *str,			/* output buffer */
    size_t bsz,			/* space available */
    const char *fmt,
    struct tm *tm)
{
    size_t l = 0;			/* chars written so far */

    char *s = str;

    memset(s, '\0', bsz);

    while (*fmt != '\0') {
        if (*fmt != '%') {
            if (l >= bsz)
                return (0);
            *s++ = *fmt++;
            l++;
        } else {
            /* set up format modifiers */
            int w = 0;
            int z = 0;

            if (*++fmt == '0') {
                z = 1;
                ++fmt;
            }
            while (*fmt >= '0' && *fmt <= '9') {
                w = w * 10 + (*fmt - '0');
                ++fmt;
            }

            switch (*fmt++) {

                /* some shorthands : check that there is space in the
                 * output string. */
#define CHECK_SPACE(n) do {				\
		    if ((l+(n)) > bsz) return 0;	\
		} while (0)

                /* copy a fixed string, checking that there's room */
#define COPY_STRING(z) do {			\
		    CHECK_SPACE(strlen(z)) ;	\
		    strcpy(s, z);		\
		} while (0)

                /* format a string, using default spec if none given w
                 * and z are width and zero-flag dw and dz are the
                 * defaults for these In fact, CHECK_SPACE(w) is not a
                 * sufficient test, since sprintf("%2d", 365) outputs
                 * three characters
                 */
#define FORMAT_STRING(dz, dw, x) do {				\
		    if (w==0) {					\
			w=(dw);					\
			if (!z)					\
			    z=(dz);				\
		    }						\
		    CHECK_SPACE(w);				\
		    sprintf(s, z ? "%0*d" : "%*d", w, (x));	\
		} while(0)

            case '%':
                CHECK_SPACE(1);
                *s = '%';
                break;

            case 'a':
                COPY_STRING(abbrev_day_names[tm->tm_wday]);
                break;

            case 'A':
                COPY_STRING(full_day_names[tm->tm_wday]);
                break;

            case 'b':
            case 'h':
                COPY_STRING(abbrev_month_names[tm->tm_mon]);
                break;

            case 'B':
                COPY_STRING(full_month_names[tm->tm_mon]);
                break;


#if 0
            /* %x not currently supported, so neither is c */
            case 'c':
                if (!xstrftime(s, bsz - l, "%x %X", tm))
                    return (0);
                break;
#endif

            case 'd':
                FORMAT_STRING(1, 2, tm->tm_mday);	/* %02d */
                break;

            case 'D':
                if (!xstrftime(s, bsz - l, "%m/%d/%y", tm))
                    return (0);
                break;

            case 'F':
                if (!xstrftime(s, bsz - l, "%Y-%m-%d", tm))
                    return (0);
                break;

            case 'H':
                FORMAT_STRING(1, 2, tm->tm_hour);	/* %02d */
                break;

            case 'I':
                FORMAT_STRING(1, 2, (tm->tm_hour + 11) % 12 + 1); /* %02d */
                break;

            case 'j':
                FORMAT_STRING(1, 3, tm->tm_yday + 1);	/* %03d */
                break;

            /* not in linux strftime man page. Not really needed now */
            case 'k':
                FORMAT_STRING(0, 2, tm->tm_hour);	/* %2d */
                break;

            case 'l':
                FORMAT_STRING(0, 2, (tm->tm_hour + 11) % 12 + 1); /* %2d */
                break;

            case 'm':
                FORMAT_STRING(1, 2, tm->tm_mon + 1);	/* %02d */
                break;

            case 'M':
                FORMAT_STRING(1, 2, tm->tm_min);	/* %02d */
                break;

            case 'p':
                CHECK_SPACE(2);
                strcpy(s, (tm->tm_hour < 12) ? "am" : "pm");
                break;

            case 'r':
                if (!xstrftime(s, bsz - l, "%I:%M:%S %p", tm))
                    return (0);
                break;

            case 'R':
                if (!xstrftime(s, bsz - l, "%H:%M", tm))
                    return (0);
                break;

            case 'S':
                FORMAT_STRING(1, 2, tm->tm_sec);	/* %02d */
                break;

            case 'T':
                if (!xstrftime(s, bsz - l, "%H:%M:%S", tm))
                    return (0);
                break;

            case 'W':		/* mon 1 day of week */
            {
                int week;
                if (tm->tm_yday <= tm->tm_wday) {
                    week = 1;

                    if ((tm->tm_mday - tm->tm_yday) > 4) {
                        week = 52;
                    }
                    if (tm->tm_yday == tm->tm_wday && tm->tm_wday == 0)
                        week = 52;

                } else {

                    /* sun prev week */
                    int bw = tm->tm_yday - tm->tm_wday;

                    if (tm->tm_wday > 0)
                        bw += 7;	/* sun end of week */

                    week = (int) bw / 7;

                    if ((bw % 7) > 2)	/* jan 1 is before friday */
                        week++;
                }
                FORMAT_STRING(1, 2, week);	/* %02d */
                break;
            }

            case 'U':		/* sun 1 day of week */
            {
                int week, bw;

                if (tm->tm_yday <= tm->tm_wday) {
                    week = 1;
                    if ((tm->tm_mday - tm->tm_yday) > 4) {
                        week = 52;
                    }
                } else {
                    /* sat prev week */
                    bw = tm->tm_yday - tm->tm_wday - 1;
                    if (tm->tm_wday >= 0)
                        bw += 7;	/* sat end of week */
                    week = (int) bw / 7;
                    if ((bw % 7) > 1) {	/* jan 1 is before friday */
                        week++;
                    }
                }
                FORMAT_STRING(1, 2, week);	/* %02d */
                break;
            }

            case 'w':		/* day of week, sun=0 */
                FORMAT_STRING(1, 2, tm->tm_wday);	/* %02d */
                break;

            case 'y':
                FORMAT_STRING(1, 2, tm->tm_year % 100);		/* %02d */
                break;

            case 'Y':
                FORMAT_STRING(1, 4, tm->tm_year);	/* %04d */
                break;

#if 0
            case 'Z':
                COPY_STRING(tm->tm_zone);
                break;
#endif
            }			/* switch */

            while (*s != '\0') {
                s++;
                l++;
            }
#undef CHECK_SPACE
#undef COPY_STRING
#undef FORMAT_STRING
        } /* switch(fmt letter) */
    } /* if(fmt letter not '%') */
    return (l);
}