Support time.Time on form binding (#801)
This commit is contained in:
		| @ -8,6 +8,7 @@ import ( | ||||
| 	"errors" | ||||
| 	"reflect" | ||||
| 	"strconv" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| func mapForm(ptr interface{}, form map[string][]string) error { | ||||
| @ -52,6 +53,12 @@ func mapForm(ptr interface{}, form map[string][]string) error { | ||||
| 			} | ||||
| 			val.Field(i).Set(slice) | ||||
| 		} else { | ||||
| 			if _, isTime := structField.Interface().(time.Time); isTime { | ||||
| 				if err := setTimeField(inputValue[0], typeField, structField); err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 				continue | ||||
| 			} | ||||
| 			if err := setWithProperType(typeField.Type.Kind(), inputValue[0], structField); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| @ -140,6 +147,26 @@ func setFloatField(val string, bitSize int, field reflect.Value) error { | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func setTimeField(val string, structField reflect.StructField, value reflect.Value) error { | ||||
| 	timeFormat := structField.Tag.Get("time_format") | ||||
| 	if timeFormat == "" { | ||||
| 		return errors.New("Blank time format") | ||||
| 	} | ||||
|  | ||||
| 	l := time.Local | ||||
| 	if isUTC, _ := strconv.ParseBool(structField.Tag.Get("time_utc")); isUTC { | ||||
| 		l = time.UTC | ||||
| 	} | ||||
|  | ||||
| 	t, err := time.ParseInLocation(timeFormat, val, l) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	value.Set(reflect.ValueOf(t)) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Don't pass in pointers to bind to. Can lead to bugs. See: | ||||
| // https://github.com/codegangsta/martini-contrib/issues/40 | ||||
| // https://github.com/codegangsta/martini-contrib/pull/34#issuecomment-29683659 | ||||
|  | ||||
| @ -42,6 +42,8 @@ func createMultipartRequest() *http.Request { | ||||
| 	must(mw.WriteField("array", "first")) | ||||
| 	must(mw.WriteField("array", "second")) | ||||
| 	must(mw.WriteField("id", "")) | ||||
| 	must(mw.WriteField("time_local", "31/12/2016 14:55")) | ||||
| 	must(mw.WriteField("time_utc", "31/12/2016 14:55")) | ||||
| 	req, err := http.NewRequest("POST", "/", body) | ||||
| 	must(err) | ||||
| 	req.Header.Set("Content-Type", MIMEMultipartPOSTForm+"; boundary="+boundary) | ||||
| @ -314,6 +316,9 @@ func TestContextPostFormMultipart(t *testing.T) { | ||||
| 		BarAsInt  int       `form:"bar"` | ||||
| 		Array     []string  `form:"array"` | ||||
| 		ID        string    `form:"id"` | ||||
| 		TimeLocal time.Time `form:"time_local" time_format:"02/01/2006 15:04"` | ||||
| 		TimeUTC   time.Time `form:"time_utc" time_format:"02/01/2006 15:04" time_utc:"1"` | ||||
| 		BlankTime time.Time `form:"blank_time" time_format:"02/01/2006 15:04"` | ||||
| 	} | ||||
| 	assert.NoError(t, c.Bind(&obj)) | ||||
| 	assert.Equal(t, obj.Foo, "bar") | ||||
| @ -321,6 +326,11 @@ func TestContextPostFormMultipart(t *testing.T) { | ||||
| 	assert.Equal(t, obj.BarAsInt, 10) | ||||
| 	assert.Equal(t, obj.Array, []string{"first", "second"}) | ||||
| 	assert.Equal(t, obj.ID, "") | ||||
| 	assert.Equal(t, obj.TimeLocal.Format("02/01/2006 15:04"), "31/12/2016 14:55") | ||||
| 	assert.Equal(t, obj.TimeLocal.Location(), time.Local) | ||||
| 	assert.Equal(t, obj.TimeUTC.Format("02/01/2006 15:04"), "31/12/2016 14:55") | ||||
| 	assert.Equal(t, obj.TimeUTC.Location(), time.UTC) | ||||
| 	assert.True(t, obj.BlankTime.IsZero()) | ||||
|  | ||||
| 	value, ok := c.GetQuery("foo") | ||||
| 	assert.False(t, ok) | ||||
|  | ||||
		Reference in New Issue
	
	Block a user