diff --git a/src/time/format.go b/src/time/format.go index 7ae89c557d5..c2bffb8ff68 100644 --- a/src/time/format.go +++ b/src/time/format.go @@ -146,10 +146,11 @@ const ( stdFracSecond0 // ".0", ".00", ... , trailing zeros included stdFracSecond9 // ".9", ".99", ..., trailing zeros omitted - stdNeedDate = 1 << 8 // need month, day, year - stdNeedClock = 2 << 8 // need hour, minute, second - stdArgShift = 16 // extra argument in high bits, above low stdArgShift - stdMask = 1<> stdArgShift) & 0xfff +} + +func separator(std int) byte { + if (std >> stdSeparatorShift) == 0 { + return '.' + } + return ',' +} + // formatNano appends a fractional second, as nanoseconds, to b // and returns the result. -func formatNano(b []byte, nanosec uint, n int, trim bool) []byte { +func formatNano(b []byte, nanosec uint, std int) []byte { + var ( + n = digitsLen(std) + separator = separator(std) + trim = std&stdMask == stdFracSecond9 + ) u := nanosec var buf [9]byte for start := len(buf); start > 0; { @@ -452,7 +480,7 @@ func formatNano(b []byte, nanosec uint, n int, trim bool) []byte { return b } } - b = append(b, '.') + b = append(b, separator) return append(b, buf[:n]...) } @@ -733,7 +761,7 @@ func (t Time) AppendFormat(b []byte, layout string) []byte { b = appendInt(b, zone/60, 2) b = appendInt(b, zone%60, 2) case stdFracSecond0, stdFracSecond9: - b = formatNano(b, uint(t.Nanosecond()), std>>stdArgShift, std&stdMask == stdFracSecond9) + b = formatNano(b, uint(t.Nanosecond()), std) } } return b @@ -1165,7 +1193,7 @@ func parse(layout, value string, defaultLocation, local *Location) (Time, error) case stdFracSecond0: // stdFracSecond0 requires the exact number of digits as specified in // the layout. - ndigit := 1 + (std >> stdArgShift) + ndigit := 1 + digitsLen(std) if len(value) < ndigit { err = errBad break diff --git a/src/time/format_test.go b/src/time/format_test.go index 1af41e2dfb3..93cbcf94013 100644 --- a/src/time/format_test.go +++ b/src/time/format_test.go @@ -832,3 +832,23 @@ func TestQuote(t *testing.T) { } } + +// Issue 48037 +func TestFormatFractionalSecondSeparators(t *testing.T) { + tests := []struct { + s, want string + }{ + {`15:04:05.000`, `21:00:57.012`}, + {`15:04:05.999`, `21:00:57.012`}, + {`15:04:05,000`, `21:00:57,012`}, + {`15:04:05,999`, `21:00:57,012`}, + } + + // The numeric time represents Thu Feb 4 21:00:57.012345600 PST 2009 + time := Unix(0, 1233810057012345600) + for _, tt := range tests { + if q := time.Format(tt.s); q != tt.want { + t.Errorf("Format(%q) = got %q, want %q", tt.s, q, tt.want) + } + } +}