time: in strptime(), make %z accept [+-]HH:MM tz [BZ #17887]

In ISO 8601, +03:30 is a valid time zone. Currently, strptime() only
parses it as a 2-digit time zone an believes this is +03:00. This change
makes it accept a single colon.
This commit is contained in:
Vincent Bernat 2015-09-17 09:56:13 +02:00 committed by Mike Frysinger
parent 900f33e23e
commit e952e1dfeb
4 changed files with 38 additions and 13 deletions

View File

@ -1,3 +1,9 @@
2015-09-18 Vincent Bernat <vincent@bernat.im>
[BZ #17887]
* time/strptime_l.c (__strptime_internal): Make %z accept
[+-]HH:MM time zones.
2015-09-18 Vincent Bernat <vincent@bernat.im>
[BZ #17886]

10
NEWS
View File

@ -11,11 +11,11 @@ Version 2.23
2542, 2543, 2558, 2898, 4404, 6803, 14341, 14912, 15384, 15786, 15918,
16141, 16296, 16415, 16517, 16519, 16520, 16521, 16734, 16973, 16985,
17118, 17243, 17244, 17787, 17886, 17905, 18084, 18086, 18240, 18265,
18370, 18421, 18480, 18525, 18595, 18610, 18618, 18647, 18661, 18674,
18675, 18681, 18757, 18778, 18781, 18787, 18789, 18790, 18795, 18796,
18820, 18823, 18824, 18857, 18863, 18870, 18872, 18873, 18875, 18887,
18921, 18951, 18952, 18961, 18966, 18967, 18970, 18977.
17118, 17243, 17244, 17787, 17886, 17887, 17905, 18084, 18086, 18240,
18265, 18370, 18421, 18480, 18525, 18595, 18610, 18618, 18647, 18661,
18674, 18675, 18681, 18757, 18778, 18781, 18787, 18789, 18790, 18795,
18796, 18820, 18823, 18824, 18857, 18863, 18870, 18872, 18873, 18875,
18887, 18921, 18951, 18952, 18961, 18966, 18967, 18970, 18977.
* The obsolete header <regexp.h> has been removed. Programs that require
this header must be updated to use <regex.h> instead.

View File

@ -749,9 +749,11 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
rp++;
break;
case 'z':
/* We recognize three formats: if two digits are given, these
specify hours. If fours digits are used, minutes are
also specified. 'Z' is equivalent to +0000. */
/* We recognize four formats:
1. Two digits specify hours.
2. Four digits specify hours and minutes.
3. Two digits, ':', and two digits specify hours and minutes.
4. 'Z' is equivalent to +0000. */
{
val = 0;
while (ISSPACE (*rp))
@ -770,6 +772,8 @@ __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
{
val = val * 10 + *rp++ - '0';
++n;
if (*rp == ':' && n == 2 && isdigit (*(rp + 1)))
++rp;
}
if (n == 2)
val *= 100;

View File

@ -35,7 +35,8 @@ static bool verbose;
following fields:
Sign field consisting of a '+' or '-' sign,
Hours field in two decimal digits, and
optional Minutes field in two decimal digits.
optional Minutes field in two decimal digits. Optionally,
a ':' is used to seperate hours and minutes.
This function may write test strings with minutes values outside
the valid range 00-59. These are invalid strings and useful for
@ -56,7 +57,7 @@ static bool verbose;
range of 00 to 59. */
static long int
mkbuf (char *buf, bool neg, unsigned int hhmm, size_t ndigits)
mkbuf (char *buf, bool neg, bool colon, unsigned int hhmm, size_t ndigits)
{
const int mm_max = 59;
char sign = neg ? '-' : '+';
@ -66,7 +67,10 @@ mkbuf (char *buf, bool neg, unsigned int hhmm, size_t ndigits)
long int expect = LONG_MAX;
i = sprintf (buf, "%s %c", dummy_string, sign);
snprintf (buf + i, ndigits + 1, "%04u", hhmm);
if (colon)
snprintf (buf + i, ndigits + 2, "%02u:%02u", hh, mm);
else
snprintf (buf + i, ndigits + 1, "%04u", hhmm);
if (mm <= mm_max && (ndigits == 2 || ndigits == 4))
{
@ -177,11 +181,22 @@ do_test (void)
{
/* Test both positive and negative signs. */
expect = mkbuf (buf, false, hhmm, ndigits);
expect = mkbuf (buf, false, false, hhmm, ndigits);
result |= compare (buf, expect, nresult);
expect = mkbuf (buf, true, hhmm, ndigits);
expect = mkbuf (buf, true, false, hhmm, ndigits);
result |= compare (buf, expect, nresult);
/* Test with colon as well. */
if (ndigits >= 3)
{
expect = mkbuf (buf, false, true, hhmm, ndigits);
result |= compare (buf, expect, nresult);
expect = mkbuf (buf, true, true, hhmm, ndigits);
result |= compare (buf, expect, nresult);
}
}
if (result > 0 || verbose)