#include <time.h>
#include <limits.h>
#include "locale_impl.h"
-#include "libc.h"
#include "time_impl.h"
-const char *__nl_langinfo_l(nl_item, locale_t);
-
static int is_leap(int y)
{
/* Avoid overflow */
return val;
}
-const char *__tm_to_tzname(const struct tm *);
-size_t __strftime_l(char *restrict, size_t, const char *restrict, const struct tm *restrict, locale_t);
-
-const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm *tm, locale_t loc)
+const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm *tm, locale_t loc, int pad)
{
nl_item item;
long long val;
const char *fmt = "-";
- int width = 2;
+ int width = 2, def_pad = '0';
switch (f) {
case 'a':
case 'C':
val = (1900LL+tm->tm_year) / 100;
goto number;
+ case 'e':
+ def_pad = '_';
case 'd':
val = tm->tm_mday;
goto number;
case 'D':
fmt = "%m/%d/%y";
goto recu_strftime;
- case 'e':
- *l = snprintf(*s, sizeof *s, "%2d", tm->tm_mday);
- return *s;
case 'F':
fmt = "%Y-%m-%d";
goto recu_strftime;
*l = 0;
return "";
}
- *l = snprintf(*s, sizeof *s, "%+.2d%.2d",
- (tm->__tm_gmtoff)/3600,
- abs(tm->__tm_gmtoff%3600)/60);
+ *l = snprintf(*s, sizeof *s, "%+.4ld",
+ tm->__tm_gmtoff/3600*100 + tm->__tm_gmtoff%3600/60);
return *s;
case 'Z':
if (tm->tm_isdst < 0) {
return 0;
}
number:
- *l = snprintf(*s, sizeof *s, "%0*lld", width, val);
+ switch (pad ? pad : def_pad) {
+ case '-': *l = snprintf(*s, sizeof *s, "%lld", val); break;
+ case '_': *l = snprintf(*s, sizeof *s, "%*lld", width, val); break;
+ case '0':
+ default: *l = snprintf(*s, sizeof *s, "%0*lld", width, val); break;
+ }
return *s;
nl_strcat:
fmt = __nl_langinfo_l(item, loc);
char buf[100];
char *p;
const char *t;
- int plus;
+ int pad, plus;
unsigned long width;
for (l=0; l<n; f++) {
if (!*f) {
continue;
}
f++;
+ pad = 0;
+ if (*f == '-' || *f == '_' || *f == '0') pad = *f++;
if ((plus = (*f == '+'))) f++;
width = strtoul(f, &p, 10);
if (*p == 'C' || *p == 'F' || *p == 'G' || *p == 'Y') {
}
f = p;
if (*f == 'E' || *f == 'O') f++;
- t = __strftime_fmt_1(&buf, &k, *f, tm, loc);
+ t = __strftime_fmt_1(&buf, &k, *f, tm, loc, pad);
if (!t) break;
if (width) {
- for (; *t=='+' || *t=='-' || (*t=='0'&&t[1]); t++, k--);
- width--;
- if (plus && tm->tm_year >= 10000-1900)
- s[l++] = '+';
- else if (tm->tm_year < -1900)
+ /* Trim off any sign and leading zeros, then
+ * count remaining digits to determine behavior
+ * for the + flag. */
+ if (*t=='+' || *t=='-') t++, k--;
+ for (; *t=='0' && t[1]-'0'<10U; t++, k--);
+ if (width < k) width = k;
+ size_t d;
+ for (d=0; t[d]-'0'<10U; d++);
+ if (tm->tm_year < -1900) {
s[l++] = '-';
- else
- width++;
+ width--;
+ } else if (plus && d+(width-k) >= (*p=='C'?3:5)) {
+ s[l++] = '+';
+ width--;
+ }
for (; width > k && l < n; width--)
s[l++] = '0';
}