1
0
mirror of https://github.com/golang/go synced 2024-11-19 18:44:41 -07:00

time: add space padding layout strings(using underscore) for not only day but others

As mentioned in #22802, only day component of layout string has space
padding(represented by one underscore before its placeholder). This
commit expands the rule for month, hour, minute and second.

Updates #22802 (maybe fixes it)

Change-Id: I886998380489862ab9a324a6774f2e4cf7124122
Reviewed-on: https://go-review.googlesource.com/78735
Run-TryBot: Rob Pike <r@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
Hanjun Kim 2017-11-20 14:23:06 +09:00 committed by Rob Pike
parent 1206e974a1
commit 8776be1535
2 changed files with 96 additions and 10 deletions

View File

@ -90,6 +90,7 @@ const (
stdLongMonth = iota + stdNeedDate // "January" stdLongMonth = iota + stdNeedDate // "January"
stdMonth // "Jan" stdMonth // "Jan"
stdNumMonth // "1" stdNumMonth // "1"
stdUnderMonth // "_1"
stdZeroMonth // "01" stdZeroMonth // "01"
stdLongWeekDay // "Monday" stdLongWeekDay // "Monday"
stdWeekDay // "Mon" stdWeekDay // "Mon"
@ -98,10 +99,13 @@ const (
stdZeroDay // "02" stdZeroDay // "02"
stdHour = iota + stdNeedClock // "15" stdHour = iota + stdNeedClock // "15"
stdHour12 // "3" stdHour12 // "3"
stdUnderHour12 // "_3"
stdZeroHour12 // "03" stdZeroHour12 // "03"
stdMinute // "4" stdMinute // "4"
stdUnderMinute // "_4"
stdZeroMinute // "04" stdZeroMinute // "04"
stdSecond // "5" stdSecond // "5"
stdUnderSecond // "_5"
stdZeroSecond // "05" stdZeroSecond // "05"
stdLongYear = iota + stdNeedDate // "2006" stdLongYear = iota + stdNeedDate // "2006"
stdYear // "06" stdYear // "06"
@ -187,13 +191,24 @@ func nextStdChunk(layout string) (prefix string, std int, suffix string) {
} }
return layout[0:i], stdDay, layout[i+1:] return layout[0:i], stdDay, layout[i+1:]
case '_': // _2, _2006 case '_': // _1, _2, _2006, _3, _4, _5
if len(layout) >= i+2 && layout[i+1] == '2' { if len(layout) >= i+2 {
//_2006 is really a literal _, followed by stdLongYear switch layout[i+1] {
if len(layout) >= i+5 && layout[i+1:i+5] == "2006" { case '1':
return layout[0 : i+1], stdLongYear, layout[i+5:] return layout[0:i], stdUnderMonth, layout[i+2:]
case '2':
//_2006 is really a literal _, followed by stdLongYear
if len(layout) >= i+5 && layout[i+1:i+5] == "2006" {
return layout[0 : i+1], stdLongYear, layout[i+5:]
}
return layout[0:i], stdUnderDay, layout[i+2:]
case '3':
return layout[0:i], stdUnderHour12, layout[i+2:]
case '4':
return layout[0:i], stdUnderMinute, layout[i+2:]
case '5':
return layout[0:i], stdUnderSecond, layout[i+2:]
} }
return layout[0:i], stdUnderDay, layout[i+2:]
} }
case '3': case '3':
@ -544,6 +559,11 @@ func (t Time) AppendFormat(b []byte, layout string) []byte {
b = append(b, m...) b = append(b, m...)
case stdNumMonth: case stdNumMonth:
b = appendInt(b, int(month), 0) b = appendInt(b, int(month), 0)
case stdUnderMonth:
if month < 10 {
b = append(b, ' ')
}
b = appendInt(b, int(month), 0)
case stdZeroMonth: case stdZeroMonth:
b = appendInt(b, int(month), 2) b = appendInt(b, int(month), 2)
case stdWeekDay: case stdWeekDay:
@ -569,6 +589,16 @@ func (t Time) AppendFormat(b []byte, layout string) []byte {
hr = 12 hr = 12
} }
b = appendInt(b, hr, 0) b = appendInt(b, hr, 0)
case stdUnderHour12:
// Noon is 12PM, midnight is 12AM.
hr := hour % 12
if hr == 0 {
hr = 12
}
if hr < 10 {
b = append(b, ' ')
}
b = appendInt(b, hr, 0)
case stdZeroHour12: case stdZeroHour12:
// Noon is 12PM, midnight is 12AM. // Noon is 12PM, midnight is 12AM.
hr := hour % 12 hr := hour % 12
@ -578,10 +608,20 @@ func (t Time) AppendFormat(b []byte, layout string) []byte {
b = appendInt(b, hr, 2) b = appendInt(b, hr, 2)
case stdMinute: case stdMinute:
b = appendInt(b, min, 0) b = appendInt(b, min, 0)
case stdUnderMinute:
if min < 10 {
b = append(b, ' ')
}
b = appendInt(b, min, 0)
case stdZeroMinute: case stdZeroMinute:
b = appendInt(b, min, 2) b = appendInt(b, min, 2)
case stdSecond: case stdSecond:
b = appendInt(b, sec, 0) b = appendInt(b, sec, 0)
case stdUnderSecond:
if sec < 10 {
b = append(b, ' ')
}
b = appendInt(b, sec, 0)
case stdZeroSecond: case stdZeroSecond:
b = appendInt(b, sec, 2) b = appendInt(b, sec, 2)
case stdPM: case stdPM:
@ -846,7 +886,10 @@ func parse(layout, value string, defaultLocation, local *Location) (Time, error)
case stdLongMonth: case stdLongMonth:
month, value, err = lookup(longMonthNames, value) month, value, err = lookup(longMonthNames, value)
month++ month++
case stdNumMonth, stdZeroMonth: case stdNumMonth, stdUnderMonth, stdZeroMonth:
if std == stdUnderMonth && len(value) > 0 && value[0] == ' ' {
value = value[1:]
}
month, value, err = getnum(value, std == stdZeroMonth) month, value, err = getnum(value, std == stdZeroMonth)
if month <= 0 || 12 < month { if month <= 0 || 12 < month {
rangeErrString = "month" rangeErrString = "month"
@ -870,17 +913,26 @@ func parse(layout, value string, defaultLocation, local *Location) (Time, error)
if hour < 0 || 24 <= hour { if hour < 0 || 24 <= hour {
rangeErrString = "hour" rangeErrString = "hour"
} }
case stdHour12, stdZeroHour12: case stdHour12, stdUnderHour12, stdZeroHour12:
if std == stdUnderHour12 && len(value) > 0 && value[0] == ' ' {
value = value[1:]
}
hour, value, err = getnum(value, std == stdZeroHour12) hour, value, err = getnum(value, std == stdZeroHour12)
if hour < 0 || 12 < hour { if hour < 0 || 12 < hour {
rangeErrString = "hour" rangeErrString = "hour"
} }
case stdMinute, stdZeroMinute: case stdMinute, stdUnderMinute, stdZeroMinute:
if std == stdUnderMinute && len(value) > 0 && value[0] == ' ' {
value = value[1:]
}
min, value, err = getnum(value, std == stdZeroMinute) min, value, err = getnum(value, std == stdZeroMinute)
if min < 0 || 60 <= min { if min < 0 || 60 <= min {
rangeErrString = "minute" rangeErrString = "minute"
} }
case stdSecond, stdZeroSecond: case stdSecond, stdUnderSecond, stdZeroSecond:
if std == stdUnderSecond && len(value) > 0 && value[0] == ' ' {
value = value[1:]
}
sec, value, err = getnum(value, std == stdZeroSecond) sec, value, err = getnum(value, std == stdZeroSecond)
if sec < 0 || 60 <= sec { if sec < 0 || 60 <= sec {
rangeErrString = "second" rangeErrString = "second"

View File

@ -116,6 +116,18 @@ func TestFormatShortYear(t *testing.T) {
} }
} }
// issue 22802.
func TestFormatSpacePadding(t *testing.T) {
for i := 9; i <= 10; i++ {
time := Date(2001, Month(i), i, i, i, i, 700000000, UTC)
result := time.Format("2006-_1-_2 _3:_4:_5")
want := fmt.Sprintf("2001-%2d-%2d %2d:%2d:%2d", i, i, i, i, i)
if result != want {
t.Errorf("SpacePadding expected %q got %q", want, result)
}
}
}
type ParseTest struct { type ParseTest struct {
name string name string
format string format string
@ -627,3 +639,25 @@ func TestUnderscoreTwoThousand(t *testing.T) {
t.Errorf("Incorrect minute, got %d", m) t.Errorf("Incorrect minute, got %d", m)
} }
} }
// issue 22802.
func TestParseSpacePadding(t *testing.T) {
format := "2006-_1-_2 _3:_4:_5"
input := "2017- 9- 6 8: 4: 2"
time, err := Parse(format, input)
if err != nil {
t.Error(err)
}
if y, m, d := time.Date(); y != 2017 || m != 9 || d != 6 {
t.Errorf("Incorrect y/m/d, got %d/%d/%d", y, m, d)
}
if h := time.Hour(); h != 8 {
t.Errorf("Incorrect hour, got %d", h)
}
if m := time.Minute(); m != 4 {
t.Errorf("Incorrect minute, got %d", m)
}
if s := time.Second(); s != 2 {
t.Errorf("Incorrect second, got %d", s)
}
}