@@ -48,19 +48,22 @@ func defaultFormat(v interface{}, f fmt.State, c rune) {
48
48
}
49
49
50
50
type 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
60
63
}
61
64
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 }
64
67
}
65
68
66
69
func (fs * flagScanner ) AppendString (str string ) { fs .buf = append (fs .buf , str ... ) }
@@ -85,54 +88,65 @@ func (fs *flagScanner) Next() (byte, bool) {
85
88
fs .AppendChar (fs .flag )
86
89
fs .Pos += 2
87
90
return fs .Next ()
88
- } else if fs .Pos != fs .Length - 1 {
91
+ } else if fs .Pos < fs .Length - 1 {
89
92
if fs .HasFlag {
90
93
fs .AppendString (fs .end )
91
94
}
92
95
fs .AppendString (fs .start )
93
96
fs .ChangeFlag = true
94
97
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
+ }
95
109
}
96
110
}
97
111
}
98
112
fs .Pos ++
99
113
return c , false
100
114
}
101
115
102
- var cDateFlagToGo = map [byte ]string {
116
+ var cDateFlagToGo = map [string ]string {
103
117
// Formatting
104
- 'n' : "\n " ,
105
- 't' : "\t " ,
118
+ "n" : "\n " ,
119
+ "t" : "\t " ,
106
120
107
121
// Year
108
- 'Y' : "2006" , 'y' : "06" ,
122
+ "Y" : "2006" , "y" : "06" ,
109
123
110
124
// 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" ,
113
127
114
128
// 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" ,
117
131
118
132
// Day of the week
119
- 'a' : "Mon" , 'A' : "Monday" , // TODO: %^A, %^a
133
+ "a" : "Mon" , "A" : "Monday" ,
120
134
121
135
// 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" ,
126
140
127
141
// 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" ,
136
150
137
151
// Many other flags are handled in the body of strftime since they cannot
138
152
// be represented in Go format strings.
@@ -142,11 +156,16 @@ var cDateFlagToGo = map[byte]string{
142
156
// extensions. This allows for flags like %-d, which provides the day of the
143
157
// month without padding (1..31 instead of 01..31).
144
158
func strftime (t time.Time , cfmt string ) string {
145
- sc := newFlagScanner ('%' , "" , "" , cfmt )
159
+ sc := newFlagScanner ('%' , "_-" , " " , "" , cfmt )
146
160
for c , eos := sc .Next (); ! eos ; c , eos = sc .Next () {
147
161
if ! sc .ChangeFlag {
148
162
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 {
150
169
sc .AppendString (t .Format (v ))
151
170
} else {
152
171
switch c {
@@ -163,6 +182,9 @@ func strftime(t time.Time, cfmt string) string {
163
182
sc .AppendString (fmt .Sprint (int (t .Weekday ())))
164
183
default :
165
184
sc .AppendChar ('%' )
185
+ if sc .HasModifier {
186
+ sc .AppendChar (sc .Modifier )
187
+ }
166
188
sc .AppendChar (c )
167
189
}
168
190
}
0 commit comments