Skip to content

fix(bind): honor OpenAPI date, date-time and date-time-local format tags - #3145

Merged
vishr merged 7 commits into
masterfrom
copilot/resolve-format-tag-conflict
Oct 5, 2026
Merged

vishr merged 7 commits into
masterfrom
copilot/resolve-format-tag-conflict

Conversation

Copilot AI commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Adding a swag format:"date-time" tag to a time.Time field made Echo read the OpenAPI format name as a Go time layout, which rejected valid RFC3339 input.

This change recognizes three OpenAPI format names for time.Time and *time.Time fields in path, query, header, and form binding:

  • date-time uses the same standard-library text decoder as an untagged time.Time. It accepts RFC3339 timestamps with Z or a numeric offset.
  • date-time-local accepts 2006-01-02T15:04:05 with optional fractional seconds and rejects time-zone suffixes.
  • date accepts 2006-01-02.

Parsing uses Go's time package, so it is as lenient as untagged time.Time binding (for example, it accepts a comma before fractional seconds). date and date-time-local give UTC times, as custom layouts without a time zone already do. That is Echo's parsing policy; the input itself does not specify UTC. The formats have distinct meanings in the OpenAPI registry. Other format values are still Go layouts. JSON/XML decoding, custom unmarshalers, and slice fields (which never used the format tag) are unchanged. The DefaultBinder doc also points HTML datetime-local inputs, which omit seconds by default, to a Go layout such as 2006-01-02T15:04.

Compared with master, the only inputs that bound before and now fail are the literal strings date-time, date-time-local, and date, which parsed to 0000-01-01T00:00:00Z.

Validation:

  • go test -race ./..., go vet ./..., staticcheck ./..., golint -set_exit_status ./...
  • The regression cases cover all three formats, scalar and pointer fields, all five binding sources, fractional seconds, preserved offsets, invalid dates, missing and forbidden time zones, JSON decoding, custom types, the literal format names, and slice fields. 53 of the new cases fail on master and all pass here.

Fixes #3107

Copilot AI linked an issue Oct 2, 2026 that may be closed by this pull request
Co-authored-by: vishr <314036+vishr@users.noreply.github.com>
Copilot AI changed the title [WIP] Resolve format tag conflicts with swag Support OpenAPI date-time formats in time binding Oct 2, 2026
Copilot AI requested a review from vishr October 2, 2026 18:03
@vishr vishr changed the title Support OpenAPI date-time formats in time binding fix(bind): honor OpenAPI date-time format tags Oct 2, 2026
vishr added 3 commits October 5, 2026 11:25
Map format:"date" (OpenAPI full-date) to 2006-01-02, state that the format
tag applies to time.Time and *time.Time fields but not slices, and use the
ok/nok subtest naming used elsewhere in bind_test.go.
@vishr vishr changed the title fix(bind): honor OpenAPI date-time format tags fix(bind): honor OpenAPI date, date-time and date-time-local format tags Oct 5, 2026
@vishr
vishr marked this pull request as ready for review October 5, 2026 19:10
@vishr
vishr merged commit bbc6de8 into master Oct 5, 2026
11 checks passed
vishr added a commit that referenced this pull request Oct 5, 2026
…ags (v4) (#3156)

Backport of #3145.

Swag and OpenAPI put format names such as `format:"date-time"` on `time.Time` fields. Since v4.14.0 added `format` tag support, the binder has treated those names as Go time layouts, so valid input failed to bind.

- `date-time` uses the same RFC3339 decoding as an untagged `time.Time`, restoring the pre-v4.14.0 behavior.
- `date-time-local` accepts `2006-01-02T15:04:05` with optional fractional seconds, rejects time-zone suffixes, and assigns UTC.
- `date` accepts `2006-01-02` and assigns UTC.
- Other `format` values are still Go layouts. Slice fields, JSON/XML decoding, and custom unmarshalers are unchanged.

Refs #3107
@vishr
vishr deleted the copilot/resolve-format-tag-conflict branch October 5, 2026 19:47
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.

format tag conflicts with swag

2 participants