Skip to content

Commit 6c1f1f2

Browse files
Add clarification on ProtoJSON Durations being not RFC3339 Duration due to us wanting to represent sub-second precision.
PiperOrigin-RevId: 828966205
1 parent fd6fca1 commit 6c1f1f2

File tree

1 file changed

+30
-10
lines changed

1 file changed

+30
-10
lines changed

content/programming-guides/json.md

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ The following table shows how data is represented in JSON files.
159159
<td>Timestamp</td>
160160
<td>string</td>
161161
<td><code>"1972-01-01T10:00:20.021Z"</code></td>
162-
<td>Uses RFC 3339 (see <a href="#rfc3339">clarification</a>), where generated output will always be Z-normalized
162+
<td>Uses RFC 3339 (see <a href="#rfc3339-timestamp">clarification</a>), where generated output will always be Z-normalized
163163
and uses 0, 3, 6 or 9 fractional digits. Offsets other than "Z" are
164164
also accepted.
165165
</td>
@@ -171,7 +171,8 @@ The following table shows how data is represented in JSON files.
171171
<td>Generated output always contains 0, 3, 6, or 9 fractional digits,
172172
depending on required precision, followed by the suffix "s". Accepted
173173
are any fractional digits (also none) as long as they fit into
174-
nanoseconds precision and the suffix "s" is required.
174+
nanoseconds precision and the suffix "s" is required. This is *not* RFC 3339
175+
'duration' format (see <a href="#rfc3339-duration">Durations</a> for clarification).
175176
</td>
176177
</tr>
177178
<tr>
@@ -372,12 +373,18 @@ that the relevant clients set an Ignore Unknown Fields flag, discussed
372373
* If "enums-as-ints" flag is used by any client, then enums will instead
373374
be compatible with the integer types instead.
374375

375-
## RFC 3339 Clarification {#rfc3339}
376+
## RFC 3339 Clarifications {#rfc3339}
377+
378+
### Timestamps {#rfc3339-timestamp}
379+
380+
ProtoJSON timestamps use the RFC 3339 timestamp format. Unfortunately, some
381+
ambiguity in the RFC 3339 spec has created a few edge cases where various other
382+
RFC 3339 implementations do not agree on whether or not the format is legal.
376383

377384
[RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) intends to declare a strict
378-
subset of ISO-8601 format, and unfortunately some ambiguity was created since
379-
RFC 3339 was published in 2002 and then ISO-8601 was subsequently revised
380-
without any corresponding revisions of RFC 3339.
385+
subset of ISO-8601 format, and some additional ambiguity was created since RFC
386+
3339 was published in 2002 and then ISO-8601 was subsequently revised without
387+
any corresponding revisions of RFC 3339.
381388

382389
Most notably, ISO-8601-1988 contains this note:
383390

@@ -391,10 +398,12 @@ technically used. RFC 3339 contains a note that intends to clarify the
391398
interpretation to be that lowercase letters should be accepted in general.
392399

393400
ISO-8601-2019 does not contain the corresponding note and is unambiguous that
394-
lowercase letters are not allowed. This created some confusion for all libraries
395-
that declare they support RFC 3339: today RFC 3339 declares it is a profile of
396-
ISO-8601 but contains a note that is in reference to something that is no longer
397-
in the latest ISO-8601 spec.
401+
lowercase letters are not allowed.
402+
403+
This created some confusion for all libraries that declare they support RFC
404+
3339: today RFC 3339 declares it is a profile of ISO-8601 but contains a
405+
clarifying note referencing text that is not present in the latest ISO-8601
406+
spec.
398407

399408
ProtoJSON spec takes the decision that the timestamp format is the stricter
400409
definition of "RFC 3339 as a profile of ISO-8601-2019". Some Protobuf
@@ -407,6 +416,17 @@ format where possible. When using a non-conformant implementation that accepts
407416
the laxer definition, strongly avoid relying on the additional edge cases being
408417
accepted.
409418

419+
### Durations {#rfc3339-duration}
420+
421+
RFC 3339 also defines a duration format, but unfortunately the RFC 3339 duration
422+
format does not have any way to express sub-second resolution.
423+
424+
The ProtoJSON duration encoding is directly inspired by RFC 3339 `dur-seconds`
425+
representation, but it is able to encode nanosecond precision. For integer
426+
number of seconds the two representations may match (like `10s`), but the
427+
ProtoJSON durations accept fractional values and conformant implementations must
428+
precisely represent nanosecond precision (like `10.500000001s`).
429+
410430
## JSON Options {#json-options}
411431

412432
A conformant protobuf JSON implementation may provide the following options:

0 commit comments

Comments
 (0)