diff options
author | Alexander Yastrebov <yastrebov.alex@gmail.com> | 2021-10-03 15:45:38 +0000 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2021-10-06 19:45:35 +0000 |
commit | e38ec96c69f826516a99f16952bd73c766f96719 (patch) | |
tree | 5e1e13626cdb51efc6de7a2a4d7f353e7c7534a0 | |
parent | 39a4df49674540ba8b835ece03edb8d304941187 (diff) | |
download | go-e38ec96c69f826516a99f16952bd73c766f96719.tar.gz go-e38ec96c69f826516a99f16952bd73c766f96719.zip |
time: truncate fractional seconds longer than 9 digits
Fixes #48685
Change-Id: Id246708878c2902b407ab759537f6b545a1f459f
GitHub-Last-Rev: 4d985192c5a66ae8891539f166ef88b53cd1cbea
GitHub-Pull-Request: golang/go#48750
Reviewed-on: https://go-review.googlesource.com/c/go/+/353713
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Trust: Emmanuel Odeke <emmanuel@orijtech.com>
-rw-r--r-- | src/time/format.go | 9 | ||||
-rw-r--r-- | src/time/format_test.go | 41 |
2 files changed, 47 insertions, 3 deletions
diff --git a/src/time/format.go b/src/time/format.go index 7373892b97..464effdb43 100644 --- a/src/time/format.go +++ b/src/time/format.go @@ -1420,16 +1420,19 @@ func parseNanoseconds(value string, nbytes int) (ns int, rangeErrString string, err = errBad return } + if nbytes > 10 { + value = value[:10] + nbytes = 10 + } if ns, err = atoi(value[1:nbytes]); err != nil { return } - if ns < 0 || 1e9 <= ns { + if ns < 0 { rangeErrString = "fractional second" return } // We need nanoseconds, which means scaling by the number - // of missing digits in the format, maximum length 10. If it's - // longer than 10, we won't scale. + // of missing digits in the format, maximum length 10. scaleDigits := 10 - nbytes for i := 0; i < scaleDigits; i++ { ns *= 10 diff --git a/src/time/format_test.go b/src/time/format_test.go index 93cbcf9401..db95536390 100644 --- a/src/time/format_test.go +++ b/src/time/format_test.go @@ -852,3 +852,44 @@ func TestFormatFractionalSecondSeparators(t *testing.T) { } } } + +// Issue 48685 +func TestParseFractionalSecondsLongerThanNineDigits(t *testing.T) { + tests := []struct { + s string + want int + }{ + // 9 digits + {"2021-09-29T16:04:33.000000000Z", 0}, + {"2021-09-29T16:04:33.000000001Z", 1}, + {"2021-09-29T16:04:33.100000000Z", 100_000_000}, + {"2021-09-29T16:04:33.100000001Z", 100_000_001}, + {"2021-09-29T16:04:33.999999999Z", 999_999_999}, + {"2021-09-29T16:04:33.012345678Z", 12_345_678}, + // 10 digits, truncates + {"2021-09-29T16:04:33.0000000000Z", 0}, + {"2021-09-29T16:04:33.0000000001Z", 0}, + {"2021-09-29T16:04:33.1000000000Z", 100_000_000}, + {"2021-09-29T16:04:33.1000000009Z", 100_000_000}, + {"2021-09-29T16:04:33.9999999999Z", 999_999_999}, + {"2021-09-29T16:04:33.0123456789Z", 12_345_678}, + // 11 digits, truncates + {"2021-09-29T16:04:33.10000000000Z", 100_000_000}, + {"2021-09-29T16:04:33.00123456789Z", 1_234_567}, + // 12 digits, truncates + {"2021-09-29T16:04:33.000123456789Z", 123_456}, + // 15 digits, truncates + {"2021-09-29T16:04:33.9999999999999999Z", 999_999_999}, + } + + for _, tt := range tests { + tm, err := Parse(RFC3339, tt.s) + if err != nil { + t.Errorf("Unexpected error: %v", err) + continue + } + if got := tm.Nanosecond(); got != tt.want { + t.Errorf("Parse(%q) = got %d, want %d", tt.s, got, tt.want) + } + } +} |