Repository navigation
runtimes/go: keep sub-second precision when encoding time.Time params - #2629
Open
Abhishek-B-R wants to merge 1 commit into
Open
Abhishek-B-R wants to merge 1 commit into
Abhishek-B-R wants to merge 1 commit into
Conversation
etype.MarshalTime formatted values with time.RFC3339, which drops the fractional seconds. It is used by the generated code for path, query and header values, so a time.Time sent to another service in one of those places (or returned in a response header) was truncated to the second, while the same value in a JSON body kept its full precision. Use time.RFC3339Nano instead. Whole-second values encode exactly as before, and UnmarshalTime already accepts fractional seconds, so both sides stay compatible.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation:
etype.MarshalTimeformats withtime.RFC3339, which has no fractionalseconds. The generated code uses it for path, query and header values
(
genutil.MarshalBuiltinandMarshalQueryOrHeader), so atime.Timepassed to another service in one of those places, or returned in a
response header, is silently truncated to the second. The same value in
a JSON body keeps full precision, so the behaviour depends on where the
field happens to live.
This bites things like keyset pagination: a
CreatedAfter time.Timequery param holding a Postgres timestamp (microseconds) arrives as the
whole second, and the callee returns rows the caller has already seen.
Before:
2026-10-28T09:30:00.123456Zis sent as2026-10-28T09:30:00Z.After: it is sent unchanged.
Approach:
Format with
time.RFC3339Nano. It trims trailing zeros, so whole-secondvalues encode exactly as they did before, and
UnmarshalTimealreadyparses fractional seconds (Go's RFC3339 parser accepts them), so old and
new runtimes on either side of a call still understand each other.
Validation:
Added
TestMarshalTimeinruntimes/go/appruntime/shared/etype, coveringwhole seconds, microseconds, nanoseconds and a +05:30 offset, each checked
for the exact string and for a lossless round trip through
UnmarshalTime.On main the three sub-second cases fail; with the change all pass.
cd runtimes/go && go test -short -tags=dev_build ./appruntime/shared/etype/(also withTZ=Asia/Kolkata)cd runtimes/go && go test -short -tags=dev_build ./...passesgo vetandgofmt -lclean on the packageThe generated Go client (
internal/gocodegen/marshalling.go,FromTime)has the same
time.RFC3339format. I left it out to keep this to theruntime, since changing it means regenerating the client goldens. Happy
to do it here or in a follow-up if you want it.
Need help on this PR? Tag
@codesmith-botwith what you need.