diff options
-rw-r--r-- | lib/xwrap.c | 20 | ||||
-rw-r--r-- | tests/date.test | 5 |
2 files changed, 19 insertions, 6 deletions
diff --git a/lib/xwrap.c b/lib/xwrap.c index 1e1019a2..7e5e1500 100644 --- a/lib/xwrap.c +++ b/lib/xwrap.c @@ -1039,17 +1039,24 @@ void xparsedate(char *str, time_t *t, unsigned *nano, int endian) } // Handle optional Z or +HH[[:]MM] timezone + while (isspace(*p)) p++; if (*p && strchr("Z+-", *p)) { - unsigned hh, mm = 0, len; + unsigned uu[3] = {0}, n = 0, nn = 0; char *tz, sign = *p++; if (sign == 'Z') tz = "UTC0"; - else if (sscanf(p, "%2u%2u%n", &hh, &mm, &len) == 2 - || sscanf(p, "%2u%n:%2u%n", &hh, &len, &mm, &len) > 0) - { + else if (0<sscanf(p, " %u%n : %u%n : %u%n", uu,&n,uu+1,&nn,uu+2,&nn)) { + if (n>2) { + uu[1] += uu[0]%100; + uu[0] /= 100; + } + if (n>nn) nn = n; + if (!nn) continue; + // flip sign because POSIX UTC offsets are backwards - sprintf(tz = libbuf, "UTC%c%02d:%02d", "+-"[sign=='+'], hh, mm); - p += len; + sprintf(tz = libbuf, "UTC%c%02u:%02u:%02u", "+-"[sign=='+'], + uu[0], uu[1], uu[2]); + p += nn; } else continue; if (!oldtz) { @@ -1058,6 +1065,7 @@ void xparsedate(char *str, time_t *t, unsigned *nano, int endian) } setenv("TZ", tz, 1); } + while (isspace(*p)) p++; if (!*p) break; } diff --git a/tests/date.test b/tests/date.test index 6aaf937e..dfcefb26 100644 --- a/tests/date.test +++ b/tests/date.test @@ -76,6 +76,8 @@ testing "TZ= @" "TZ='America/Los_Angeles' date -d 'TZ=\"GMT\" @1533427200'" "Sat # Test all supported UTC offset variants. testing "tz Z" \ "date -u -d 2020-08-01T12:34:56Z" "Sat Aug 1 12:34:56 UTC 2020\n" "" "" +testing "tz ' Z '" \ + "date -u -d '2020-08-01T12:34:56 Z '" "Sat Aug 1 12:34:56 UTC 2020\n" "" "" testing "tz -0800" \ "date -u -d 2020-08-01T12:34:56-0800" "Sat Aug 1 20:34:56 UTC 2020\n" "" "" testing "tz +0800" \ @@ -88,6 +90,9 @@ testing "tz +08" \ "date -u -d 2020-08-01T12:34:56+08" "Sat Aug 1 04:34:56 UTC 2020\n" "" "" testing "tz +008" \ "date -u -d 2020-08-01T12:34:56+008" "Sat Aug 1 12:26:56 UTC 2020\n" "" "" +testing "tz + 8 : 8 " \ + "date -u -d '2020-08-01T12:34:56 + 8 : 8 '" "Sat Aug 1 04:26:56 UTC 2020\n"\ + "" "" # Can we parse date's own output format? testing "round trip" 'TZ=$tz date -d "$(TZ=$tz date -d @1598476818)"' \ |