Skip to content

Commit 6920514

Browse files
committed
Add lots more strftime flags
1 parent da9f439 commit 6920514

File tree

2 files changed

+119
-3
lines changed

2 files changed

+119
-3
lines changed

utils.go

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,47 @@ func (fs *flagScanner) Next() (byte, bool) {
100100
}
101101

102102
var cDateFlagToGo = map[byte]string{
103-
'a': "mon", 'A': "Monday", 'b': "Jan", 'B': "January", 'c': "02 Jan 06 15:04 MST", 'd': "02",
104-
'F': "2006-01-02", 'H': "15", 'I': "03", 'm': "01", 'M': "04", 'p': "PM", 'P': "pm", 'S': "05",
105-
'x': "15/04/05", 'X': "15:04:05", 'y': "06", 'Y': "2006", 'z': "-0700", 'Z': "MST"}
103+
// Formatting
104+
'n': "\n",
105+
't': "\t",
106106

107+
// Year
108+
'Y': "2006", 'y': "06",
109+
110+
// Month
111+
'b': "Jan", 'B': "January", // TODO: %^B, %^b
112+
'm': "01", // TODO: %-m, %_m
113+
114+
// Day of the year/month
115+
'j': "002",
116+
'd': "02", 'e': "_2", // TODO: %-d
117+
118+
// Day of the week
119+
'a': "Mon", 'A': "Monday", // TODO: %^A, %^a
120+
121+
// Hour, minute, second
122+
'H': "15",
123+
'I': "03", 'l': "3",
124+
'M': "04",
125+
'S': "05",
126+
127+
// 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",
136+
137+
// Many other flags are handled in the body of strftime since they cannot
138+
// be represented in Go format strings.
139+
}
140+
141+
// This implementation of strftime is inspired by both the C spec and Ruby's
142+
// extensions. This allows for flags like %-d, which provides the day of the
143+
// month without padding (1..31 instead of 01..31).
107144
func strftime(t time.Time, cfmt string) string {
108145
sc := newFlagScanner('%', "", "", cfmt)
109146
for c, eos := sc.Next(); !eos; c, eos = sc.Next() {
@@ -113,6 +150,15 @@ func strftime(t time.Time, cfmt string) string {
113150
sc.AppendString(t.Format(v))
114151
} else {
115152
switch c {
153+
case 'G':
154+
isoYear, _ := t.ISOWeek()
155+
sc.AppendString(fmt.Sprint(isoYear))
156+
case 'g':
157+
isoYear, _ := t.ISOWeek()
158+
sc.AppendString(fmt.Sprint(isoYear)[2:])
159+
case 'V':
160+
_, isoWeek := t.ISOWeek()
161+
sc.AppendString(fmt.Sprint(isoWeek))
116162
case 'w':
117163
sc.AppendString(fmt.Sprint(int(t.Weekday())))
118164
default:

utils_test.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package lua
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
"time"
7+
)
8+
9+
func TestStrftime(t *testing.T) {
10+
type testCase struct {
11+
T time.Time
12+
Fmt string
13+
Expected string
14+
}
15+
16+
t1 := time.Date(2016, time.February, 3, 13, 23, 45, 123, time.FixedZone("Plus2", 60*60*2))
17+
t2 := time.Date(1945, time.September, 6, 7, 35, 4, 989, time.FixedZone("Minus5", 60*60*-5))
18+
19+
cases := []testCase{
20+
{t1, "foo%nbar%tbaz 100%% cool", "foo\nbar\tbaz 100% cool"},
21+
22+
{t1, "%Y %y", "2016 16"},
23+
{t1, "%G %g", "2016 16"},
24+
{t1, "%b %B %m", "Feb February 02"},
25+
{t1, "%V", "5"},
26+
{t1, "%w", "3"},
27+
{t1, "%j", "034"},
28+
{t1, "%d", "03"},
29+
{t1, "%e", " 3"},
30+
{t1, "%a %A", "Wed Wednesday"},
31+
{t1, "%H %I %l", "13 01 1"},
32+
{t1, "%M", "23"},
33+
{t1, "%S", "45"},
34+
{t1, "%c", "03 Feb 16 13:23 Plus2"},
35+
{t1, "%D %x", "02/03/16 02/03/16"},
36+
{t1, "%F", "2016-02-03"},
37+
{t1, "%r", "01:23:45 PM"},
38+
{t1, "%R %T %X", "13:23 13:23:45 13:23:45"},
39+
{t1, "%p %P", "PM pm"},
40+
{t1, "%z %Z", "+0200 Plus2"},
41+
42+
{t2, "%Y %y", "1945 45"},
43+
{t2, "%G %g", "1945 45"},
44+
{t2, "%b %B %m", "Sep September 09"},
45+
{t2, "%V", "36"},
46+
{t2, "%w", "4"},
47+
{t2, "%j", "249"},
48+
{t2, "%d", "06"},
49+
{t2, "%e", " 6"},
50+
{t2, "%a %A", "Thu Thursday"},
51+
{t2, "%H %I %l", "07 07 7"},
52+
{t2, "%M", "35"},
53+
{t2, "%S", "04"},
54+
{t2, "%c", "06 Sep 45 07:35 Minus5"},
55+
{t2, "%D %x", "09/06/45 09/06/45"},
56+
{t2, "%F", "1945-09-06"},
57+
{t2, "%r", "07:35:04 AM"},
58+
{t2, "%R %T %X", "07:35 07:35:04 07:35:04"},
59+
{t2, "%p %P", "AM am"},
60+
{t2, "%z %Z", "-0500 Minus5"},
61+
}
62+
for i, c := range cases {
63+
t.Run(fmt.Sprintf("Case %d (\"%s\")", i, c.Fmt), func(t *testing.T) {
64+
actual := strftime(c.T, c.Fmt)
65+
if actual != c.Expected {
66+
t.Errorf("bad strftime: expected \"%s\" but got \"%s\"", c.Expected, actual)
67+
}
68+
})
69+
}
70+
}

0 commit comments

Comments
 (0)