]> Cypherpunks repositories - gostls13.git/commitdiff
time: add support for parsing timezones denoted by sign and offset
authorMichael Kasch <michael.kasch@gmail.com>
Fri, 2 Mar 2018 18:03:21 +0000 (19:03 +0100)
committerBrad Fitzpatrick <bradfitz@golang.org>
Thu, 8 Mar 2018 17:15:35 +0000 (17:15 +0000)
IANA Zoneinfo does not provide names for all timezones. Some are denoted
by a sign and an offset only. E.g: Europe/Turkey is currently +03 or
America/La_Paz which is -04 (https://data.iana.org/time-zones/releases/tzdata2018c.tar.gz)

Fixes #24071

Change-Id: I9c230a719945e1263c5b52bab82084d22861be3e
Reviewed-on: https://go-review.googlesource.com/98157
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/time/format.go
src/time/format_test.go

index a60474f02684bc7c260a8483b739ab3a5ef489fb..7994052510e51057f8472820391802c5e9ff8fec 100644 (file)
@@ -1117,6 +1117,11 @@ func parseTimeZone(value string) (length int, ok bool) {
                length = parseGMT(value)
                return length, true
        }
+       // Special Case 3: Some time zones are not named, but have +/-00 format
+       if value[0] == '+' || value[0] == '-' {
+               length = parseSignedOffset(value)
+               return length, true
+       }
        // How many upper-case letters are there? Need at least three, at most five.
        var nUpper int
        for nUpper = 0; nUpper < 6; nUpper++ {
@@ -1153,21 +1158,29 @@ func parseGMT(value string) int {
        if len(value) == 0 {
                return 3
        }
+
+       return 3 + parseSignedOffset(value)
+}
+
+// parseSignedOffset parses a signed timezone offset (e.g. "+03" or "-04").
+// The function checks for a signed number in the range -14 through +12 excluding zero.
+// Returns length of the found offset string or 0 otherwise
+func parseSignedOffset(value string) int {
        sign := value[0]
        if sign != '-' && sign != '+' {
-               return 3
+               return 0
        }
        x, rem, err := leadingInt(value[1:])
        if err != nil {
-               return 3
+               return 0
        }
        if sign == '-' {
                x = -x
        }
        if x == 0 || x < -14 || 12 < x {
-               return 3
+               return 0
        }
-       return 3 + len(value) - len(rem)
+       return len(value) - len(rem)
 }
 
 func parseNanoseconds(value string, nbytes int) (ns int, rangeErrString string, err error) {
index 6d27f468c7b7863fcd3dde6159dd6bbb97245deb..68a4d3ddb0e8992d5d567c60cfe539feddcafc7a 100644 (file)
@@ -427,6 +427,8 @@ var parseTimeZoneTests = []ParseTimeZoneTest{
        {"ESASTT hi", 0, false}, // run of upper-case letters too long.
        {"ESATY hi", 0, false},  // five letters must end in T.
        {"WITA hi", 4, true},    // Issue #18251
+       {"+03 hi", 3, true},     // Issue #24071
+       {"-04 hi", 3, true},     // Issue #24071
 }
 
 func TestParseTimeZone(t *testing.T) {