Skip to content

fix: support time_format tag in JSON binding (ShouldBindJSON) - #4771

Open
waterWang wants to merge 1 commit into
gin-gonic:masterfrom
waterWang:fix/json-time-format
Open

fix: support time_format tag in JSON binding (ShouldBindJSON)#4771
waterWang wants to merge 1 commit into
gin-gonic:masterfrom
waterWang:fix/json-time-format

Conversation

@waterWang

Copy link
Copy Markdown

Description

The time_format struct tag works for form/query binding but is completely ignored when binding via JSON (ShouldBindJSON). This has been a long-standing issue open since 2019 (see #2170).

Root cause: The JSON binding path (binding/json.go) uses json.Decoder.Decode(obj) directly, which calls time.Time.UnmarshalJSON — this only supports RFC3339 format. The time_format/time_utc/time_location tags are only checked in the form binding path (form_mapping.gosetTimeField).

Fix: When a struct has time.Time fields with time_format tags, the decoder falls back to mappingByPtr with a jsonSource setter that uses the existing setTimeField function. For structs without time_format tags, the original fast path (direct JSON unmarshal with UseNumber/DisallowUnknownFields support) is preserved.

Changes

  • binding/json.go: Added jsonSource type that implements setter interface. For time.Time fields with time_format tags, it uses setTimeField to parse the string value with the custom format. For all other types, it uses standard JSON unmarshaling. Modified decodeJSON to check for time_format tags and fall back to the jsonSource approach when needed.
  • binding/json_test.go: Added comprehensive tests covering:
    • Custom time format strings (e.g. "2006-01-02 15:04:05")
    • Unix timestamp formats (unix, unixNano)
    • time_utc tag combination
    • time_location tag combination
    • Regression: RFC3339 format still works without time_format tag

Backward Compatibility

100% backward compatible — all existing tests pass unchanged. The fast path (direct JSON unmarshal) is used for structs without time_format tags, so UseNumber and DisallowUnknownFields settings are unaffected.

Fixes #2170

The time_format struct tag works for form/query binding but is completely
ignored when binding via JSON (ShouldBindJSON). This commit adds support
for time_format, time_utc, and time_location tags in the JSON binding path.

When a struct has time.Time fields with time_format tags, the JSON decoder
falls back to mappingByPtr with a jsonSource setter that uses setTimeField
to parse the string value with the custom format. For structs without
time_format tags, the original fast path (direct JSON unmarshal) is used,
preserving full backward compatibility.

Fixes gin-gonic#2170
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

time_format tag not work with ShouldBindJSON?

1 participant