[1/2,BZ,#16141] strptime: extend %z range to UTC+14:00

Message ID 1417564016-3572-1-git-send-email-james@loowit.net
State Superseded
Headers

Commit Message

James Perkins Dec. 2, 2014, 11:46 p.m. UTC
  This is a fix for [BZ #16141] strptime %z offset restriction.

strptime supports the parsing of a timezone offset from UTC time into the
broken-out time field tm_gmtoff. It supports timezone offsets between
UTC-12:00 and UTC+12:00, returning an error (NULL) for values outside
that range.

However, there are valid international timezones outside the supported
range.  Extending the valid positive timezone offset to +14:00 allows
for the correct parsing of several timezone offsets including:

* Pacific/Auckland summer time (+13:00)
* Pacific/Kiritimati (+14:00)
* Pacific/Apia summer time (+14:00)

James

2014-12-02  James Perkins  james@loowit.net

	[BZ #16141]
	* time/strptime_l.c (__strptime_internal): Extend %z timezone
	offset range to UTC+14:00 to parse offsets typical of extreme
	Western Pacific timezones, like NZ and Samoa summer time and
	Christmas Island.

---
 time/strptime_l.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
  

Comments

Paul Eggert Dec. 3, 2014, 1:31 a.m. UTC | #1
James Perkins wrote:
> Extending the valid positive timezone offset to +14:00 allows
> for the correct parsing of several timezone offsets

Why stop with the range -12..+14?  A wider range is needed to support past 
historical timestamps, e.g., when the Philippines used American time and NW 
North America used Asian:

$ TZ=Asia/Manila date -d@-4039286400 --rfc-3339=seconds
1841-12-31 08:04:00-15:56
$ TZ=America/Juneau date -d@-4039286400 --rfc-3339=seconds
1842-01-01 15:02:19+15:02

Also, POSIX allows the range -24 .. +25 for the hours field:

$ TZ=XXX-24:59YYY,2,1 date -d@0 --rfc-3339=seconds
1970-01-02 01:59:00+25:59
$ TZ=ZZZ24:59 date -d@0 --rfc-3339=seconds
1969-12-30 23:01:00-24:59

So I suggest allowing at least -24 .. +25.
  
James Perkins Dec. 3, 2014, 2:41 a.m. UTC | #2
On Tue, Dec 2, 2014 at 5:31 PM, Paul Eggert <eggert@cs.ucla.edu> wrote:
> Also, POSIX allows the range -24 .. +25 for the hours field:
>
> $ TZ=XXX-24:59YYY,2,1 date -d@0 --rfc-3339=seconds
> 1970-01-02 01:59:00+25:59
> $ TZ=ZZZ24:59 date -d@0 --rfc-3339=seconds
> 1969-12-30 23:01:00-24:59
>
> So I suggest allowing at least -24 .. +25.

After I posted my PATCH v2, to support -2400 to +2500, I re-read your comment,
which I know suspect encourages me to support -2459 to +2559.

If you agree, I will spin the patch set one more time. Thanks again for your
feedback.

Cheers,
James
  
Paul Eggert Dec. 3, 2014, 6:21 a.m. UTC | #3
James Perkins wrote:
> encourages me to support -2459 to +2559.

Yes, that's right.  If possible it should go all the way to -24:59:59 to 
+25:59:59.  Or perhaps you should allow the first two digits to be anything up 
to 99; why not be generous?
  
James Perkins Dec. 3, 2014, 10:24 p.m. UTC | #4
On Tue, Dec 2, 2014 at 10:21 PM, Paul Eggert <eggert@cs.ucla.edu> wrote:
> Yes, that's right.  If possible it should go all the way to -24:59:59 to
> +25:59:59.  Or perhaps you should allow the first two digits to be anything
> up to 99; why not be generous?

I will rework strptime to remove the limits on hours, so that strptime will
calculate a correct seconds offset for values in the range -9959 to +9959 if
minutes are provided in the input string, or -99 to +99 hours if the minutes
were not provided.

I do not plan to extend strptime's functionality to include optional seconds
(presumably a six numeric digit offset string) at this time; it is a new feature
and deserves its own bugzilla entry. It will also need a champion which is
more motivated and better connected than I am.

Cheers,
James
  
Mike Frysinger Aug. 27, 2015, 4:10 a.m. UTC | #5
looks fine to me.  if no one else gets to it, i'll merge it in a few days.
-mike
  

Patch

diff --git a/time/strptime_l.c b/time/strptime_l.c
index b3a612e..2140c47 100644
--- a/time/strptime_l.c
+++ b/time/strptime_l.c
@@ -777,7 +777,11 @@  __strptime_internal (rp, fmt, tmp, statep LOCALE_PARAM)
 		  return NULL;
 		val = (val / 100) * 100 + ((val % 100) * 50) / 30;
 	      }
-	    if (val > 1200)
+	    /* minimum UTC-12, used aboard ships */
+	    if (neg && val > 1200)
+	      return NULL;
+	    /* maximum UTC+14, Pacific/Kiritimati and Pacific/Apia summer time */
+	    if (!neg && val > 1400)
 	      return NULL;
 	    tm->tm_gmtoff = (val * 3600) / 100;
 	    if (neg)