@@ -48,19 +48,22 @@ func defaultFormat(v interface{}, f fmt.State, c rune) {
4848}
4949
5050type flagScanner struct {
51- flag byte
52- start string
53- end string
54- buf []byte
55- str string
56- Length int
57- Pos int
58- HasFlag bool
59- ChangeFlag bool
51+ flag byte
52+ modifiers []byte
53+ start string
54+ end string
55+ buf []byte
56+ str string
57+ Length int
58+ Pos int
59+ HasFlag bool
60+ ChangeFlag bool
61+ HasModifier bool
62+ Modifier byte
6063}
6164
62- func newFlagScanner (flag byte , start , end , str string ) * flagScanner {
63- return & flagScanner {flag , start , end , make ([]byte , 0 , len (str )), str , len (str ), 0 , false , false }
65+ func newFlagScanner (flag byte , modifiers , start , end , str string ) * flagScanner {
66+ return & flagScanner {flag , [] byte ( modifiers ), start , end , make ([]byte , 0 , len (str )), str , len (str ), 0 , false , false , false , 0 }
6467}
6568
6669func (fs * flagScanner ) AppendString (str string ) { fs .buf = append (fs .buf , str ... ) }
@@ -85,54 +88,65 @@ func (fs *flagScanner) Next() (byte, bool) {
8588 fs .AppendChar (fs .flag )
8689 fs .Pos += 2
8790 return fs .Next ()
88- } else if fs .Pos != fs .Length - 1 {
91+ } else if fs .Pos < fs .Length - 1 {
8992 if fs .HasFlag {
9093 fs .AppendString (fs .end )
9194 }
9295 fs .AppendString (fs .start )
9396 fs .ChangeFlag = true
9497 fs .HasFlag = true
98+ fs .HasModifier = false
99+ fs .Modifier = 0
100+ if fs .Pos < fs .Length - 2 {
101+ for _ , modifier := range fs .modifiers {
102+ if fs .str [fs .Pos + 1 ] == modifier {
103+ fs .HasModifier = true
104+ fs .Modifier = modifier
105+ fs .Pos += 1
106+ }
107+ }
108+ }
95109 }
96110 }
97111 }
98112 fs .Pos ++
99113 return c , false
100114}
101115
102- var cDateFlagToGo = map [byte ]string {
116+ var cDateFlagToGo = map [string ]string {
103117 // Formatting
104- 'n' : "\n " ,
105- 't' : "\t " ,
118+ "n" : "\n " ,
119+ "t" : "\t " ,
106120
107121 // Year
108- 'Y' : "2006" , 'y' : "06" ,
122+ "Y" : "2006" , "y" : "06" ,
109123
110124 // Month
111- 'b' : "Jan" , 'B' : "January" , // TODO: %^B, %^b
112- 'm' : "01" , // TODO: %-m, %_m
125+ "b" : "Jan" , "B" : "January" ,
126+ "m" : "01" , "-m" : "1" ,
113127
114128 // Day of the year/month
115- 'j' : "002" ,
116- 'd' : "02" , 'e' : "_2 " , // TODO: %-d
129+ "j" : "002" ,
130+ "d" : "02" , "-d" : "2 " , "e" : "_2" ,
117131
118132 // Day of the week
119- 'a' : "Mon" , 'A' : "Monday" , // TODO: %^A, %^a
133+ "a" : "Mon" , "A" : "Monday" ,
120134
121135 // Hour, minute, second
122- 'H' : "15" ,
123- 'I' : "03" , 'l' : "3" ,
124- 'M' : "04" ,
125- 'S' : "05" ,
136+ "H" : "15" ,
137+ "I" : "03" , "l" : "3" ,
138+ "M" : "04" ,
139+ "S" : "05" ,
126140
127141 // Other
128- 'c' : "02 Jan 06 15:04 MST" ,
129- 'x' : "01/02/06" , 'X' : "15:04:05" ,
130- 'D' : "01/02/06" ,
131- 'F' : "2006-01-02" ,
132- 'r' : "03:04:05 PM" , 'R' : "15:04" ,
133- 'T' : "15:04:05" ,
134- 'p' : "PM" , 'P' : "pm" ,
135- 'z' : "-0700" , 'Z' : "MST" ,
142+ "c" : "02 Jan 06 15:04 MST" ,
143+ "x" : "01/02/06" , "X" : "15:04:05" ,
144+ "D" : "01/02/06" ,
145+ "F" : "2006-01-02" ,
146+ "r" : "03:04:05 PM" , "R" : "15:04" ,
147+ "T" : "15:04:05" ,
148+ "p" : "PM" , "P" : "pm" ,
149+ "z" : "-0700" , "Z" : "MST" ,
136150
137151 // Many other flags are handled in the body of strftime since they cannot
138152 // be represented in Go format strings.
@@ -142,11 +156,16 @@ var cDateFlagToGo = map[byte]string{
142156// extensions. This allows for flags like %-d, which provides the day of the
143157// month without padding (1..31 instead of 01..31).
144158func strftime (t time.Time , cfmt string ) string {
145- sc := newFlagScanner ('%' , "" , "" , cfmt )
159+ sc := newFlagScanner ('%' , "_-" , " " , "" , cfmt )
146160 for c , eos := sc .Next (); ! eos ; c , eos = sc .Next () {
147161 if ! sc .ChangeFlag {
148162 if sc .HasFlag {
149- if v , ok := cDateFlagToGo [c ]; ok {
163+ flag := string (c )
164+ if sc .HasModifier {
165+ flag = string (sc .Modifier ) + flag
166+ }
167+
168+ if v , ok := cDateFlagToGo [flag ]; ok {
150169 sc .AppendString (t .Format (v ))
151170 } else {
152171 switch c {
@@ -163,6 +182,9 @@ func strftime(t time.Time, cfmt string) string {
163182 sc .AppendString (fmt .Sprint (int (t .Weekday ())))
164183 default :
165184 sc .AppendChar ('%' )
185+ if sc .HasModifier {
186+ sc .AppendChar (sc .Modifier )
187+ }
166188 sc .AppendChar (c )
167189 }
168190 }
0 commit comments