Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/time/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ var StdChunkNames = map[int]string{
var Quote = quote

var AppendInt = appendInt
var AppendIntWidth2 = appendIntWidth2
var AppendIntWidth4 = appendIntWidth4
var AppendFormatAny = Time.appendFormat
var AppendFormatRFC3339 = Time.appendFormatRFC3339
var ParseAny = parse
Expand Down
30 changes: 30 additions & 0 deletions src/time/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,36 @@ func appendInt(b []byte, x int, width int) []byte {
return b
}

const unitsDigit = "01234567890123456789012345678901234567890123456789" +
"01234567890123456789012345678901234567890123456789"
const tensDigit = "00000000001111111111222222222233333333334444444444" +
"55555555556666666666777777777788888888889999999999"

// appendIntWidth2 special scenario for appendInt, with parameter width=2
// Only applicable to integers with absolute value less than 100
func appendIntWidth2(b []byte, x int) []byte {
if x < 0 {
b = append(b, '-')
x = -x
}
if x >= 1e2 {
x %= 1e2
}
return append(b, tensDigit[x], unitsDigit[x])
}

// appendIntWidth4 special scenario for appendInt, with parameter width=4
func appendIntWidth4(b []byte, x int) []byte {
if x < 0 {
b = append(b, '-')
x = -x
}
if x >= 1e4 {
return appendInt(b, x, 4)
}
return append(b, tensDigit[x/1e2], unitsDigit[x/1e2], tensDigit[x%1e2], unitsDigit[x%1e2])
}

// Never printed, just needs to be non-nil for return by atoi.
var errAtoi = errors.New("time: invalid number")

Expand Down
16 changes: 8 additions & 8 deletions src/time/format_rfc3339.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@ func (t Time) appendFormatRFC3339(b []byte, nanos bool) []byte {

// Format date.
year, month, day := abs.days().date()
b = appendInt(b, year, 4)
b = appendIntWidth4(b, year)
b = append(b, '-')
b = appendInt(b, int(month), 2)
b = appendIntWidth2(b, int(month))
b = append(b, '-')
b = appendInt(b, day, 2)
b = appendIntWidth2(b, day)

b = append(b, 'T')

// Format time.
hour, min, sec := abs.clock()
b = appendInt(b, hour, 2)
b = appendIntWidth2(b, hour)
b = append(b, ':')
b = appendInt(b, min, 2)
b = appendIntWidth2(b, min)
b = append(b, ':')
b = appendInt(b, sec, 2)
b = appendIntWidth2(b, sec)

if nanos {
std := stdFracSecond(stdFracSecond9, 9, '.')
Expand All @@ -53,9 +53,9 @@ func (t Time) appendFormatRFC3339(b []byte, nanos bool) []byte {
} else {
b = append(b, '+')
}
b = appendInt(b, zone/60, 2)
b = appendIntWidth2(b, zone/60)
b = append(b, ':')
b = appendInt(b, zone%60, 2)
b = appendIntWidth2(b, zone%60)
return b
}

Expand Down
67 changes: 67 additions & 0 deletions src/time/format_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1091,3 +1091,70 @@ func FuzzParseRFC3339(f *testing.F) {
}
})
}

func TestAppendIntWidth(t *testing.T) {
values := []int{0, -1, 1, 10, -10, 99, -99}
for _, v := range values {
exp := AppendInt(nil, v, 2)
got := AppendIntWidth2(nil, v)
if !bytes.Equal(got, exp) {
t.Errorf("AppendIntWidth2(%d) = %s, want %s", v, got, exp)
}
}

got := AppendIntWidth2(nil, 199)
if !bytes.Equal(got, []byte("99")) {
t.Errorf("AppendIntWidth2(199) = %s, want %s", got, []byte("99"))
}

values = append(values, 9999, -9999, 10001)
for _, v := range values {
exp := AppendInt(nil, v, 4)
got := AppendIntWidth4(nil, v)
if !bytes.Equal(got, exp) {
t.Errorf("AppendIntWidth4(%d) = %s, want %s", v, got, exp)
}
}
}

func BenchmarkAppendIntWidth2(b *testing.B) {
b.Run("name=AppendInt", func(b *testing.B) {
var buf = make([]byte, 0, 8)
b.ResetTimer()
for i := 0; i < b.N; i++ {
buf = AppendInt(buf[:0], 36, 2)
}
})
b.Run("name=AppendIntWidth2", func(b *testing.B) {
var buf = make([]byte, 0, 8)
b.ResetTimer()
for i := 0; i < b.N; i++ {
buf = AppendIntWidth2(buf[:0], 36)
}
})
}

func BenchmarkAppendIntWidth4(b *testing.B) {
b.Run("name=AppendInt", func(b *testing.B) {
var buf = make([]byte, 0, 8)
b.ResetTimer()
for i := 0; i < b.N; i++ {
buf = AppendInt(buf[:0], 360, 4)
}
})
b.Run("name=AppendIntWidth4", func(b *testing.B) {
var buf = make([]byte, 0, 8)
b.ResetTimer()
for i := 0; i < b.N; i++ {
buf = AppendIntWidth4(buf[:0], 360)
}
})
}

func BenchmarkTimeFormatRFC3339(b *testing.B) {
tm := Now()
buf := make([]byte, 0, 64)
for i := 0; i < b.N; i++ {
buf = tm.AppendFormat(buf[:0], RFC3339)
}
}