Skip to content

Commit

Permalink
time: add support for parsing timezones denoted by sign and offset
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
MyChaOS87 authored and bradfitz committed Mar 8, 2018
1 parent 3d69ef3 commit 9f2c611
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 4 deletions.
21 changes: 17 additions & 4 deletions src/time/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -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++ {
Expand Down Expand Up @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions src/time/format_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit 9f2c611

Please sign in to comment.