mirror of
https://github.com/golang/go
synced 2024-11-25 08:57:58 -07:00
time: expand acceptance of time zones when parsing
I tried to make it absolutely correct but there are too many conflicting definitions for the official list of time zones. Since when we're parsing we know when to expect a time zone and we know what they look like if not exactly what the definitive set is, we compromise. We accept any three-character sequence of upper case letters, possibly followed by a capital T (all four-letter zones end in T). There is one crazy special case (ChST) and the possibility of a signed hour offset for GMT. Fixes #3790 I hope forever, but I doubt that very much. R=golang-dev, adg CC=golang-dev https://golang.org/cl/12969043
This commit is contained in:
parent
ec837ad73c
commit
a454d2fd2e
@ -1023,30 +1023,39 @@ func parse(layout, value string, defaultLocation, local *Location) (Time, error)
|
|||||||
return Date(year, Month(month), day, hour, min, sec, nsec, defaultLocation), nil
|
return Date(year, Month(month), day, hour, min, sec, nsec, defaultLocation), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseTimeZone parses a time zone string and returns its length.
|
// parseTimeZone parses a time zone string and returns its length. Time zones
|
||||||
|
// are human-generated and unpredictable. We can't do precise error checking.
|
||||||
|
// On the other hand, for a correct parse there must be a time zone at the
|
||||||
|
// beginning of the string, so it's almost always true that there's one
|
||||||
|
// there. We check: 3 or 4 upper case letters (with one exception). If 4, the
|
||||||
|
// last letter must be a T.
|
||||||
|
// GMT is special because it can have an hour offset.
|
||||||
func parseTimeZone(value string) (length int, ok bool) {
|
func parseTimeZone(value string) (length int, ok bool) {
|
||||||
if len(value) < 3 {
|
if len(value) < 3 {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
// GMT may have an offset.
|
// Special case 1: This is the only zone with a lower-case letter.
|
||||||
if len(value) >= 3 && value[:3] == "GMT" {
|
if len(value) >= 4 && value[:4] == "ChST" {
|
||||||
|
return 4, true
|
||||||
|
}
|
||||||
|
// Special case 2: GMT may have an hour offset; treat it specially.
|
||||||
|
if value[:3] == "GMT" {
|
||||||
length = parseGMT(value)
|
length = parseGMT(value)
|
||||||
return length, true
|
return length, true
|
||||||
}
|
}
|
||||||
|
// There must be three upper-case letters.
|
||||||
if len(value) >= 3 && value[2] == 'T' {
|
for i := 0; i < 3; i++ {
|
||||||
length = 3
|
c := value[i]
|
||||||
} else if len(value) >= 4 && value[3] == 'T' {
|
if c < 'A' || 'Z' < c {
|
||||||
length = 4
|
|
||||||
} else {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
for i := 0; i < length; i++ {
|
|
||||||
if value[i] < 'A' || 'Z' < value[i] {
|
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return length, true
|
// There may be a fourth upper case letter. If so, in a time zone it's always a 'T'.
|
||||||
|
// (The last letter is often not a 'T' in three-letter zones: MSK, MSD, HAE, etc.)
|
||||||
|
if len(value) >= 4 && value[3] == 'T' {
|
||||||
|
return 4, true
|
||||||
|
}
|
||||||
|
return 3, true
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseGMT parses a GMT time zone. The input string is known to start "GMT".
|
// parseGMT parses a GMT time zone. The input string is known to start "GMT".
|
||||||
|
Loading…
Reference in New Issue
Block a user