[ptime] fix %p and %l

This commit is contained in:
Timothy Stack 2018-05-28 08:15:42 -07:00
parent 6bfd158e49
commit d1da7b800c
2 changed files with 59 additions and 33 deletions

View File

@ -603,23 +603,41 @@ inline void ftime_k(char *dst, off_t &off_inout, ssize_t len, const struct exttm
inline bool ptime_l(struct exttm *dst, const char *str, off_t &off_inout, ssize_t len)
{
off_t orig_off = off_inout;
bool consumed_space = false;
dst->et_tm.tm_hour = 0;
PTIME_CONSUME(1, {
if (str[off_inout] < '1' || str[off_inout] > '9') {
return false;
}
dst->et_tm.tm_hour = str[off_inout] - '0';
});
if (off_inout + 1 < len) {
if (str[off_inout] >= '0' && str[off_inout] <= '9') {
dst->et_tm.tm_hour *= 10;
dst->et_tm.tm_hour += str[off_inout] - '0';
off_inout += 1;
}
if ((off_inout + 1) > len) {
return false;
}
if (dst->et_tm.tm_hour >= 1 && dst->et_tm.tm_hour <= 12) {
if (str[off_inout] == ' ') {
consumed_space = true;
off_inout += 1;
}
if ((off_inout + 1) > len) {
off_inout = orig_off;
return false;
}
if (str[off_inout] < '1' || str[off_inout] > '9') {
off_inout = orig_off;
return false;
}
dst->et_tm.tm_hour = str[off_inout] - '0';
off_inout += 1;
if (consumed_space || str[off_inout] < '0' || str[off_inout] > '9') {
return true;
}
dst->et_tm.tm_hour *= 10;
dst->et_tm.tm_hour += str[off_inout] - '0';
off_inout += 1;
if (dst->et_tm.tm_hour >= 0 && dst->et_tm.tm_hour <= 23) {
return true;
}
@ -657,11 +675,11 @@ inline bool ptime_p(struct exttm *dst, const char *str, off_t &off_inout, ssize_
}
else if ((lead & 0xdf) == 'A') {
if (dst->et_tm.tm_hour == 12) {
dst->et_tm.tm_hour -= 12;
dst->et_tm.tm_hour = 0;
}
}
else if ((lead & 0xdf) == 'P') {
if (dst->et_tm.tm_hour > 12) {
if (dst->et_tm.tm_hour < 12) {
dst->et_tm.tm_hour += 12;
}
}

View File

@ -82,30 +82,38 @@ TEST_CASE("rgb_color from string") {
}
TEST_CASE("ptime_roundtrip") {
const char *fmt = "%Y-%d-%m\t%H:%M:%S";
const char *fmts[] = {
"%Y-%m-%d %l:%M:%S %p",
"%Y-%m-%d %I:%M:%S %p",
};
time_t now = time(nullptr);
for (time_t sec = now; sec < (now + (24 * 60 * 60)); sec++) {
char ftime_result[128];
char strftime_result[128];
struct exttm etm;
for (auto fmt : fmts) {
for (time_t sec = now; sec < (now + (24 * 60 * 60)); sec++) {
char ftime_result[128];
char strftime_result[128];
struct exttm etm;
memset(&etm, 0, sizeof(etm));
gmtime_r(&sec, &etm.et_tm);
etm.et_flags = ETF_YEAR_SET | ETF_MONTH_SET | ETF_DAY_SET;
size_t ftime_size = ftime_fmt(ftime_result, sizeof(ftime_result), fmt, etm);
size_t strftime_size = strftime(strftime_result, sizeof(strftime_result), fmt, &etm.et_tm);
memset(&etm, 0, sizeof(etm));
gmtime_r(&sec, &etm.et_tm);
etm.et_flags = ETF_YEAR_SET | ETF_MONTH_SET | ETF_DAY_SET;
size_t ftime_size = ftime_fmt(ftime_result, sizeof(ftime_result),
fmt, etm);
size_t strftime_size = strftime(strftime_result,
sizeof(strftime_result), fmt,
&etm.et_tm);
CHECK(string(ftime_result, ftime_size) ==
string(strftime_result, strftime_size));
CHECK(string(ftime_result, ftime_size) ==
string(strftime_result, strftime_size));
struct exttm etm2;
off_t off = 0;
struct exttm etm2;
off_t off = 0;
memset(&etm2, 0, sizeof(etm2));
bool rc = ptime_fmt(fmt, &etm2, ftime_result, off, ftime_size);
CHECK(rc);
CHECK(sec == tm2sec(&etm2.et_tm));
memset(&etm2, 0, sizeof(etm2));
bool rc = ptime_fmt(fmt, &etm2, ftime_result, off, ftime_size);
CHECK(rc);
CHECK(sec == tm2sec(&etm2.et_tm));
}
}
}