Skip to content

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

Merged
vishr merged 5 commits into
v4from
fix/v4-openapi-time-format
Oct 5, 2026
Merged

vishr merged 5 commits into
v4from
fix/v4-openapi-time-format

Conversation

@vishr

@vishr vishr commented Oct 5, 2026 •

Copy link
Copy Markdown
Member

Backport of #3145 to v4.

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. Before v4.14.0 the tag was ignored, so RFC3339 values bound to swag-annotated format:"date-time" fields. That case broke on upgrade.

  • date-time uses the same RFC3339 decoding as an untagged time.Time, which restores 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.
  • For date-time-local and date, zoned RFC3339 values bound before v4.14.0 only because the tag was ignored. They stay rejected, as the OpenAPI definitions require.
  • 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).
  • Other format values are still Go layouts. Slice fields never used the tag and are unchanged.

Compared with current v4, 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.

The tests are ported from #3145 and adapted to the v4 binder API. They cover path, query, header, form, and multipart sources, scalar and pointer fields, JSON decoding, custom types, the literal format names, and slice fields. Without the fix, 53 of the new cases fail. With it, go test -race ./..., staticcheck, and golint pass.

The BindPathParams doc now mentions the OpenAPI names and headers, and its HTML datetime-local example uses a form tag. Two existing lines in TestTimeFormatBinding are gofmt-aligned.

Refs #3107

vishr added 4 commits October 5, 2026 11:21
Backport of #3145. Swag and OpenAPI put format:"date-time" and
format:"date-time-local" on time.Time fields. Since v4.14.0 the binder
treated those values as Go layouts, so valid input failed to bind.

date-time now uses the same RFC3339 decoding as an untagged time.Time.
date-time-local accepts 2006-01-02T15:04:05 with optional fractional
seconds, rejects time-zone suffixes, and assigns UTC. Other format
values are still Go layouts.

Refs #3107
…uts (v4)

Also gofmt two existing lines in TestTimeFormatBinding.
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 (v4) fix(bind): honor OpenAPI date, date-time and date-time-local format tags (v4) Oct 5, 2026
@vishr
vishr merged commit 320fe67 into v4 Oct 5, 2026
8 checks passed
@vishr
vishr deleted the fix/v4-openapi-time-format 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.

1 participant