@@ -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
382389Most notably, ISO-8601-1988 contains this note:
383390
@@ -391,10 +398,12 @@ technically used. RFC 3339 contains a note that intends to clarify the
391398interpretation to be that lowercase letters should be accepted in general.
392399
393400ISO-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
399408ProtoJSON spec takes the decision that the timestamp format is the stricter
400409definition 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
407416the laxer definition, strongly avoid relying on the additional edge cases being
408417accepted.
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
412432A conformant protobuf JSON implementation may provide the following options:
0 commit comments