mirror of
https://github.com/golang/go
synced 2024-11-02 13:42:29 +00:00
time: unify formatting of decimals for timestamps
Change function appendUint to appendInt with variable-width 0-padding. This allows the decimal for the year to be generated without extra code to handle the wider padding and directly handles negative numbers. Removes the special casing for numbers with one and two digits. The special case for 0 was unreachable. The new version is slightly slower. benchmark old ns/op new ns/op delta BenchmarkFormat 444 454 +2.25% BenchmarkFormatNow 398 415 +4.27% Change-Id: I4ddef96bf07ad35dca76053321d510441ec6d4f5 Reviewed-on: https://go-review.googlesource.com/2751 Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
5c22a4a2e1
commit
d5ef698142
1 changed files with 45 additions and 66 deletions
|
@ -315,36 +315,34 @@ func lookup(tab []string, val string) (int, string, error) {
|
|||
return -1, val, errBad
|
||||
}
|
||||
|
||||
// appendUint appends the decimal form of x to b and returns the result.
|
||||
// If x is a single-digit number and pad != 0, appendUint inserts the pad byte
|
||||
// before the digit.
|
||||
// appendInt appends the decimal form of x to b and returns the result.
|
||||
// If the decimal form (excluding sign) is shorter than width, the result is padded with leading 0's.
|
||||
// Duplicates functionality in strconv, but avoids dependency.
|
||||
func appendUint(b []byte, x uint, pad byte) []byte {
|
||||
if x < 10 {
|
||||
if pad != 0 {
|
||||
b = append(b, pad)
|
||||
}
|
||||
return append(b, byte('0'+x))
|
||||
}
|
||||
if x < 100 {
|
||||
b = append(b, byte('0'+x/10))
|
||||
b = append(b, byte('0'+x%10))
|
||||
return b
|
||||
func appendInt(b []byte, x int, width int) []byte {
|
||||
u := uint(x)
|
||||
if x < 0 {
|
||||
b = append(b, '-')
|
||||
u = uint(-x)
|
||||
}
|
||||
|
||||
var buf [32]byte
|
||||
n := len(buf)
|
||||
if x == 0 {
|
||||
return append(b, '0')
|
||||
// Assemble decimal in reverse order.
|
||||
var buf [20]byte
|
||||
i := len(buf)
|
||||
for u >= 10 {
|
||||
i--
|
||||
q := u / 10
|
||||
buf[i] = byte('0' + u - q*10)
|
||||
u = q
|
||||
}
|
||||
for x >= 10 {
|
||||
n--
|
||||
buf[n] = byte(x%10 + '0')
|
||||
x /= 10
|
||||
i--
|
||||
buf[i] = byte('0' + u)
|
||||
|
||||
// Add 0-padding.
|
||||
for w := len(buf) - i; w < width; w++ {
|
||||
b = append(b, '0')
|
||||
}
|
||||
n--
|
||||
buf[n] = byte(x + '0')
|
||||
return append(b, buf[n:]...)
|
||||
|
||||
return append(b, buf[i:]...)
|
||||
}
|
||||
|
||||
// Never printed, just needs to be non-nil for return by atoi.
|
||||
|
@ -458,75 +456,56 @@ func (t Time) Format(layout string) string {
|
|||
if y < 0 {
|
||||
y = -y
|
||||
}
|
||||
b = appendUint(b, uint(y%100), '0')
|
||||
b = appendInt(b, y%100, 2)
|
||||
case stdLongYear:
|
||||
// Pad year to at least 4 digits.
|
||||
y := year
|
||||
switch {
|
||||
case year <= -1000:
|
||||
b = append(b, '-')
|
||||
y = -y
|
||||
case year <= -100:
|
||||
b = append(b, "-0"...)
|
||||
y = -y
|
||||
case year <= -10:
|
||||
b = append(b, "-00"...)
|
||||
y = -y
|
||||
case year < 0:
|
||||
b = append(b, "-000"...)
|
||||
y = -y
|
||||
case year < 10:
|
||||
b = append(b, "000"...)
|
||||
case year < 100:
|
||||
b = append(b, "00"...)
|
||||
case year < 1000:
|
||||
b = append(b, '0')
|
||||
}
|
||||
b = appendUint(b, uint(y), 0)
|
||||
b = appendInt(b, year, 4)
|
||||
case stdMonth:
|
||||
b = append(b, month.String()[:3]...)
|
||||
case stdLongMonth:
|
||||
m := month.String()
|
||||
b = append(b, m...)
|
||||
case stdNumMonth:
|
||||
b = appendUint(b, uint(month), 0)
|
||||
b = appendInt(b, int(month), 0)
|
||||
case stdZeroMonth:
|
||||
b = appendUint(b, uint(month), '0')
|
||||
b = appendInt(b, int(month), 2)
|
||||
case stdWeekDay:
|
||||
b = append(b, absWeekday(abs).String()[:3]...)
|
||||
case stdLongWeekDay:
|
||||
s := absWeekday(abs).String()
|
||||
b = append(b, s...)
|
||||
case stdDay:
|
||||
b = appendUint(b, uint(day), 0)
|
||||
b = appendInt(b, day, 0)
|
||||
case stdUnderDay:
|
||||
b = appendUint(b, uint(day), ' ')
|
||||
if day < 10 {
|
||||
b = append(b, ' ')
|
||||
}
|
||||
b = appendInt(b, day, 0)
|
||||
case stdZeroDay:
|
||||
b = appendUint(b, uint(day), '0')
|
||||
b = appendInt(b, day, 2)
|
||||
case stdHour:
|
||||
b = appendUint(b, uint(hour), '0')
|
||||
b = appendInt(b, hour, 2)
|
||||
case stdHour12:
|
||||
// Noon is 12PM, midnight is 12AM.
|
||||
hr := hour % 12
|
||||
if hr == 0 {
|
||||
hr = 12
|
||||
}
|
||||
b = appendUint(b, uint(hr), 0)
|
||||
b = appendInt(b, hr, 0)
|
||||
case stdZeroHour12:
|
||||
// Noon is 12PM, midnight is 12AM.
|
||||
hr := hour % 12
|
||||
if hr == 0 {
|
||||
hr = 12
|
||||
}
|
||||
b = appendUint(b, uint(hr), '0')
|
||||
b = appendInt(b, hr, 2)
|
||||
case stdMinute:
|
||||
b = appendUint(b, uint(min), 0)
|
||||
b = appendInt(b, min, 0)
|
||||
case stdZeroMinute:
|
||||
b = appendUint(b, uint(min), '0')
|
||||
b = appendInt(b, min, 2)
|
||||
case stdSecond:
|
||||
b = appendUint(b, uint(sec), 0)
|
||||
b = appendInt(b, sec, 2)
|
||||
case stdZeroSecond:
|
||||
b = appendUint(b, uint(sec), '0')
|
||||
b = appendInt(b, sec, 2)
|
||||
case stdPM:
|
||||
if hour >= 12 {
|
||||
b = append(b, "PM"...)
|
||||
|
@ -555,18 +534,18 @@ func (t Time) Format(layout string) string {
|
|||
} else {
|
||||
b = append(b, '+')
|
||||
}
|
||||
b = appendUint(b, uint(zone/60), '0')
|
||||
b = appendInt(b, zone/60, 2)
|
||||
if std == stdISO8601ColonTZ || std == stdNumColonTZ || std == stdISO8601ColonSecondsTZ || std == stdNumColonSecondsTZ {
|
||||
b = append(b, ':')
|
||||
}
|
||||
b = appendUint(b, uint(zone%60), '0')
|
||||
b = appendInt(b, zone%60, 2)
|
||||
|
||||
// append seconds if appropriate
|
||||
if std == stdISO8601SecondsTZ || std == stdNumSecondsTz || std == stdNumColonSecondsTZ || std == stdISO8601ColonSecondsTZ {
|
||||
if std == stdNumColonSecondsTZ || std == stdISO8601ColonSecondsTZ {
|
||||
b = append(b, ':')
|
||||
}
|
||||
b = appendUint(b, uint(absoffset%60), '0')
|
||||
b = appendInt(b, absoffset%60, 2)
|
||||
}
|
||||
|
||||
case stdTZ:
|
||||
|
@ -583,8 +562,8 @@ func (t Time) Format(layout string) string {
|
|||
} else {
|
||||
b = append(b, '+')
|
||||
}
|
||||
b = appendUint(b, uint(zone/60), '0')
|
||||
b = appendUint(b, uint(zone%60), '0')
|
||||
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)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue