Skip to content

Commit dd81620

Browse files
committed
allow specifying a custom layout for time values
Fixes #17
1 parent 05266dc commit dd81620

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

query/encode.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,12 @@ type Encoder interface {
8484
// "unix" option signals that the field should be encoded as a Unix time (see
8585
// time.Unix()). The "unixmilli" and "unixnano" options will encode the number
8686
// of milliseconds and nanoseconds, respectively, since January 1, 1970 (see
87-
// time.UnixNano()).
87+
// time.UnixNano()). Including the "layout" struct tag (separate from the
88+
// "url" tag) will use the value of the "layout" tag as a layout passed to
89+
// time.Format. For example:
90+
//
91+
// // Encode a time.Time as YYYY-MM-DD
92+
// Field time.Time `layout:"2006-01-02"`
8893
//
8994
// Slice and Array values default to encoding as multiple URL values of the
9095
// same name. Including the "comma" option signals that the field should be
@@ -223,7 +228,7 @@ func reflectValue(values url.Values, val reflect.Value, scope string) error {
223228
} else {
224229
s.WriteString(del)
225230
}
226-
s.WriteString(valueString(sv.Index(i), opts))
231+
s.WriteString(valueString(sv.Index(i), opts, sf))
227232
}
228233
values.Add(name, s.String())
229234
} else {
@@ -232,14 +237,14 @@ func reflectValue(values url.Values, val reflect.Value, scope string) error {
232237
if opts.Contains("numbered") {
233238
k = fmt.Sprintf("%s%d", name, i)
234239
}
235-
values.Add(k, valueString(sv.Index(i), opts))
240+
values.Add(k, valueString(sv.Index(i), opts, sf))
236241
}
237242
}
238243
continue
239244
}
240245

241246
if sv.Type() == timeType {
242-
values.Add(name, valueString(sv, opts))
247+
values.Add(name, valueString(sv, opts, sf))
243248
continue
244249
}
245250

@@ -250,7 +255,7 @@ func reflectValue(values url.Values, val reflect.Value, scope string) error {
250255
continue
251256
}
252257

253-
values.Add(name, valueString(sv, opts))
258+
values.Add(name, valueString(sv, opts, sf))
254259
}
255260

256261
for _, f := range embedded {
@@ -263,7 +268,7 @@ func reflectValue(values url.Values, val reflect.Value, scope string) error {
263268
}
264269

265270
// valueString returns the string representation of a value.
266-
func valueString(v reflect.Value, opts tagOptions) string {
271+
func valueString(v reflect.Value, opts tagOptions, sf reflect.StructField) string {
267272
for v.Kind() == reflect.Ptr {
268273
if v.IsNil() {
269274
return ""
@@ -289,6 +294,9 @@ func valueString(v reflect.Value, opts tagOptions) string {
289294
if opts.Contains("unixnano") {
290295
return strconv.FormatInt(t.UnixNano(), 10)
291296
}
297+
if layout := sf.Tag.Get("layout"); layout != "" {
298+
return t.Format(layout)
299+
}
292300
return t.Format(time.RFC3339)
293301
}
294302

query/encode_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ func TestValues_BasicTypes(t *testing.T) {
8484
}{time.Date(2000, 1, 1, 12, 34, 56, 0, time.UTC)},
8585
url.Values{"V": {"946730096000000000"}},
8686
},
87+
{
88+
struct {
89+
V time.Time `layout:"2006-01-02"`
90+
}{time.Date(2000, 1, 1, 12, 34, 56, 0, time.UTC)},
91+
url.Values{"V": {"2000-01-01"}},
92+
},
8793
}
8894

8995
for _, tt := range tests {

0 commit comments

Comments
 (0)