diff options
Diffstat (limited to 'libgo/go/time/format.go')
-rw-r--r-- | libgo/go/time/format.go | 62 |
1 files changed, 48 insertions, 14 deletions
diff --git a/libgo/go/time/format.go b/libgo/go/time/format.go index c2ae7930203..b903e1485c6 100644 --- a/libgo/go/time/format.go +++ b/libgo/go/time/format.go @@ -42,6 +42,13 @@ import "errors" // Z07:00 Z or ±hh:mm // Z07 Z or ±hh // +// The recognized day of week formats are "Mon" and "Monday". +// The recognized month formats are "Jan" and "January". +// +// Text in the format string that is not recognized as part of the reference +// time is echoed verbatim during Format and expected to appear verbatim +// in the input to Parse. +// // The executable example for time.Format demonstrates the working // of the layout string in detail and is a good reference. // @@ -844,6 +851,7 @@ func parse(layout, value string, defaultLocation, local *Location) (Time, error) sec, value, err = getnum(value, std == stdZeroSecond) if sec < 0 || 60 <= sec { rangeErrString = "second" + break } // Special case: do we have a fractional second but no // fractional second in the format? @@ -1004,7 +1012,7 @@ func parse(layout, value string, defaultLocation, local *Location) (Time, error) } // Validate the day of the month. - if day > daysIn(Month(month), year) { + if day < 1 || day > daysIn(Month(month), year) { return Time{}, &ParseError{alayout, avalue, "", value, ": day out of range"} } @@ -1020,12 +1028,12 @@ func parse(layout, value string, defaultLocation, local *Location) (Time, error) // If that zone was in effect at the given time, use it. name, offset, _, _, _ := local.lookup(t.sec + internalToUnix) if offset == zoneOffset && (zoneName == "" || name == zoneName) { - t.loc = local + t.setLoc(local) return t, nil } // Otherwise create fake zone to record offset. - t.loc = FixedZone(zoneName, zoneOffset) + t.setLoc(FixedZone(zoneName, zoneOffset)) return t, nil } @@ -1036,7 +1044,7 @@ func parse(layout, value string, defaultLocation, local *Location) (Time, error) offset, _, ok := local.lookupName(zoneName, t.sec+internalToUnix) if ok { t.sec -= int64(offset) - t.loc = local + t.setLoc(local) return t, nil } @@ -1045,7 +1053,7 @@ func parse(layout, value string, defaultLocation, local *Location) (Time, error) offset, _ = atoi(zoneName[3:]) // Guaranteed OK by parseGMT. offset *= 3600 } - t.loc = FixedZone(zoneName, offset) + t.setLoc(FixedZone(zoneName, offset)) return t, nil } @@ -1093,8 +1101,9 @@ func parseTimeZone(value string) (length int, ok bool) { if value[4] == 'T' { return 5, true } - case 4: // Must end in T to match. - if value[3] == 'T' { + case 4: + // Must end in T, except one special case. + if value[3] == 'T' || value[:4] == "WITA" { return 4, true } case 3: @@ -1173,6 +1182,37 @@ func leadingInt(s string) (x int64, rem string, err error) { return x, s[i:], nil } +// leadingFraction consumes the leading [0-9]* from s. +// It is used only for fractions, so does not return an error on overflow, +// it just stops accumulating precision. +func leadingFraction(s string) (x int64, scale float64, rem string) { + i := 0 + scale = 1 + overflow := false + for ; i < len(s); i++ { + c := s[i] + if c < '0' || c > '9' { + break + } + if overflow { + continue + } + if x > (1<<63-1)/10 { + // It's possible for overflow to give a positive number, so take care. + overflow = true + continue + } + y := x*10 + int64(c) - '0' + if y < 0 { + overflow = true + continue + } + x = y + scale *= 10 + } + return x, scale, s[i:] +} + var unitMap = map[string]int64{ "ns": int64(Nanosecond), "us": int64(Microsecond), @@ -1235,13 +1275,7 @@ func ParseDuration(s string) (Duration, error) { if s != "" && s[0] == '.' { s = s[1:] pl := len(s) - f, s, err = leadingInt(s) - if err != nil { - return 0, errors.New("time: invalid duration " + orig) - } - for n := pl - len(s); n > 0; n-- { - scale *= 10 - } + f, scale, s = leadingFraction(s) post = pl != len(s) } if !pre && !post { |